@yuanliwei/exceljs 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +3024 -0
  3. package/README_zh.md +2878 -0
  4. package/excel.js +13 -0
  5. package/index.d.ts +2040 -0
  6. package/index.ts +2 -0
  7. package/lib/csv/csv.js +191 -0
  8. package/lib/csv/line-buffer.js +74 -0
  9. package/lib/csv/stream-converter.js +135 -0
  10. package/lib/doc/anchor.js +91 -0
  11. package/lib/doc/cell.js +1124 -0
  12. package/lib/doc/column.js +320 -0
  13. package/lib/doc/data/theme1.json +234 -0
  14. package/lib/doc/data-validations.js +19 -0
  15. package/lib/doc/defined-names.js +196 -0
  16. package/lib/doc/enums.js +48 -0
  17. package/lib/doc/image.js +59 -0
  18. package/lib/doc/modelcontainer.js +18 -0
  19. package/lib/doc/note.js +65 -0
  20. package/lib/doc/pivot-table.js +132 -0
  21. package/lib/doc/range.js +257 -0
  22. package/lib/doc/row.js +415 -0
  23. package/lib/doc/table.js +465 -0
  24. package/lib/doc/workbook.js +224 -0
  25. package/lib/doc/worksheet.js +949 -0
  26. package/lib/exceljs.bare.js +13 -0
  27. package/lib/exceljs.browser.js +36 -0
  28. package/lib/exceljs.nodejs.js +14 -0
  29. package/lib/stream/xlsx/hyperlink-reader.js +83 -0
  30. package/lib/stream/xlsx/sheet-comments-writer.js +121 -0
  31. package/lib/stream/xlsx/sheet-rels-writer.js +119 -0
  32. package/lib/stream/xlsx/workbook-reader.js +337 -0
  33. package/lib/stream/xlsx/workbook-writer.js +347 -0
  34. package/lib/stream/xlsx/worksheet-reader.js +374 -0
  35. package/lib/stream/xlsx/worksheet-writer.js +717 -0
  36. package/lib/utils/auto-drain.js +15 -0
  37. package/lib/utils/browser-buffer-decode.js +14 -0
  38. package/lib/utils/browser-buffer-encode.js +15 -0
  39. package/lib/utils/cell-matrix.js +165 -0
  40. package/lib/utils/col-cache.js +287 -0
  41. package/lib/utils/copy-style.js +43 -0
  42. package/lib/utils/encryptor.js +55 -0
  43. package/lib/utils/iterate-stream.js +48 -0
  44. package/lib/utils/parse-sax.js +30 -0
  45. package/lib/utils/shared-formula.js +44 -0
  46. package/lib/utils/shared-strings.js +35 -0
  47. package/lib/utils/stream-base64.js +72 -0
  48. package/lib/utils/stream-buf.js +364 -0
  49. package/lib/utils/string-buf.js +82 -0
  50. package/lib/utils/string-builder.js +35 -0
  51. package/lib/utils/stuttered-pipe.js +67 -0
  52. package/lib/utils/typed-stack.js +24 -0
  53. package/lib/utils/under-dash.js +184 -0
  54. package/lib/utils/utils.js +205 -0
  55. package/lib/utils/xml-stream.js +169 -0
  56. package/lib/utils/zip-stream.js +87 -0
  57. package/lib/xlsx/.rels +11 -0
  58. package/lib/xlsx/calcChain.xml +6 -0
  59. package/lib/xlsx/core.xml +7 -0
  60. package/lib/xlsx/defaultnumformats.js +153 -0
  61. package/lib/xlsx/rel-type.js +20 -0
  62. package/lib/xlsx/styles.xml +41 -0
  63. package/lib/xlsx/workbook.xml +16 -0
  64. package/lib/xlsx/xform/base-xform.js +145 -0
  65. package/lib/xlsx/xform/book/defined-name-xform.js +91 -0
  66. package/lib/xlsx/xform/book/sheet-xform.js +34 -0
  67. package/lib/xlsx/xform/book/workbook-calc-properties-xform.js +26 -0
  68. package/lib/xlsx/xform/book/workbook-pivot-cache-xform.js +29 -0
  69. package/lib/xlsx/xform/book/workbook-properties-xform.js +29 -0
  70. package/lib/xlsx/xform/book/workbook-view-xform.js +53 -0
  71. package/lib/xlsx/xform/book/workbook-xform.js +259 -0
  72. package/lib/xlsx/xform/comment/comment-xform.js +105 -0
  73. package/lib/xlsx/xform/comment/comments-xform.js +82 -0
  74. package/lib/xlsx/xform/comment/style/vml-position-xform.js +39 -0
  75. package/lib/xlsx/xform/comment/style/vml-protection-xform.js +36 -0
  76. package/lib/xlsx/xform/comment/vml-anchor-xform.js +60 -0
  77. package/lib/xlsx/xform/comment/vml-client-data-xform.js +95 -0
  78. package/lib/xlsx/xform/comment/vml-notes-xform.js +107 -0
  79. package/lib/xlsx/xform/comment/vml-shape-xform.js +95 -0
  80. package/lib/xlsx/xform/comment/vml-textbox-xform.js +64 -0
  81. package/lib/xlsx/xform/composite-xform.js +56 -0
  82. package/lib/xlsx/xform/core/app-heading-pairs-xform.js +32 -0
  83. package/lib/xlsx/xform/core/app-titles-of-parts-xform.js +28 -0
  84. package/lib/xlsx/xform/core/app-xform.js +100 -0
  85. package/lib/xlsx/xform/core/content-types-xform.js +135 -0
  86. package/lib/xlsx/xform/core/core-xform.js +136 -0
  87. package/lib/xlsx/xform/core/relationship-xform.js +25 -0
  88. package/lib/xlsx/xform/core/relationships-xform.js +73 -0
  89. package/lib/xlsx/xform/drawing/base-cell-anchor-xform.js +48 -0
  90. package/lib/xlsx/xform/drawing/blip-fill-xform.js +71 -0
  91. package/lib/xlsx/xform/drawing/blip-xform.js +42 -0
  92. package/lib/xlsx/xform/drawing/c-nv-pic-pr-xform.js +38 -0
  93. package/lib/xlsx/xform/drawing/c-nv-pr-xform.js +68 -0
  94. package/lib/xlsx/xform/drawing/cell-position-xform.js +77 -0
  95. package/lib/xlsx/xform/drawing/drawing-xform.js +109 -0
  96. package/lib/xlsx/xform/drawing/ext-lst-xform.js +43 -0
  97. package/lib/xlsx/xform/drawing/ext-xform.js +44 -0
  98. package/lib/xlsx/xform/drawing/hlink-click-xform.js +41 -0
  99. package/lib/xlsx/xform/drawing/nv-pic-pr-xform.js +65 -0
  100. package/lib/xlsx/xform/drawing/one-cell-anchor-xform.js +63 -0
  101. package/lib/xlsx/xform/drawing/pic-xform.js +77 -0
  102. package/lib/xlsx/xform/drawing/sp-pr.js +17 -0
  103. package/lib/xlsx/xform/drawing/two-cell-anchor-xform.js +62 -0
  104. package/lib/xlsx/xform/list-xform.js +95 -0
  105. package/lib/xlsx/xform/pivot-table/cache-field.js +43 -0
  106. package/lib/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +77 -0
  107. package/lib/xlsx/xform/pivot-table/pivot-cache-records-xform.js +103 -0
  108. package/lib/xlsx/xform/pivot-table/pivot-table-xform.js +189 -0
  109. package/lib/xlsx/xform/sheet/auto-filter-xform.js +38 -0
  110. package/lib/xlsx/xform/sheet/cell-xform.js +498 -0
  111. package/lib/xlsx/xform/sheet/cf/cf-rule-xform.js +301 -0
  112. package/lib/xlsx/xform/sheet/cf/cfvo-xform.js +27 -0
  113. package/lib/xlsx/xform/sheet/cf/color-scale-xform.js +45 -0
  114. package/lib/xlsx/xform/sheet/cf/conditional-formatting-xform.js +48 -0
  115. package/lib/xlsx/xform/sheet/cf/conditional-formattings-xform.js +92 -0
  116. package/lib/xlsx/xform/sheet/cf/databar-xform.js +49 -0
  117. package/lib/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +87 -0
  118. package/lib/xlsx/xform/sheet/cf/formula-xform.js +25 -0
  119. package/lib/xlsx/xform/sheet/cf/icon-set-xform.js +47 -0
  120. package/lib/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +27 -0
  121. package/lib/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +98 -0
  122. package/lib/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +43 -0
  123. package/lib/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +62 -0
  124. package/lib/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +50 -0
  125. package/lib/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +98 -0
  126. package/lib/xlsx/xform/sheet/cf-ext/f-ext-xform.js +25 -0
  127. package/lib/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +73 -0
  128. package/lib/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +25 -0
  129. package/lib/xlsx/xform/sheet/col-xform.js +86 -0
  130. package/lib/xlsx/xform/sheet/data-validations-xform.js +257 -0
  131. package/lib/xlsx/xform/sheet/dimension-xform.js +29 -0
  132. package/lib/xlsx/xform/sheet/drawing-xform.js +33 -0
  133. package/lib/xlsx/xform/sheet/ext-lst-xform.js +86 -0
  134. package/lib/xlsx/xform/sheet/header-footer-xform.js +146 -0
  135. package/lib/xlsx/xform/sheet/hyperlink-xform.js +54 -0
  136. package/lib/xlsx/xform/sheet/merge-cell-xform.js +27 -0
  137. package/lib/xlsx/xform/sheet/merges.js +56 -0
  138. package/lib/xlsx/xform/sheet/outline-properties-xform.js +43 -0
  139. package/lib/xlsx/xform/sheet/page-breaks-xform.js +27 -0
  140. package/lib/xlsx/xform/sheet/page-margins-xform.js +49 -0
  141. package/lib/xlsx/xform/sheet/page-setup-properties-xform.js +35 -0
  142. package/lib/xlsx/xform/sheet/page-setup-xform.js +103 -0
  143. package/lib/xlsx/xform/sheet/picture-xform.js +33 -0
  144. package/lib/xlsx/xform/sheet/print-options-xform.js +49 -0
  145. package/lib/xlsx/xform/sheet/row-breaks-xform.js +39 -0
  146. package/lib/xlsx/xform/sheet/row-xform.js +142 -0
  147. package/lib/xlsx/xform/sheet/sheet-format-properties-xform.js +55 -0
  148. package/lib/xlsx/xform/sheet/sheet-properties-xform.js +90 -0
  149. package/lib/xlsx/xform/sheet/sheet-protection-xform.js +89 -0
  150. package/lib/xlsx/xform/sheet/sheet-view-xform.js +202 -0
  151. package/lib/xlsx/xform/sheet/table-part-xform.js +33 -0
  152. package/lib/xlsx/xform/sheet/worksheet-xform.js +548 -0
  153. package/lib/xlsx/xform/simple/boolean-xform.js +31 -0
  154. package/lib/xlsx/xform/simple/date-xform.js +66 -0
  155. package/lib/xlsx/xform/simple/float-xform.js +51 -0
  156. package/lib/xlsx/xform/simple/integer-xform.js +57 -0
  157. package/lib/xlsx/xform/simple/string-xform.js +51 -0
  158. package/lib/xlsx/xform/static-xform.js +64 -0
  159. package/lib/xlsx/xform/strings/phonetic-text-xform.js +98 -0
  160. package/lib/xlsx/xform/strings/rich-text-xform.js +101 -0
  161. package/lib/xlsx/xform/strings/shared-string-xform.js +102 -0
  162. package/lib/xlsx/xform/strings/shared-strings-xform.js +127 -0
  163. package/lib/xlsx/xform/strings/text-xform.js +44 -0
  164. package/lib/xlsx/xform/style/alignment-xform.js +172 -0
  165. package/lib/xlsx/xform/style/border-xform.js +207 -0
  166. package/lib/xlsx/xform/style/color-xform.js +63 -0
  167. package/lib/xlsx/xform/style/dxf-xform.js +111 -0
  168. package/lib/xlsx/xform/style/fill-xform.js +364 -0
  169. package/lib/xlsx/xform/style/font-xform.js +102 -0
  170. package/lib/xlsx/xform/style/numfmt-xform.js +63 -0
  171. package/lib/xlsx/xform/style/protection-xform.js +60 -0
  172. package/lib/xlsx/xform/style/style-xform.js +125 -0
  173. package/lib/xlsx/xform/style/styles-xform.js +527 -0
  174. package/lib/xlsx/xform/style/underline-xform.js +47 -0
  175. package/lib/xlsx/xform/table/auto-filter-xform.js +81 -0
  176. package/lib/xlsx/xform/table/custom-filter-xform.js +33 -0
  177. package/lib/xlsx/xform/table/filter-column-xform.js +96 -0
  178. package/lib/xlsx/xform/table/filter-xform.js +31 -0
  179. package/lib/xlsx/xform/table/table-column-xform.js +44 -0
  180. package/lib/xlsx/xform/table/table-style-info-xform.js +41 -0
  181. package/lib/xlsx/xform/table/table-xform.js +131 -0
  182. package/lib/xlsx/xlsx.js +774 -0
  183. package/lib/xlsx/xml/theme1.js +3 -0
  184. package/lib/xlsx/xml/theme1.xml +318 -0
  185. package/package.json +149 -0
package/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ import * as ExcelJS from './dist/es5';
2
+ export default ExcelJS;
package/lib/csv/csv.js ADDED
@@ -0,0 +1,191 @@
1
+ const fs = require('fs');
2
+ const fastCsv = require('fast-csv');
3
+ const customParseFormat = require('dayjs/plugin/customParseFormat');
4
+ const utc = require('dayjs/plugin/utc');
5
+ const dayjs = require('dayjs').extend(customParseFormat).extend(utc);
6
+ const StreamBuf = require('../utils/stream-buf');
7
+
8
+ const {
9
+ fs: {exists},
10
+ } = require('../utils/utils');
11
+
12
+ /* eslint-disable quote-props */
13
+ const SpecialValues = {
14
+ true: true,
15
+ false: false,
16
+ '#N/A': {error: '#N/A'},
17
+ '#REF!': {error: '#REF!'},
18
+ '#NAME?': {error: '#NAME?'},
19
+ '#DIV/0!': {error: '#DIV/0!'},
20
+ '#NULL!': {error: '#NULL!'},
21
+ '#VALUE!': {error: '#VALUE!'},
22
+ '#NUM!': {error: '#NUM!'},
23
+ };
24
+ /* eslint-ensable quote-props */
25
+
26
+ class CSV {
27
+ constructor(workbook) {
28
+ this.workbook = workbook;
29
+ this.worksheet = null;
30
+ }
31
+
32
+ async readFile(filename, options) {
33
+ options = options || {};
34
+ if (!(await exists(filename))) {
35
+ throw new Error(`File not found: ${filename}`);
36
+ }
37
+ const stream = fs.createReadStream(filename);
38
+ const worksheet = await this.read(stream, options);
39
+ stream.close();
40
+ return worksheet;
41
+ }
42
+
43
+ read(stream, options) {
44
+ options = options || {};
45
+
46
+ return new Promise((resolve, reject) => {
47
+ const worksheet = this.workbook.addWorksheet(options.sheetName);
48
+
49
+ const dateFormats = options.dateFormats || [
50
+ 'YYYY-MM-DD[T]HH:mm:ssZ',
51
+ 'YYYY-MM-DD[T]HH:mm:ss',
52
+ 'MM-DD-YYYY',
53
+ 'YYYY-MM-DD',
54
+ ];
55
+ const map =
56
+ options.map ||
57
+ function(datum) {
58
+ if (datum === '') {
59
+ return null;
60
+ }
61
+ const datumNumber = Number(datum);
62
+ if (!Number.isNaN(datumNumber) && datumNumber !== Infinity) {
63
+ return datumNumber;
64
+ }
65
+ const dt = dateFormats.reduce((matchingDate, currentDateFormat) => {
66
+ if (matchingDate) {
67
+ return matchingDate;
68
+ }
69
+ const dayjsObj = dayjs(datum, currentDateFormat, true);
70
+ if (dayjsObj.isValid()) {
71
+ return dayjsObj;
72
+ }
73
+ return null;
74
+ }, null);
75
+ if (dt) {
76
+ return new Date(dt.valueOf());
77
+ }
78
+ const special = SpecialValues[datum];
79
+ if (special !== undefined) {
80
+ return special;
81
+ }
82
+ return datum;
83
+ };
84
+
85
+ const csvStream = fastCsv
86
+ .parse(options.parserOptions)
87
+ .on('data', data => {
88
+ worksheet.addRow(data.map(map));
89
+ })
90
+ .on('end', () => {
91
+ csvStream.emit('worksheet', worksheet);
92
+ });
93
+
94
+ csvStream.on('worksheet', resolve).on('error', reject);
95
+
96
+ stream.pipe(csvStream);
97
+ });
98
+ }
99
+
100
+ /**
101
+ * @deprecated since version 4.0. You should use `CSV#read` instead. Please follow upgrade instruction: https://github.com/exceljs/exceljs/blob/master/UPGRADE-4.0.md
102
+ */
103
+ createInputStream() {
104
+ throw new Error(
105
+ '`CSV#createInputStream` is deprecated. You should use `CSV#read` instead. This method will be removed in version 5.0. Please follow upgrade instruction: https://github.com/exceljs/exceljs/blob/master/UPGRADE-4.0.md'
106
+ );
107
+ }
108
+
109
+ write(stream, options) {
110
+ return new Promise((resolve, reject) => {
111
+ options = options || {};
112
+ // const encoding = options.encoding || 'utf8';
113
+ // const separator = options.separator || ',';
114
+ // const quoteChar = options.quoteChar || '\'';
115
+
116
+ const worksheet = this.workbook.getWorksheet(options.sheetName || options.sheetId);
117
+
118
+ const csvStream = fastCsv.format(options.formatterOptions);
119
+ stream.on('finish', () => {
120
+ resolve();
121
+ });
122
+ csvStream.on('error', reject);
123
+ csvStream.pipe(stream);
124
+
125
+ const {dateFormat, dateUTC} = options;
126
+ const map =
127
+ options.map ||
128
+ (value => {
129
+ if (value) {
130
+ if (value.text || value.hyperlink) {
131
+ return value.hyperlink || value.text || '';
132
+ }
133
+ if (value.formula || value.result) {
134
+ return value.result || '';
135
+ }
136
+ if (value instanceof Date) {
137
+ if (dateFormat) {
138
+ return dateUTC
139
+ ? dayjs.utc(value).format(dateFormat)
140
+ : dayjs(value).format(dateFormat);
141
+ }
142
+ return dateUTC ? dayjs.utc(value).format() : dayjs(value).format();
143
+ }
144
+ if (value.error) {
145
+ return value.error;
146
+ }
147
+ if (typeof value === 'object') {
148
+ return JSON.stringify(value);
149
+ }
150
+ }
151
+ return value;
152
+ });
153
+
154
+ const includeEmptyRows = options.includeEmptyRows === undefined || options.includeEmptyRows;
155
+ let lastRow = 1;
156
+ if (worksheet) {
157
+ worksheet.eachRow((row, rowNumber) => {
158
+ if (includeEmptyRows) {
159
+ while (lastRow++ < rowNumber - 1) {
160
+ csvStream.write([]);
161
+ }
162
+ }
163
+ const {values} = row;
164
+ values.shift();
165
+ csvStream.write(values.map(map));
166
+ lastRow = rowNumber;
167
+ });
168
+ }
169
+ csvStream.end();
170
+ });
171
+ }
172
+
173
+ writeFile(filename, options) {
174
+ options = options || {};
175
+
176
+ const streamOptions = {
177
+ encoding: options.encoding || 'utf8',
178
+ };
179
+ const stream = fs.createWriteStream(filename, streamOptions);
180
+
181
+ return this.write(stream, options);
182
+ }
183
+
184
+ async writeBuffer(options) {
185
+ const stream = new StreamBuf();
186
+ await this.write(stream, options);
187
+ return stream.read();
188
+ }
189
+ }
190
+
191
+ module.exports = CSV;
@@ -0,0 +1,74 @@
1
+ const {EventEmitter} = require('events');
2
+
3
+ class LineBuffer extends EventEmitter {
4
+ constructor(options) {
5
+ super();
6
+
7
+ this.encoding = options.encoding;
8
+
9
+ this.buffer = null;
10
+
11
+ // part of cork/uncork
12
+ this.corked = false;
13
+ this.queue = [];
14
+ }
15
+
16
+ // Events:
17
+ // line: here is a line
18
+ // done: all lines emitted
19
+
20
+ write(chunk) {
21
+ // find line or lines in chunk and emit them if not corked
22
+ // or queue them if corked
23
+ const data = this.buffer ? this.buffer + chunk : chunk;
24
+ const lines = data.split(/\r?\n/g);
25
+
26
+ // save the last line
27
+ this.buffer = lines.pop();
28
+
29
+ lines.forEach(function(line) {
30
+ if (this.corked) {
31
+ this.queue.push(line);
32
+ } else {
33
+ this.emit('line', line);
34
+ }
35
+ });
36
+
37
+ return !this.corked;
38
+ }
39
+
40
+ cork() {
41
+ this.corked = true;
42
+ }
43
+
44
+ uncork() {
45
+ this.corked = false;
46
+ this._flush();
47
+
48
+ // tell the source I'm ready again
49
+ this.emit('drain');
50
+ }
51
+
52
+ setDefaultEncoding() {
53
+ // ?
54
+ }
55
+
56
+ end() {
57
+ if (this.buffer) {
58
+ this.emit('line', this.buffer);
59
+ this.buffer = null;
60
+ }
61
+ this.emit('done');
62
+ }
63
+
64
+ _flush() {
65
+ if (!this.corked) {
66
+ this.queue.forEach(line => {
67
+ this.emit('line', line);
68
+ });
69
+ this.queue = [];
70
+ }
71
+ }
72
+ }
73
+
74
+ module.exports = LineBuffer;
@@ -0,0 +1,135 @@
1
+ // =======================================================================================================
2
+ // StreamConverter
3
+ //
4
+ // convert between encoding schemes in a stream
5
+ // Work in Progress - Will complete this at some point
6
+ let jconv;
7
+
8
+ class StreamConverter {
9
+ constructor(inner, options) {
10
+ this.inner = inner;
11
+
12
+ options = options || {};
13
+ this.innerEncoding = (options.innerEncoding || 'UTF8').toUpperCase();
14
+ this.outerEncoding = (options.outerEncoding || 'UTF8').toUpperCase();
15
+
16
+ this.innerBOM = options.innerBOM || null;
17
+ this.outerBOM = options.outerBOM || null;
18
+
19
+ this.writeStarted = false;
20
+ }
21
+
22
+ convertInwards(data) {
23
+ if (data) {
24
+ if (typeof data === 'string') {
25
+ data = Buffer.from(data, this.outerEncoding);
26
+ }
27
+
28
+ if (this.innerEncoding !== this.outerEncoding) {
29
+ data = jconv.convert(data, this.outerEncoding, this.innerEncoding);
30
+ }
31
+ }
32
+
33
+ return data;
34
+ }
35
+
36
+ convertOutwards(data) {
37
+ if (typeof data === 'string') {
38
+ data = Buffer.from(data, this.innerEncoding);
39
+ }
40
+
41
+ if (this.innerEncoding !== this.outerEncoding) {
42
+ data = jconv.convert(data, this.innerEncoding, this.outerEncoding);
43
+ }
44
+ return data;
45
+ }
46
+
47
+ addListener(event, handler) {
48
+ this.inner.addListener(event, handler);
49
+ }
50
+
51
+ removeListener(event, handler) {
52
+ this.inner.removeListener(event, handler);
53
+ }
54
+
55
+ write(data, encoding, callback) {
56
+ if (encoding instanceof Function) {
57
+ callback = encoding;
58
+ encoding = undefined;
59
+ }
60
+
61
+ if (!this.writeStarted) {
62
+ // if inner encoding has BOM, write it now
63
+ if (this.innerBOM) {
64
+ this.inner.write(this.innerBOM);
65
+ }
66
+
67
+ // if outer encoding has BOM, delete it now
68
+ if (this.outerBOM) {
69
+ if (data.length <= this.outerBOM.length) {
70
+ if (callback) {
71
+ callback();
72
+ }
73
+ return;
74
+ }
75
+ const bomless = Buffer.alloc(data.length - this.outerBOM.length);
76
+ data.copy(bomless, 0, this.outerBOM.length, data.length);
77
+ data = bomless;
78
+ }
79
+
80
+ this.writeStarted = true;
81
+ }
82
+
83
+ this.inner.write(
84
+ this.convertInwards(data),
85
+ encoding ? this.innerEncoding : undefined,
86
+ callback
87
+ );
88
+ }
89
+
90
+ read() {
91
+ // TBD
92
+ }
93
+
94
+ pipe(destination, options) {
95
+ const reverseConverter = new StreamConverter(destination, {
96
+ innerEncoding: this.outerEncoding,
97
+ outerEncoding: this.innerEncoding,
98
+ innerBOM: this.outerBOM,
99
+ outerBOM: this.innerBOM,
100
+ });
101
+
102
+ this.inner.pipe(reverseConverter, options);
103
+ }
104
+
105
+ close() {
106
+ this.inner.close();
107
+ }
108
+
109
+ on(type, callback) {
110
+ switch (type) {
111
+ case 'data':
112
+ this.inner.on('data', chunk => {
113
+ callback(this.convertOutwards(chunk));
114
+ });
115
+ return this;
116
+ default:
117
+ this.inner.on(type, callback);
118
+ return this;
119
+ }
120
+ }
121
+
122
+ once(type, callback) {
123
+ this.inner.once(type, callback);
124
+ }
125
+
126
+ end(chunk, encoding, callback) {
127
+ this.inner.end(this.convertInwards(chunk), this.innerEncoding, callback);
128
+ }
129
+
130
+ emit(type, value) {
131
+ this.inner.emit(type, value);
132
+ }
133
+ }
134
+
135
+ module.exports = StreamConverter;
@@ -0,0 +1,91 @@
1
+ 'use strict';
2
+
3
+ const colCache = require('../utils/col-cache');
4
+
5
+ class Anchor {
6
+ constructor(worksheet, address, offset = 0) {
7
+ this.worksheet = worksheet;
8
+
9
+ if (!address) {
10
+ this.nativeCol = 0;
11
+ this.nativeColOff = 0;
12
+ this.nativeRow = 0;
13
+ this.nativeRowOff = 0;
14
+ } else if (typeof address === 'string') {
15
+ const decoded = colCache.decodeAddress(address);
16
+ this.nativeCol = decoded.col + offset;
17
+ this.nativeColOff = 0;
18
+ this.nativeRow = decoded.row + offset;
19
+ this.nativeRowOff = 0;
20
+ } else if (address.nativeCol !== undefined) {
21
+ this.nativeCol = address.nativeCol || 0;
22
+ this.nativeColOff = address.nativeColOff || 0;
23
+ this.nativeRow = address.nativeRow || 0;
24
+ this.nativeRowOff = address.nativeRowOff || 0;
25
+ } else if (address.col !== undefined) {
26
+ this.col = address.col + offset;
27
+ this.row = address.row + offset;
28
+ } else {
29
+ this.nativeCol = 0;
30
+ this.nativeColOff = 0;
31
+ this.nativeRow = 0;
32
+ this.nativeRowOff = 0;
33
+ }
34
+ }
35
+
36
+ static asInstance(model) {
37
+ return model instanceof Anchor || model == null ? model : new Anchor(model);
38
+ }
39
+
40
+ get col() {
41
+ return this.nativeCol + (Math.min(this.colWidth - 1, this.nativeColOff) / this.colWidth);
42
+ }
43
+
44
+ set col(v) {
45
+ this.nativeCol = Math.floor(v);
46
+ this.nativeColOff = Math.floor((v - this.nativeCol) * this.colWidth);
47
+ }
48
+
49
+ get row() {
50
+ return this.nativeRow + (Math.min(this.rowHeight - 1, this.nativeRowOff) / this.rowHeight);
51
+ }
52
+
53
+ set row(v) {
54
+ this.nativeRow = Math.floor(v);
55
+ this.nativeRowOff = Math.floor((v - this.nativeRow) * this.rowHeight);
56
+ }
57
+
58
+ get colWidth() {
59
+ return this.worksheet &&
60
+ this.worksheet.getColumn(this.nativeCol + 1) &&
61
+ this.worksheet.getColumn(this.nativeCol + 1).isCustomWidth
62
+ ? Math.floor(this.worksheet.getColumn(this.nativeCol + 1).width * 10000)
63
+ : 640000;
64
+ }
65
+
66
+ get rowHeight() {
67
+ return this.worksheet &&
68
+ this.worksheet.getRow(this.nativeRow + 1) &&
69
+ this.worksheet.getRow(this.nativeRow + 1).height
70
+ ? Math.floor(this.worksheet.getRow(this.nativeRow + 1).height * 10000)
71
+ : 180000;
72
+ }
73
+
74
+ get model() {
75
+ return {
76
+ nativeCol: this.nativeCol,
77
+ nativeColOff: this.nativeColOff,
78
+ nativeRow: this.nativeRow,
79
+ nativeRowOff: this.nativeRowOff,
80
+ };
81
+ }
82
+
83
+ set model(value) {
84
+ this.nativeCol = value.nativeCol;
85
+ this.nativeColOff = value.nativeColOff;
86
+ this.nativeRow = value.nativeRow;
87
+ this.nativeRowOff = value.nativeRowOff;
88
+ }
89
+ }
90
+
91
+ module.exports = Anchor;