@cj-tech-master/excelts 1.6.2 → 1.6.3
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.
- package/README.md +19 -0
- package/README_zh.md +19 -0
- package/dist/browser/excelts.iife.js +1 -1
- package/dist/browser/excelts.iife.js.map +1 -1
- package/dist/browser/excelts.iife.min.js +1 -1
- package/dist/cjs/stream/xlsx/hyperlink-reader.js +1 -1
- package/dist/cjs/stream/xlsx/workbook-reader.js +7 -4
- package/dist/cjs/stream/xlsx/workbook-writer.js +37 -23
- package/dist/cjs/stream/xlsx/worksheet-reader.js +12 -8
- package/dist/cjs/stream/xlsx/worksheet-writer.js +12 -6
- package/dist/esm/stream/xlsx/hyperlink-reader.js +1 -1
- package/dist/esm/stream/xlsx/workbook-reader.js +7 -4
- package/dist/esm/stream/xlsx/workbook-writer.js +37 -23
- package/dist/esm/stream/xlsx/worksheet-reader.js +12 -8
- package/dist/esm/stream/xlsx/worksheet-writer.js +12 -6
- package/dist/types/doc/table.d.ts +2 -2
- package/dist/types/index.d.ts +3 -0
- package/dist/types/stream/xlsx/hyperlink-reader.d.ts +11 -11
- package/dist/types/stream/xlsx/workbook-reader.d.ts +125 -36
- package/dist/types/stream/xlsx/workbook-writer.d.ts +105 -22
- package/dist/types/stream/xlsx/worksheet-reader.d.ts +40 -22
- package/dist/types/stream/xlsx/worksheet-writer.d.ts +83 -49
- package/dist/types/types.d.ts +4 -16
- package/package.json +1 -1
|
@@ -52,7 +52,7 @@ class HyperlinkReader extends events_1.EventEmitter {
|
|
|
52
52
|
case rel_type_js_1.RelType.Hyperlink:
|
|
53
53
|
{
|
|
54
54
|
const relationship = {
|
|
55
|
-
type: enums_js_1.Enums.RelationshipType.
|
|
55
|
+
type: enums_js_1.Enums.RelationshipType.Hyperlink,
|
|
56
56
|
rId,
|
|
57
57
|
target: node.attributes.Target,
|
|
58
58
|
targetMode: node.attributes.TargetMode
|
|
@@ -73,6 +73,9 @@ class WorkbookReader extends events_1.EventEmitter {
|
|
|
73
73
|
}
|
|
74
74
|
async *parse(input, options) {
|
|
75
75
|
if (options) {
|
|
76
|
+
// Note: This replaces all options, not merging with constructor defaults.
|
|
77
|
+
// This is intentional for backwards compatibility - passing partial options
|
|
78
|
+
// to parse() will leave unspecified options as undefined.
|
|
76
79
|
this.options = options;
|
|
77
80
|
}
|
|
78
81
|
const stream = (this.stream = this._getStream(input || this.input));
|
|
@@ -316,13 +319,13 @@ class WorkbookReader extends events_1.EventEmitter {
|
|
|
316
319
|
const worksheetReader = new worksheet_reader_js_1.WorksheetReader({
|
|
317
320
|
workbook: this,
|
|
318
321
|
id: parseInt(sheetNo, 10),
|
|
319
|
-
iterator,
|
|
322
|
+
iterator: iterator,
|
|
320
323
|
options: this.options
|
|
321
324
|
});
|
|
322
|
-
const matchingRel = (this.workbookRels || []).find(
|
|
325
|
+
const matchingRel = (this.workbookRels || []).find(rel => rel.Target === `worksheets/sheet${sheetNo}.xml`);
|
|
323
326
|
const matchingSheet = matchingRel &&
|
|
324
327
|
this.model &&
|
|
325
|
-
(this.model.sheets || []).find(
|
|
328
|
+
(this.model.sheets || []).find(sheet => sheet.rId === matchingRel.Id);
|
|
326
329
|
if (matchingSheet) {
|
|
327
330
|
worksheetReader.id = matchingSheet.id;
|
|
328
331
|
worksheetReader.name = matchingSheet.name;
|
|
@@ -337,7 +340,7 @@ class WorkbookReader extends events_1.EventEmitter {
|
|
|
337
340
|
const hyperlinksReader = new hyperlink_reader_js_1.HyperlinkReader({
|
|
338
341
|
workbook: this,
|
|
339
342
|
id: parseInt(sheetNo, 10),
|
|
340
|
-
iterator,
|
|
343
|
+
iterator: iterator,
|
|
341
344
|
options: this.options
|
|
342
345
|
});
|
|
343
346
|
if (this.options.hyperlinks === "emit") {
|
|
@@ -98,14 +98,14 @@ class WorkbookWriter {
|
|
|
98
98
|
let buffer;
|
|
99
99
|
if (base64) {
|
|
100
100
|
// Use Buffer.from for efficient base64 decoding
|
|
101
|
-
const base64Data = typeof data === "string" ? data :
|
|
101
|
+
const base64Data = typeof data === "string" ? data : new TextDecoder().decode(data);
|
|
102
102
|
buffer = Buffer.from(base64Data, "base64");
|
|
103
103
|
}
|
|
104
104
|
else if (typeof data === "string") {
|
|
105
105
|
buffer = Buffer.from(data, "utf8");
|
|
106
106
|
}
|
|
107
107
|
else {
|
|
108
|
-
buffer =
|
|
108
|
+
buffer = data;
|
|
109
109
|
}
|
|
110
110
|
zipFile.push(buffer, true); // true = final chunk
|
|
111
111
|
}
|
|
@@ -125,15 +125,15 @@ class WorkbookWriter {
|
|
|
125
125
|
// if there are any uncommitted worksheets, commit them now and wait
|
|
126
126
|
const promises = this._worksheets.map(commitWorksheet);
|
|
127
127
|
if (promises.length) {
|
|
128
|
-
return Promise.all(promises);
|
|
128
|
+
return Promise.all(promises).then(() => { });
|
|
129
129
|
}
|
|
130
130
|
return Promise.resolve();
|
|
131
131
|
}
|
|
132
132
|
async commit() {
|
|
133
|
-
// commit all worksheets, then add
|
|
133
|
+
// commit all worksheets, then add supplementary files
|
|
134
134
|
await this.promise;
|
|
135
|
-
await this.addMedia();
|
|
136
135
|
await this._commitWorksheets();
|
|
136
|
+
await this.addMedia();
|
|
137
137
|
await Promise.all([
|
|
138
138
|
this.addContentTypes(),
|
|
139
139
|
this.addApp(),
|
|
@@ -155,28 +155,39 @@ class WorkbookWriter {
|
|
|
155
155
|
}
|
|
156
156
|
return this._worksheets.length || 1;
|
|
157
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Add Image to Workbook and return the id
|
|
160
|
+
*/
|
|
158
161
|
addImage(image) {
|
|
159
162
|
const id = this.media.length;
|
|
160
|
-
const medium =
|
|
163
|
+
const medium = {
|
|
164
|
+
...image,
|
|
161
165
|
type: "image",
|
|
162
166
|
name: `image${id}.${image.extension}`
|
|
163
|
-
}
|
|
167
|
+
};
|
|
164
168
|
this.media.push(medium);
|
|
165
169
|
return id;
|
|
166
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Get image by id
|
|
173
|
+
*/
|
|
167
174
|
getImage(id) {
|
|
168
175
|
return this.media[id];
|
|
169
176
|
}
|
|
170
|
-
|
|
177
|
+
/**
|
|
178
|
+
* Add a new worksheet and return a reference to it
|
|
179
|
+
*/
|
|
180
|
+
addWorksheet(name, options) {
|
|
171
181
|
// it's possible to add a worksheet with different than default
|
|
172
182
|
// shared string handling
|
|
173
183
|
// in fact, it's even possible to switch it mid-sheet
|
|
174
|
-
const
|
|
175
|
-
|
|
184
|
+
const opts = options || {};
|
|
185
|
+
const useSharedStrings = opts.useSharedStrings !== undefined ? opts.useSharedStrings : this.useSharedStrings;
|
|
186
|
+
if (opts.tabColor) {
|
|
176
187
|
console.trace("tabColor option has moved to { properties: tabColor: {...} }");
|
|
177
|
-
|
|
178
|
-
tabColor:
|
|
179
|
-
},
|
|
188
|
+
opts.properties = Object.assign({
|
|
189
|
+
tabColor: opts.tabColor
|
|
190
|
+
}, opts.properties);
|
|
180
191
|
}
|
|
181
192
|
const id = this.nextId;
|
|
182
193
|
name = name || `sheet${id}`;
|
|
@@ -185,16 +196,19 @@ class WorkbookWriter {
|
|
|
185
196
|
name,
|
|
186
197
|
workbook: this,
|
|
187
198
|
useSharedStrings,
|
|
188
|
-
properties:
|
|
189
|
-
state:
|
|
190
|
-
pageSetup:
|
|
191
|
-
views:
|
|
192
|
-
autoFilter:
|
|
193
|
-
headerFooter:
|
|
199
|
+
properties: opts.properties,
|
|
200
|
+
state: opts.state,
|
|
201
|
+
pageSetup: opts.pageSetup,
|
|
202
|
+
views: opts.views,
|
|
203
|
+
autoFilter: opts.autoFilter,
|
|
204
|
+
headerFooter: opts.headerFooter
|
|
194
205
|
});
|
|
195
206
|
this._worksheets[id] = worksheet;
|
|
196
207
|
return worksheet;
|
|
197
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Fetch sheet by name or id
|
|
211
|
+
*/
|
|
198
212
|
getWorksheet(id) {
|
|
199
213
|
if (id === undefined) {
|
|
200
214
|
return this._worksheets.find(() => true);
|
|
@@ -203,7 +217,7 @@ class WorkbookWriter {
|
|
|
203
217
|
return this._worksheets[id];
|
|
204
218
|
}
|
|
205
219
|
if (typeof id === "string") {
|
|
206
|
-
return this._worksheets.find(
|
|
220
|
+
return this._worksheets.find(worksheet => worksheet && worksheet.name === id);
|
|
207
221
|
}
|
|
208
222
|
return undefined;
|
|
209
223
|
}
|
|
@@ -256,7 +270,7 @@ class WorkbookWriter {
|
|
|
256
270
|
reject(err);
|
|
257
271
|
}
|
|
258
272
|
else {
|
|
259
|
-
resolve(data);
|
|
273
|
+
resolve(new Uint8Array(data));
|
|
260
274
|
}
|
|
261
275
|
});
|
|
262
276
|
});
|
|
@@ -265,13 +279,13 @@ class WorkbookWriter {
|
|
|
265
279
|
}
|
|
266
280
|
if (medium.buffer) {
|
|
267
281
|
this._addFile(medium.buffer, filename);
|
|
268
|
-
return
|
|
282
|
+
return;
|
|
269
283
|
}
|
|
270
284
|
if (medium.base64) {
|
|
271
285
|
const dataimg64 = medium.base64;
|
|
272
286
|
const content = dataimg64.substring(dataimg64.indexOf(",") + 1);
|
|
273
287
|
this._addFile(content, filename, true);
|
|
274
|
-
return
|
|
288
|
+
return;
|
|
275
289
|
}
|
|
276
290
|
}
|
|
277
291
|
throw new Error("Unsupported media");
|
|
@@ -28,7 +28,7 @@ class WorksheetReader extends events_1.EventEmitter {
|
|
|
28
28
|
destroy() {
|
|
29
29
|
throw new Error("Invalid Operation: destroy");
|
|
30
30
|
}
|
|
31
|
-
// return the current dimensions of the
|
|
31
|
+
// return the current dimensions of the reader
|
|
32
32
|
get dimensions() {
|
|
33
33
|
return this._dimensions;
|
|
34
34
|
}
|
|
@@ -47,7 +47,7 @@ class WorksheetReader extends events_1.EventEmitter {
|
|
|
47
47
|
if (col) {
|
|
48
48
|
return col;
|
|
49
49
|
}
|
|
50
|
-
//
|
|
50
|
+
// otherwise, assume letter
|
|
51
51
|
c = col_cache_js_1.colCache.l2n(c);
|
|
52
52
|
}
|
|
53
53
|
if (!this._columns) {
|
|
@@ -88,9 +88,9 @@ class WorksheetReader extends events_1.EventEmitter {
|
|
|
88
88
|
}
|
|
89
89
|
async *[Symbol.asyncIterator]() {
|
|
90
90
|
for await (const events of this.parse()) {
|
|
91
|
-
for (const
|
|
92
|
-
if (eventType === "row") {
|
|
93
|
-
yield value;
|
|
91
|
+
for (const event of events) {
|
|
92
|
+
if (event.eventType === "row") {
|
|
93
|
+
yield event.value;
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
@@ -286,6 +286,7 @@ class WorksheetReader extends events_1.EventEmitter {
|
|
|
286
286
|
cell.value = sharedStrings[index];
|
|
287
287
|
}
|
|
288
288
|
else {
|
|
289
|
+
// Streaming format - unresolved shared string reference
|
|
289
290
|
cell.value = {
|
|
290
291
|
sharedString: index
|
|
291
292
|
};
|
|
@@ -302,19 +303,22 @@ class WorksheetReader extends events_1.EventEmitter {
|
|
|
302
303
|
case "b":
|
|
303
304
|
cell.value = parseInt(c.v.text, 10) !== 0;
|
|
304
305
|
break;
|
|
305
|
-
default:
|
|
306
|
-
|
|
307
|
-
|
|
306
|
+
default: {
|
|
307
|
+
const numFmtStr = typeof cell.numFmt === "string" ? cell.numFmt : cell.numFmt?.formatCode;
|
|
308
|
+
if (numFmtStr && (0, utils_js_1.isDateFmt)(numFmtStr)) {
|
|
309
|
+
cell.value = (0, utils_js_1.excelToDate)(parseFloat(c.v.text), properties?.model?.date1904);
|
|
308
310
|
}
|
|
309
311
|
else {
|
|
310
312
|
cell.value = parseFloat(c.v.text);
|
|
311
313
|
}
|
|
312
314
|
break;
|
|
315
|
+
}
|
|
313
316
|
}
|
|
314
317
|
}
|
|
315
318
|
if (hyperlinks) {
|
|
316
319
|
const hyperlink = hyperlinks[c.ref];
|
|
317
320
|
if (hyperlink) {
|
|
321
|
+
// Streaming-specific: assign text and hyperlink for further processing
|
|
318
322
|
cell.text = cell.value;
|
|
319
323
|
cell.value = undefined;
|
|
320
324
|
cell.hyperlink = hyperlink;
|
|
@@ -278,20 +278,26 @@ class WorksheetWriter {
|
|
|
278
278
|
}
|
|
279
279
|
// iterate over every uncommitted row in the worksheet, including maybe empty rows
|
|
280
280
|
eachRow(options, iteratee) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
281
|
+
let callback;
|
|
282
|
+
let opts;
|
|
283
|
+
if (typeof options === "function") {
|
|
284
|
+
callback = options;
|
|
285
|
+
opts = undefined;
|
|
284
286
|
}
|
|
285
|
-
|
|
287
|
+
else {
|
|
288
|
+
callback = iteratee;
|
|
289
|
+
opts = options;
|
|
290
|
+
}
|
|
291
|
+
if (opts && opts.includeEmpty) {
|
|
286
292
|
const n = this._nextRow;
|
|
287
293
|
for (let i = this._rowZero; i < n; i++) {
|
|
288
|
-
|
|
294
|
+
callback(this.getRow(i), i);
|
|
289
295
|
}
|
|
290
296
|
}
|
|
291
297
|
else {
|
|
292
298
|
this._rows.forEach(row => {
|
|
293
299
|
if (row.hasValues) {
|
|
294
|
-
|
|
300
|
+
callback(row, row.number);
|
|
295
301
|
}
|
|
296
302
|
});
|
|
297
303
|
}
|
|
@@ -49,7 +49,7 @@ class HyperlinkReader extends EventEmitter {
|
|
|
49
49
|
case RelType.Hyperlink:
|
|
50
50
|
{
|
|
51
51
|
const relationship = {
|
|
52
|
-
type: Enums.RelationshipType.
|
|
52
|
+
type: Enums.RelationshipType.Hyperlink,
|
|
53
53
|
rId,
|
|
54
54
|
target: node.attributes.Target,
|
|
55
55
|
targetMode: node.attributes.TargetMode
|
|
@@ -67,6 +67,9 @@ class WorkbookReader extends EventEmitter {
|
|
|
67
67
|
}
|
|
68
68
|
async *parse(input, options) {
|
|
69
69
|
if (options) {
|
|
70
|
+
// Note: This replaces all options, not merging with constructor defaults.
|
|
71
|
+
// This is intentional for backwards compatibility - passing partial options
|
|
72
|
+
// to parse() will leave unspecified options as undefined.
|
|
70
73
|
this.options = options;
|
|
71
74
|
}
|
|
72
75
|
const stream = (this.stream = this._getStream(input || this.input));
|
|
@@ -310,13 +313,13 @@ class WorkbookReader extends EventEmitter {
|
|
|
310
313
|
const worksheetReader = new WorksheetReader({
|
|
311
314
|
workbook: this,
|
|
312
315
|
id: parseInt(sheetNo, 10),
|
|
313
|
-
iterator,
|
|
316
|
+
iterator: iterator,
|
|
314
317
|
options: this.options
|
|
315
318
|
});
|
|
316
|
-
const matchingRel = (this.workbookRels || []).find(
|
|
319
|
+
const matchingRel = (this.workbookRels || []).find(rel => rel.Target === `worksheets/sheet${sheetNo}.xml`);
|
|
317
320
|
const matchingSheet = matchingRel &&
|
|
318
321
|
this.model &&
|
|
319
|
-
(this.model.sheets || []).find(
|
|
322
|
+
(this.model.sheets || []).find(sheet => sheet.rId === matchingRel.Id);
|
|
320
323
|
if (matchingSheet) {
|
|
321
324
|
worksheetReader.id = matchingSheet.id;
|
|
322
325
|
worksheetReader.name = matchingSheet.name;
|
|
@@ -331,7 +334,7 @@ class WorkbookReader extends EventEmitter {
|
|
|
331
334
|
const hyperlinksReader = new HyperlinkReader({
|
|
332
335
|
workbook: this,
|
|
333
336
|
id: parseInt(sheetNo, 10),
|
|
334
|
-
iterator,
|
|
337
|
+
iterator: iterator,
|
|
335
338
|
options: this.options
|
|
336
339
|
});
|
|
337
340
|
if (this.options.hyperlinks === "emit") {
|
|
@@ -92,14 +92,14 @@ class WorkbookWriter {
|
|
|
92
92
|
let buffer;
|
|
93
93
|
if (base64) {
|
|
94
94
|
// Use Buffer.from for efficient base64 decoding
|
|
95
|
-
const base64Data = typeof data === "string" ? data :
|
|
95
|
+
const base64Data = typeof data === "string" ? data : new TextDecoder().decode(data);
|
|
96
96
|
buffer = Buffer.from(base64Data, "base64");
|
|
97
97
|
}
|
|
98
98
|
else if (typeof data === "string") {
|
|
99
99
|
buffer = Buffer.from(data, "utf8");
|
|
100
100
|
}
|
|
101
101
|
else {
|
|
102
|
-
buffer =
|
|
102
|
+
buffer = data;
|
|
103
103
|
}
|
|
104
104
|
zipFile.push(buffer, true); // true = final chunk
|
|
105
105
|
}
|
|
@@ -119,15 +119,15 @@ class WorkbookWriter {
|
|
|
119
119
|
// if there are any uncommitted worksheets, commit them now and wait
|
|
120
120
|
const promises = this._worksheets.map(commitWorksheet);
|
|
121
121
|
if (promises.length) {
|
|
122
|
-
return Promise.all(promises);
|
|
122
|
+
return Promise.all(promises).then(() => { });
|
|
123
123
|
}
|
|
124
124
|
return Promise.resolve();
|
|
125
125
|
}
|
|
126
126
|
async commit() {
|
|
127
|
-
// commit all worksheets, then add
|
|
127
|
+
// commit all worksheets, then add supplementary files
|
|
128
128
|
await this.promise;
|
|
129
|
-
await this.addMedia();
|
|
130
129
|
await this._commitWorksheets();
|
|
130
|
+
await this.addMedia();
|
|
131
131
|
await Promise.all([
|
|
132
132
|
this.addContentTypes(),
|
|
133
133
|
this.addApp(),
|
|
@@ -149,28 +149,39 @@ class WorkbookWriter {
|
|
|
149
149
|
}
|
|
150
150
|
return this._worksheets.length || 1;
|
|
151
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Add Image to Workbook and return the id
|
|
154
|
+
*/
|
|
152
155
|
addImage(image) {
|
|
153
156
|
const id = this.media.length;
|
|
154
|
-
const medium =
|
|
157
|
+
const medium = {
|
|
158
|
+
...image,
|
|
155
159
|
type: "image",
|
|
156
160
|
name: `image${id}.${image.extension}`
|
|
157
|
-
}
|
|
161
|
+
};
|
|
158
162
|
this.media.push(medium);
|
|
159
163
|
return id;
|
|
160
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Get image by id
|
|
167
|
+
*/
|
|
161
168
|
getImage(id) {
|
|
162
169
|
return this.media[id];
|
|
163
170
|
}
|
|
164
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Add a new worksheet and return a reference to it
|
|
173
|
+
*/
|
|
174
|
+
addWorksheet(name, options) {
|
|
165
175
|
// it's possible to add a worksheet with different than default
|
|
166
176
|
// shared string handling
|
|
167
177
|
// in fact, it's even possible to switch it mid-sheet
|
|
168
|
-
const
|
|
169
|
-
|
|
178
|
+
const opts = options || {};
|
|
179
|
+
const useSharedStrings = opts.useSharedStrings !== undefined ? opts.useSharedStrings : this.useSharedStrings;
|
|
180
|
+
if (opts.tabColor) {
|
|
170
181
|
console.trace("tabColor option has moved to { properties: tabColor: {...} }");
|
|
171
|
-
|
|
172
|
-
tabColor:
|
|
173
|
-
},
|
|
182
|
+
opts.properties = Object.assign({
|
|
183
|
+
tabColor: opts.tabColor
|
|
184
|
+
}, opts.properties);
|
|
174
185
|
}
|
|
175
186
|
const id = this.nextId;
|
|
176
187
|
name = name || `sheet${id}`;
|
|
@@ -179,16 +190,19 @@ class WorkbookWriter {
|
|
|
179
190
|
name,
|
|
180
191
|
workbook: this,
|
|
181
192
|
useSharedStrings,
|
|
182
|
-
properties:
|
|
183
|
-
state:
|
|
184
|
-
pageSetup:
|
|
185
|
-
views:
|
|
186
|
-
autoFilter:
|
|
187
|
-
headerFooter:
|
|
193
|
+
properties: opts.properties,
|
|
194
|
+
state: opts.state,
|
|
195
|
+
pageSetup: opts.pageSetup,
|
|
196
|
+
views: opts.views,
|
|
197
|
+
autoFilter: opts.autoFilter,
|
|
198
|
+
headerFooter: opts.headerFooter
|
|
188
199
|
});
|
|
189
200
|
this._worksheets[id] = worksheet;
|
|
190
201
|
return worksheet;
|
|
191
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Fetch sheet by name or id
|
|
205
|
+
*/
|
|
192
206
|
getWorksheet(id) {
|
|
193
207
|
if (id === undefined) {
|
|
194
208
|
return this._worksheets.find(() => true);
|
|
@@ -197,7 +211,7 @@ class WorkbookWriter {
|
|
|
197
211
|
return this._worksheets[id];
|
|
198
212
|
}
|
|
199
213
|
if (typeof id === "string") {
|
|
200
|
-
return this._worksheets.find(
|
|
214
|
+
return this._worksheets.find(worksheet => worksheet && worksheet.name === id);
|
|
201
215
|
}
|
|
202
216
|
return undefined;
|
|
203
217
|
}
|
|
@@ -250,7 +264,7 @@ class WorkbookWriter {
|
|
|
250
264
|
reject(err);
|
|
251
265
|
}
|
|
252
266
|
else {
|
|
253
|
-
resolve(data);
|
|
267
|
+
resolve(new Uint8Array(data));
|
|
254
268
|
}
|
|
255
269
|
});
|
|
256
270
|
});
|
|
@@ -259,13 +273,13 @@ class WorkbookWriter {
|
|
|
259
273
|
}
|
|
260
274
|
if (medium.buffer) {
|
|
261
275
|
this._addFile(medium.buffer, filename);
|
|
262
|
-
return
|
|
276
|
+
return;
|
|
263
277
|
}
|
|
264
278
|
if (medium.base64) {
|
|
265
279
|
const dataimg64 = medium.base64;
|
|
266
280
|
const content = dataimg64.substring(dataimg64.indexOf(",") + 1);
|
|
267
281
|
this._addFile(content, filename, true);
|
|
268
|
-
return
|
|
282
|
+
return;
|
|
269
283
|
}
|
|
270
284
|
}
|
|
271
285
|
throw new Error("Unsupported media");
|
|
@@ -25,7 +25,7 @@ class WorksheetReader extends EventEmitter {
|
|
|
25
25
|
destroy() {
|
|
26
26
|
throw new Error("Invalid Operation: destroy");
|
|
27
27
|
}
|
|
28
|
-
// return the current dimensions of the
|
|
28
|
+
// return the current dimensions of the reader
|
|
29
29
|
get dimensions() {
|
|
30
30
|
return this._dimensions;
|
|
31
31
|
}
|
|
@@ -44,7 +44,7 @@ class WorksheetReader extends EventEmitter {
|
|
|
44
44
|
if (col) {
|
|
45
45
|
return col;
|
|
46
46
|
}
|
|
47
|
-
//
|
|
47
|
+
// otherwise, assume letter
|
|
48
48
|
c = colCache.l2n(c);
|
|
49
49
|
}
|
|
50
50
|
if (!this._columns) {
|
|
@@ -85,9 +85,9 @@ class WorksheetReader extends EventEmitter {
|
|
|
85
85
|
}
|
|
86
86
|
async *[Symbol.asyncIterator]() {
|
|
87
87
|
for await (const events of this.parse()) {
|
|
88
|
-
for (const
|
|
89
|
-
if (eventType === "row") {
|
|
90
|
-
yield value;
|
|
88
|
+
for (const event of events) {
|
|
89
|
+
if (event.eventType === "row") {
|
|
90
|
+
yield event.value;
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
}
|
|
@@ -283,6 +283,7 @@ class WorksheetReader extends EventEmitter {
|
|
|
283
283
|
cell.value = sharedStrings[index];
|
|
284
284
|
}
|
|
285
285
|
else {
|
|
286
|
+
// Streaming format - unresolved shared string reference
|
|
286
287
|
cell.value = {
|
|
287
288
|
sharedString: index
|
|
288
289
|
};
|
|
@@ -299,19 +300,22 @@ class WorksheetReader extends EventEmitter {
|
|
|
299
300
|
case "b":
|
|
300
301
|
cell.value = parseInt(c.v.text, 10) !== 0;
|
|
301
302
|
break;
|
|
302
|
-
default:
|
|
303
|
-
|
|
304
|
-
|
|
303
|
+
default: {
|
|
304
|
+
const numFmtStr = typeof cell.numFmt === "string" ? cell.numFmt : cell.numFmt?.formatCode;
|
|
305
|
+
if (numFmtStr && isDateFmt(numFmtStr)) {
|
|
306
|
+
cell.value = excelToDate(parseFloat(c.v.text), properties?.model?.date1904);
|
|
305
307
|
}
|
|
306
308
|
else {
|
|
307
309
|
cell.value = parseFloat(c.v.text);
|
|
308
310
|
}
|
|
309
311
|
break;
|
|
312
|
+
}
|
|
310
313
|
}
|
|
311
314
|
}
|
|
312
315
|
if (hyperlinks) {
|
|
313
316
|
const hyperlink = hyperlinks[c.ref];
|
|
314
317
|
if (hyperlink) {
|
|
318
|
+
// Streaming-specific: assign text and hyperlink for further processing
|
|
315
319
|
cell.text = cell.value;
|
|
316
320
|
cell.value = undefined;
|
|
317
321
|
cell.hyperlink = hyperlink;
|
|
@@ -275,20 +275,26 @@ class WorksheetWriter {
|
|
|
275
275
|
}
|
|
276
276
|
// iterate over every uncommitted row in the worksheet, including maybe empty rows
|
|
277
277
|
eachRow(options, iteratee) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
278
|
+
let callback;
|
|
279
|
+
let opts;
|
|
280
|
+
if (typeof options === "function") {
|
|
281
|
+
callback = options;
|
|
282
|
+
opts = undefined;
|
|
281
283
|
}
|
|
282
|
-
|
|
284
|
+
else {
|
|
285
|
+
callback = iteratee;
|
|
286
|
+
opts = options;
|
|
287
|
+
}
|
|
288
|
+
if (opts && opts.includeEmpty) {
|
|
283
289
|
const n = this._nextRow;
|
|
284
290
|
for (let i = this._rowZero; i < n; i++) {
|
|
285
|
-
|
|
291
|
+
callback(this.getRow(i), i);
|
|
286
292
|
}
|
|
287
293
|
}
|
|
288
294
|
else {
|
|
289
295
|
this._rows.forEach(row => {
|
|
290
296
|
if (row.hasValues) {
|
|
291
|
-
|
|
297
|
+
callback(row, row.number);
|
|
292
298
|
}
|
|
293
299
|
});
|
|
294
300
|
}
|
|
@@ -67,8 +67,8 @@ declare class Table {
|
|
|
67
67
|
set headerRow(value: boolean | undefined);
|
|
68
68
|
get totalsRow(): boolean | undefined;
|
|
69
69
|
set totalsRow(value: boolean | undefined);
|
|
70
|
-
get theme():
|
|
71
|
-
set theme(value:
|
|
70
|
+
get theme(): TableStyleProperties["theme"];
|
|
71
|
+
set theme(value: TableStyleProperties["theme"]);
|
|
72
72
|
get showFirstColumn(): boolean | undefined;
|
|
73
73
|
set showFirstColumn(value: boolean | undefined);
|
|
74
74
|
get showLastColumn(): boolean | undefined;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ export { Image } from "./doc/image.js";
|
|
|
13
13
|
export * from "./doc/anchor.js";
|
|
14
14
|
export { Table } from "./doc/table.js";
|
|
15
15
|
export { DataValidations } from "./doc/data-validations.js";
|
|
16
|
+
export type { WorkbookReaderOptions, ParseEvent, SharedStringEvent, WorksheetReadyEvent, HyperlinksEvent } from "./stream/xlsx/workbook-reader.js";
|
|
17
|
+
export type { WorksheetReaderOptions, WorksheetEvent, RowEvent, HyperlinkEvent, WorksheetHyperlink } from "./stream/xlsx/worksheet-reader.js";
|
|
18
|
+
export type { WorkbookWriterOptions, ZipOptions, ZlibOptions } from "./stream/xlsx/workbook-writer.js";
|
|
16
19
|
export type { PivotTable, PivotTableModel, PivotTableSource, CacheField, DataField, PivotTableSubtotal, ParsedCacheDefinition, ParsedCacheRecords } from "./doc/pivot-table.js";
|
|
17
20
|
export * from "./doc/enums.js";
|
|
18
21
|
export * from "./types.js";
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import type { WorkbookReader, InternalWorksheetOptions } from "./workbook-reader.js";
|
|
3
|
+
export interface HyperlinkReaderOptions {
|
|
4
|
+
workbook: WorkbookReader;
|
|
4
5
|
id: number;
|
|
5
|
-
iterator:
|
|
6
|
-
options:
|
|
6
|
+
iterator: AsyncIterable<unknown>;
|
|
7
|
+
options: InternalWorksheetOptions;
|
|
7
8
|
}
|
|
8
|
-
|
|
9
|
+
/** Hyperlink relationship parsed from worksheet rels */
|
|
10
|
+
export interface Hyperlink {
|
|
9
11
|
type: number;
|
|
10
12
|
rId: string;
|
|
11
13
|
target: string;
|
|
12
14
|
targetMode: string;
|
|
13
15
|
}
|
|
14
16
|
declare class HyperlinkReader extends EventEmitter {
|
|
15
|
-
workbook:
|
|
17
|
+
workbook: WorkbookReader;
|
|
16
18
|
id: number;
|
|
17
|
-
iterator:
|
|
18
|
-
options:
|
|
19
|
-
hyperlinks?:
|
|
20
|
-
[key: string]: Hyperlink;
|
|
21
|
-
};
|
|
19
|
+
iterator: AsyncIterable<unknown>;
|
|
20
|
+
options: InternalWorksheetOptions;
|
|
21
|
+
hyperlinks?: Record<string, Hyperlink>;
|
|
22
22
|
constructor({ workbook, id, iterator, options }: HyperlinkReaderOptions);
|
|
23
23
|
get count(): number;
|
|
24
24
|
each(fn: (hyperlink: Hyperlink, rId: string) => void): void;
|