@justybase/spreadsheet-tasks 1.3.3 → 2.0.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 (57) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +25 -16
  3. package/browser/browser-spreadsheet.js +3037 -0
  4. package/browser/justybase-spreadsheet.min.js +36 -0
  5. package/dist/cjs/index.d.ts +399 -0
  6. package/dist/cjs/index.js +3944 -0
  7. package/dist/cjs/index.js.map +1 -0
  8. package/dist/esm/index.js +3889 -0
  9. package/dist/esm/index.js.map +1 -0
  10. package/dist/esm/package.json +1 -0
  11. package/docs/API.md +8 -9
  12. package/docs/PACKAGING.md +32 -0
  13. package/docs/PUBLISHING.md +8 -1
  14. package/examples/basic-read.ts +1 -1
  15. package/examples/formats-verify.ts +1 -2
  16. package/examples/large-dataset.ts +1 -1
  17. package/package.json +28 -13
  18. package/dist/BiffReaderWriter.d.ts +0 -44
  19. package/dist/BiffReaderWriter.d.ts.map +0 -1
  20. package/dist/BiffReaderWriter.js +0 -282
  21. package/dist/BiffReaderWriter.js.map +0 -1
  22. package/dist/BigBuffer.d.ts +0 -24
  23. package/dist/BigBuffer.d.ts.map +0 -1
  24. package/dist/BigBuffer.js +0 -120
  25. package/dist/BigBuffer.js.map +0 -1
  26. package/dist/ExcelReaderAbstract.d.ts +0 -17
  27. package/dist/ExcelReaderAbstract.d.ts.map +0 -1
  28. package/dist/ExcelReaderAbstract.js +0 -25
  29. package/dist/ExcelReaderAbstract.js.map +0 -1
  30. package/dist/Formats.d.ts +0 -34
  31. package/dist/Formats.d.ts.map +0 -1
  32. package/dist/Formats.js +0 -48
  33. package/dist/Formats.js.map +0 -1
  34. package/dist/ReaderFactory.d.ts +0 -6
  35. package/dist/ReaderFactory.d.ts.map +0 -1
  36. package/dist/ReaderFactory.js +0 -56
  37. package/dist/ReaderFactory.js.map +0 -1
  38. package/dist/XlsbReader.d.ts +0 -24
  39. package/dist/XlsbReader.d.ts.map +0 -1
  40. package/dist/XlsbReader.js +0 -186
  41. package/dist/XlsbReader.js.map +0 -1
  42. package/dist/XlsbWriter.d.ts +0 -80
  43. package/dist/XlsbWriter.d.ts.map +0 -1
  44. package/dist/XlsbWriter.js +0 -964
  45. package/dist/XlsbWriter.js.map +0 -1
  46. package/dist/XlsxReader.d.ts +0 -30
  47. package/dist/XlsxReader.d.ts.map +0 -1
  48. package/dist/XlsxReader.js +0 -341
  49. package/dist/XlsxReader.js.map +0 -1
  50. package/dist/XlsxWriter.d.ts +0 -51
  51. package/dist/XlsxWriter.d.ts.map +0 -1
  52. package/dist/XlsxWriter.js +0 -632
  53. package/dist/XlsxWriter.js.map +0 -1
  54. package/dist/index.d.ts +0 -10
  55. package/dist/index.d.ts.map +0 -1
  56. package/dist/index.js +0 -29
  57. package/dist/index.js.map +0 -1
@@ -1,632 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.XlsxWriter = void 0;
40
- const fs = __importStar(require("fs"));
41
- const archiver_1 = __importDefault(require("archiver"));
42
- const stream_1 = require("stream");
43
- const BigBuffer_1 = require("./BigBuffer");
44
- const Formats_1 = require("./Formats");
45
- const COLUMN_LETTERS = (() => {
46
- const letters = [];
47
- for (let i = 65; i < 91; i++) {
48
- letters.push(String.fromCharCode(i));
49
- }
50
- const temp = [];
51
- for (const p of letters) {
52
- for (let i = 65; i < 91; i++) {
53
- temp.push(p + String.fromCharCode(i));
54
- }
55
- }
56
- letters.push(...temp);
57
- return letters;
58
- })();
59
- const INVALID_SHEET_NAME_CHARS = /[\\/*?[\]:]/g;
60
- class XlsxWriter {
61
- constructor(filePath) {
62
- this.sheetCount = 0;
63
- this.sheetList = [];
64
- this.sstArray = [];
65
- this.sstMap = new Map();
66
- this.sstCntAll = 0;
67
- this.colWidths = [];
68
- this._autofilterIsOn = false;
69
- // Format registry
70
- this._formatRegistry = new Map();
71
- this._formatXfMap = new Map();
72
- this._nextNumfmtId = 165;
73
- this._nextXfIndex = 4;
74
- // Streaming state
75
- this.currentSheetBuffer = null;
76
- this.currentSheetRowNum = 0;
77
- this.currentSheetStartCol = 0;
78
- this.currentSheetEndCol = 0;
79
- this.currentSheetDoAutofilter = false;
80
- this.isStreaming = false;
81
- this.currentColLetters = [];
82
- this.output = fs.createWriteStream(filePath);
83
- this.archive = (0, archiver_1.default)('zip');
84
- this.archive.pipe(this.output);
85
- this._oaEpoch = Date.UTC(1899, 11, 30);
86
- }
87
- _getColumnLetter(colIndex) {
88
- return colIndex < COLUMN_LETTERS.length ? COLUMN_LETTERS[colIndex] : 'A';
89
- }
90
- _sanitizeSheetName(name) {
91
- if (!name || typeof name !== 'string') {
92
- return `Sheet${this.sheetCount + 1}`;
93
- }
94
- let sanitized = name.replace(INVALID_SHEET_NAME_CHARS, '_');
95
- if (sanitized.length > 31) {
96
- sanitized = sanitized.substring(0, 31);
97
- }
98
- if (sanitized.trim().length === 0) {
99
- sanitized = `Sheet${this.sheetCount + 1}`;
100
- }
101
- return sanitized;
102
- }
103
- _escapeSheetNameForXml(name) {
104
- return name
105
- .replace(/&/g, '&amp;')
106
- .replace(/</g, '&lt;')
107
- .replace(/>/g, '&gt;')
108
- .replace(/"/g, '&quot;')
109
- .replace(/'/g, '&apos;');
110
- }
111
- _formatSheetNameForFormula(name) {
112
- if (/[\s\-+=()!@#$%^&]/.test(name) || /^[0-9]/.test(name)) {
113
- const escaped = name.replace(/'/g, "''");
114
- return `'${escaped}'`;
115
- }
116
- return name;
117
- }
118
- addSheet(sheetName, hidden = false) {
119
- const sanitizedName = this._sanitizeSheetName(sheetName);
120
- this.sheetCount++;
121
- const rId = `rId${this.sheetCount}`;
122
- const sheetFileName = `sheet${this.sheetCount}.xml`;
123
- this.sheetList.push({
124
- name: sanitizedName,
125
- pathInArchive: `xl/worksheets/${sheetFileName}`,
126
- hidden: hidden,
127
- nameInArchive: sheetFileName,
128
- sheetId: this.sheetCount,
129
- rId: rId,
130
- filterHeaderRange: null
131
- });
132
- }
133
- _needsEscape(str) {
134
- for (let i = 0; i < str.length; i++) {
135
- const c = str.charCodeAt(i);
136
- if (c === 38 || c === 60 || c === 62 || c === 34 || c === 39 ||
137
- (c >= 0 && c <= 8) || c === 11 || c === 12 || (c >= 14 && c <= 31)) {
138
- return true;
139
- }
140
- }
141
- return false;
142
- }
143
- _escape(str) {
144
- if (typeof str !== 'string')
145
- return str;
146
- if (!this._needsEscape(str))
147
- return str;
148
- return str.replace(/&/g, '&amp;')
149
- .replace(/</g, '&lt;')
150
- .replace(/>/g, '&gt;')
151
- .replace(/"/g, '&quot;')
152
- .replace(/'/g, '&apos;')
153
- // eslint-disable-next-line no-control-regex
154
- .replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, '');
155
- }
156
- startSheet(sheetName, columnCount, headers, options = {}) {
157
- if (this.isStreaming) {
158
- throw new Error('Already in streaming mode. Call endSheet() first.');
159
- }
160
- const { hidden = false, doAutofilter = true, sampleRows } = options;
161
- this.addSheet(sheetName, hidden);
162
- this.isStreaming = true;
163
- this.currentSheetBuffer = new BigBuffer_1.BigBuffer();
164
- this.currentSheetRowNum = 0;
165
- this.currentSheetStartCol = 0;
166
- this.currentSheetEndCol = columnCount;
167
- this.currentSheetDoAutofilter = doAutofilter && headers !== undefined;
168
- const bigBuf = this.currentSheetBuffer;
169
- this.colWidths = new Array(columnCount).fill(-1.0);
170
- const colLetters = new Array(columnCount);
171
- for (let i = 0; i < columnCount; i++) {
172
- colLetters[i] = this._getColumnLetter(i);
173
- }
174
- this.currentColLetters = colLetters;
175
- if (headers) {
176
- for (let i = 0; i < columnCount; i++) {
177
- const len = headers[i] ? headers[i].length + 1 : 0;
178
- let width = 1.25 * len + 2;
179
- if (width > 80)
180
- width = 80;
181
- if (this.colWidths[i] < width)
182
- this.colWidths[i] = width;
183
- }
184
- }
185
- if (sampleRows) {
186
- for (let r = 0; r < Math.min(sampleRows.length, 100); r++) {
187
- const row = sampleRows[r];
188
- for (let c = 0; c < row.length; c++) {
189
- const raw = row[c];
190
- if (raw === null || raw === undefined)
191
- continue;
192
- const val = (0, Formats_1.isFormattedCell)(raw) ? raw.value : raw;
193
- const len = val instanceof Date ? 20 : val.toString().length + 1;
194
- let width = 1.25 * len + 2;
195
- if (width > 80)
196
- width = 80;
197
- if (this.colWidths[c] < width)
198
- this.colWidths[c] = width;
199
- }
200
- }
201
- }
202
- bigBuf.writeString('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
203
- bigBuf.writeString('<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">');
204
- // Dimension - just A1 since we don't know row count in advance
205
- bigBuf.writeString('<dimension ref="A1"/>');
206
- const isFirstSheet = this.sheetCount === 1;
207
- if (headers) {
208
- if (isFirstSheet) {
209
- bigBuf.writeString('<sheetViews><sheetView tabSelected="1" workbookViewId="0"><pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen" /><selection pane="bottomLeft" /></sheetView></sheetViews><sheetFormatPr defaultRowHeight="15"/>');
210
- }
211
- else {
212
- bigBuf.writeString('<sheetViews><sheetView workbookViewId="0"><pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen" /><selection pane="bottomLeft" /></sheetView></sheetViews><sheetFormatPr defaultRowHeight="15"/>');
213
- }
214
- }
215
- else {
216
- if (isFirstSheet) {
217
- bigBuf.writeString('<sheetViews><sheetView tabSelected="1" workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="15"/>');
218
- }
219
- else {
220
- bigBuf.writeString('<sheetViews><sheetView workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="15"/>');
221
- }
222
- }
223
- bigBuf.writeString('<cols>');
224
- for (let i = 0; i < columnCount; i++) {
225
- const width = this.colWidths[i] > 0 ? this.colWidths[i] : 10;
226
- bigBuf.writeString(`<col min="${i + 1}" max="${i + 1}" width="${width}" bestFit="1" customWidth="1" />`);
227
- }
228
- bigBuf.writeString('</cols><sheetData>');
229
- if (headers) {
230
- this.currentSheetRowNum++;
231
- bigBuf.writeString(`<row r="${this.currentSheetRowNum}">`);
232
- for (let c = 0; c < headers.length; c++) {
233
- this._writeStringCell(bigBuf, headers[c], colLetters[c], this.currentSheetRowNum, 3);
234
- }
235
- bigBuf.writeString('</row>');
236
- }
237
- }
238
- writeRow(row) {
239
- if (!this.isStreaming || !this.currentSheetBuffer) {
240
- throw new Error('Not in streaming mode. Call startSheet() first.');
241
- }
242
- if (row.length !== this.currentSheetEndCol - this.currentSheetStartCol) {
243
- throw new Error(`Row length mismatch. Expected ${this.currentSheetEndCol - this.currentSheetStartCol} columns, got ${row.length}`);
244
- }
245
- const bigBuf = this.currentSheetBuffer;
246
- this.currentSheetRowNum++;
247
- bigBuf.writeString(`<row r="${this.currentSheetRowNum}">`);
248
- for (let c = 0; c < row.length; c++) {
249
- const raw = row[c];
250
- if (raw === null || raw === undefined)
251
- continue;
252
- const fmtString = (0, Formats_1.getFormat)(raw);
253
- const val = fmtString !== null ? (0, Formats_1.unwrapCell)(raw) : raw;
254
- const xfIdx = fmtString !== null ? this._registerFormat(fmtString) : -1;
255
- const styleAttr = xfIdx >= 0 ? ` s="${xfIdx}"` : '';
256
- const colRef = this.currentColLetters[c];
257
- if (typeof val === 'number') {
258
- if (Number.isFinite(val)) {
259
- bigBuf.writeString(`<c r="${colRef}${this.currentSheetRowNum}"${styleAttr}><v>${val}</v></c>`);
260
- }
261
- else {
262
- this._writeStringCell(bigBuf, val.toString(), colRef, this.currentSheetRowNum, xfIdx >= 0 ? xfIdx : undefined);
263
- }
264
- }
265
- else if (typeof val === 'bigint') {
266
- this._writeStringCell(bigBuf, val.toString(), colRef, this.currentSheetRowNum, xfIdx >= 0 ? xfIdx : undefined);
267
- }
268
- else if (typeof val === 'boolean') {
269
- bigBuf.writeString(`<c r="${colRef}${this.currentSheetRowNum}" t="b"${styleAttr}><v>${val ? 1 : 0}</v></c>`);
270
- }
271
- else if (val instanceof Date) {
272
- const oaDate = this._toOADate(val);
273
- if (Number.isFinite(oaDate)) {
274
- const finalStyle = xfIdx >= 0 ? xfIdx : 1;
275
- bigBuf.writeString(`<c r="${colRef}${this.currentSheetRowNum}" s="${finalStyle}"><v>${oaDate}</v></c>`);
276
- }
277
- else {
278
- this._writeStringCell(bigBuf, val.toString(), colRef, this.currentSheetRowNum, xfIdx >= 0 ? xfIdx : undefined);
279
- }
280
- }
281
- else {
282
- this._writeStringCell(bigBuf, val.toString(), colRef, this.currentSheetRowNum, xfIdx >= 0 ? xfIdx : undefined);
283
- }
284
- }
285
- bigBuf.writeString('</row>');
286
- }
287
- endSheet() {
288
- if (!this.isStreaming || !this.currentSheetBuffer) {
289
- throw new Error('Not in streaming mode. Call startSheet() first.');
290
- }
291
- const bigBuf = this.currentSheetBuffer;
292
- bigBuf.writeString('</sheetData>');
293
- if (this.currentSheetDoAutofilter && this.currentSheetEndCol > 0) {
294
- this._autofilterIsOn = true;
295
- const filterRef = `A1:${this.currentColLetters[this.currentSheetEndCol - 1]}${this.currentSheetRowNum}`;
296
- bigBuf.writeString(`<autoFilter ref="${filterRef}"/>`);
297
- const sheet = this.sheetList[this.sheetCount - 1];
298
- const formulaSheetName = this._formatSheetNameForFormula(sheet.name);
299
- sheet.filterHeaderRange = `${formulaSheetName}!$A$1:$${this.currentColLetters[this.currentSheetEndCol - 1]}$${this.currentSheetRowNum}`;
300
- }
301
- bigBuf.writeString('</worksheet>');
302
- this.archive.append(stream_1.Readable.from(bigBuf.getChunks()), {
303
- name: this.sheetList[this.sheetCount - 1].pathInArchive
304
- });
305
- // Reset streaming state
306
- this.isStreaming = false;
307
- this.currentSheetBuffer = null;
308
- this.currentSheetRowNum = 0;
309
- this.currentSheetStartCol = 0;
310
- this.currentSheetEndCol = 0;
311
- this.currentSheetDoAutofilter = false;
312
- this.currentColLetters = [];
313
- }
314
- writeSheet(rows, headers = null, doAutofilter = true) {
315
- const bigBuf = new BigBuffer_1.BigBuffer();
316
- let columnCount = 0;
317
- if (rows.length > 0) {
318
- columnCount = rows[0].length;
319
- }
320
- else if (headers) {
321
- columnCount = headers.length;
322
- }
323
- this.colWidths = new Array(columnCount).fill(-1.0);
324
- const colLetters = new Array(columnCount);
325
- for (let i = 0; i < columnCount; i++) {
326
- colLetters[i] = this._getColumnLetter(i);
327
- }
328
- if (headers) {
329
- for (let i = 0; i < columnCount; i++) {
330
- const len = headers[i] ? headers[i].length + 1 : 0;
331
- let width = 1.25 * len + 2;
332
- if (width > 80)
333
- width = 80;
334
- if (this.colWidths[i] < width)
335
- this.colWidths[i] = width;
336
- }
337
- }
338
- for (let r = 0; r < Math.min(rows.length, 100); r++) {
339
- const row = rows[r];
340
- for (let c = 0; c < row.length; c++) {
341
- const raw = row[c];
342
- if (raw === null || raw === undefined)
343
- continue;
344
- const val = (0, Formats_1.isFormattedCell)(raw) ? raw.value : raw;
345
- const len = val instanceof Date ? 20 : val.toString().length + 1;
346
- let width = 1.25 * len + 2;
347
- if (width > 80)
348
- width = 80;
349
- if (this.colWidths[c] < width)
350
- this.colWidths[c] = width;
351
- }
352
- }
353
- bigBuf.writeString('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
354
- bigBuf.writeString('<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">');
355
- const totalRows = rows.length + (headers ? 1 : 0);
356
- if (totalRows > 0 && columnCount > 0) {
357
- bigBuf.writeString(`<dimension ref="A1:${colLetters[columnCount - 1]}${totalRows}"/>`);
358
- }
359
- else {
360
- bigBuf.writeString('<dimension ref="A1"/>');
361
- }
362
- const isFirstSheet = this.sheetCount === 1;
363
- if (headers) {
364
- if (isFirstSheet) {
365
- bigBuf.writeString('<sheetViews><sheetView tabSelected="1" workbookViewId="0"><pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen" /><selection pane="bottomLeft" /></sheetView></sheetViews><sheetFormatPr defaultRowHeight="15"/>');
366
- }
367
- else {
368
- bigBuf.writeString('<sheetViews><sheetView workbookViewId="0"><pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen" /><selection pane="bottomLeft" /></sheetView></sheetViews><sheetFormatPr defaultRowHeight="15"/>');
369
- }
370
- }
371
- else {
372
- if (isFirstSheet) {
373
- bigBuf.writeString('<sheetViews><sheetView tabSelected="1" workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="15"/>');
374
- }
375
- else {
376
- bigBuf.writeString('<sheetViews><sheetView workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="15"/>');
377
- }
378
- }
379
- bigBuf.writeString('<cols>');
380
- for (let i = 0; i < columnCount; i++) {
381
- const width = this.colWidths[i] > 0 ? this.colWidths[i] : 10;
382
- bigBuf.writeString(`<col min="${i + 1}" max="${i + 1}" width="${width}" bestFit="1" customWidth="1" />`);
383
- }
384
- bigBuf.writeString('</cols><sheetData>');
385
- let rowNum = 0;
386
- if (headers) {
387
- rowNum++;
388
- bigBuf.writeString(`<row r="${rowNum}">`);
389
- for (let c = 0; c < headers.length; c++) {
390
- this._writeStringCell(bigBuf, headers[c], colLetters[c], rowNum, 3);
391
- }
392
- bigBuf.writeString('</row>');
393
- }
394
- for (let r = 0; r < rows.length; r++) {
395
- rowNum++;
396
- bigBuf.writeString(`<row r="${rowNum}">`);
397
- const row = rows[r];
398
- for (let c = 0; c < row.length; c++) {
399
- const raw = row[c];
400
- if (raw === null || raw === undefined)
401
- continue;
402
- const fmtString = (0, Formats_1.getFormat)(raw);
403
- const val = fmtString !== null ? (0, Formats_1.unwrapCell)(raw) : raw;
404
- const xfIdx = fmtString !== null ? this._registerFormat(fmtString) : -1;
405
- const styleAttr = xfIdx >= 0 ? ` s="${xfIdx}"` : '';
406
- const colRef = colLetters[c];
407
- if (typeof val === 'number') {
408
- if (Number.isFinite(val)) {
409
- bigBuf.writeString(`<c r="${colRef}${rowNum}"${styleAttr}><v>${val}</v></c>`);
410
- }
411
- else {
412
- this._writeStringCell(bigBuf, val.toString(), colRef, rowNum, xfIdx >= 0 ? xfIdx : undefined);
413
- }
414
- }
415
- else if (typeof val === 'bigint') {
416
- this._writeStringCell(bigBuf, val.toString(), colRef, rowNum, xfIdx >= 0 ? xfIdx : undefined);
417
- }
418
- else if (typeof val === 'boolean') {
419
- bigBuf.writeString(`<c r="${colRef}${rowNum}" t="b"${styleAttr}><v>${val ? 1 : 0}</v></c>`);
420
- }
421
- else if (val instanceof Date) {
422
- const oaDate = this._toOADate(val);
423
- if (Number.isFinite(oaDate)) {
424
- const finalStyle = xfIdx >= 0 ? xfIdx : 1;
425
- bigBuf.writeString(`<c r="${colRef}${rowNum}" s="${finalStyle}"><v>${oaDate}</v></c>`);
426
- }
427
- else {
428
- this._writeStringCell(bigBuf, val.toString(), colRef, rowNum, xfIdx >= 0 ? xfIdx : undefined);
429
- }
430
- }
431
- else {
432
- this._writeStringCell(bigBuf, val.toString(), colRef, rowNum, xfIdx >= 0 ? xfIdx : undefined);
433
- }
434
- }
435
- bigBuf.writeString('</row>');
436
- }
437
- bigBuf.writeString('</sheetData>');
438
- if (doAutofilter && headers && columnCount > 0) {
439
- this._autofilterIsOn = true;
440
- const filterRef = `A1:${colLetters[columnCount - 1]}${totalRows}`;
441
- bigBuf.writeString(`<autoFilter ref="${filterRef}"/>`);
442
- const sheet = this.sheetList[this.sheetCount - 1];
443
- const formulaSheetName = this._formatSheetNameForFormula(sheet.name);
444
- sheet.filterHeaderRange = `${formulaSheetName}!$A$1:$${colLetters[columnCount - 1]}$${totalRows}`;
445
- }
446
- bigBuf.writeString('</worksheet>');
447
- this.archive.append(stream_1.Readable.from(bigBuf.getChunks()), {
448
- name: this.sheetList[this.sheetCount - 1].pathInArchive
449
- });
450
- }
451
- _writeStringCell(bigBuf, val, colRef, rowNum, styleOverride) {
452
- let index = this.sstMap.get(val);
453
- if (index === undefined) {
454
- index = this.sstArray.length;
455
- this.sstArray.push(val);
456
- this.sstMap.set(val, index);
457
- }
458
- this.sstCntAll++;
459
- const styleAttr = styleOverride !== undefined ? ` s="${styleOverride}"` : '';
460
- bigBuf.writeString(`<c r="${colRef}${rowNum}" t="s"${styleAttr}><v>${index}</v></c>`);
461
- }
462
- _registerFormat(fmtString) {
463
- if (this._formatXfMap.has(fmtString)) {
464
- return this._formatXfMap.get(fmtString);
465
- }
466
- const numfmtId = this._nextNumfmtId++;
467
- this._formatRegistry.set(fmtString, numfmtId);
468
- const xfIndex = this._nextXfIndex++;
469
- this._formatXfMap.set(fmtString, xfIndex);
470
- return xfIndex;
471
- }
472
- _toOADate(date) {
473
- // Use UTC time to avoid timezone conversion issues
474
- return (date.getTime() - this._oaEpoch) / 86400000;
475
- }
476
- _getDateWidth(_date) {
477
- return 19; // "YYYY-MM-DD HH:MM:SS" ≈ 19 chars
478
- }
479
- finalize() {
480
- return new Promise((resolve, reject) => {
481
- try {
482
- this._writeSharedStrings();
483
- this._writeStyles();
484
- this._writeWorkbook();
485
- this._writeContentTypes();
486
- this._writeRels();
487
- this.output.on('close', () => {
488
- resolve();
489
- });
490
- this.archive.on('error', (err) => {
491
- reject(err);
492
- });
493
- this.archive.finalize();
494
- }
495
- catch (err) {
496
- reject(err);
497
- }
498
- });
499
- }
500
- _writeSharedStrings() {
501
- const bigBuf = new BigBuffer_1.BigBuffer();
502
- bigBuf.writeString('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
503
- bigBuf.writeString(`<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="${this.sstCntAll}" uniqueCount="${this.sstArray.length}">`);
504
- for (let i = 0; i < this.sstArray.length; i++) {
505
- const txt = this.sstArray[i];
506
- const cleanTxt = this._escape(txt);
507
- if (cleanTxt.length > 0 && (cleanTxt[0] === ' ' || cleanTxt[cleanTxt.length - 1] === ' ' || /[\t\n\r]/.test(cleanTxt))) {
508
- bigBuf.writeString(`<si><t xml:space="preserve">${cleanTxt}</t></si>`);
509
- }
510
- else {
511
- bigBuf.writeString(`<si><t>${cleanTxt}</t></si>`);
512
- }
513
- }
514
- bigBuf.writeString('</sst>');
515
- this.archive.append(stream_1.Readable.from(bigBuf.getChunks()), { name: 'xl/sharedStrings.xml' });
516
- }
517
- _writeStyles() {
518
- let numFmts = '';
519
- let numFmtCount = 0;
520
- const xfEntries = [];
521
- xfEntries.push('<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>');
522
- xfEntries.push('<xf numFmtId="14" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>');
523
- xfEntries.push('<xf numFmtId="22" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>');
524
- xfEntries.push('<xf numFmtId="0" fontId="1" fillId="0" borderId="0" xfId="0" applyFont="1"/>');
525
- for (const [fmtString, numfmtId] of this._formatRegistry) {
526
- const escapedFmt = fmtString
527
- .replace(/&/g, '&amp;')
528
- .replace(/</g, '&lt;')
529
- .replace(/>/g, '&gt;')
530
- .replace(/"/g, '&quot;')
531
- .replace(/'/g, '&apos;');
532
- numFmts += `<numFmt numFmtId="${numfmtId}" formatCode="${escapedFmt}"/>`;
533
- numFmtCount++;
534
- }
535
- const sortedFormats = [...this._formatXfMap.entries()].sort((a, b) => a[1] - b[1]);
536
- for (const [fmtString] of sortedFormats) {
537
- const numfmtId = this._formatRegistry.get(fmtString);
538
- xfEntries.push(`<xf numFmtId="${numfmtId}" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/>`);
539
- }
540
- const totalXf = xfEntries.length;
541
- const numFmtsSection = numFmtCount > 0 ? `<numFmts count="${numFmtCount}">${numFmts}</numFmts>` : '';
542
- const styles = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
543
- <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
544
- ${numFmtsSection}
545
- <fonts count="2">
546
- <font><sz val="11"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font>
547
- <font><b/><sz val="11"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font>
548
- </fonts>
549
- <fills count="2">
550
- <fill><patternFill patternType="none"/></fill>
551
- <fill><patternFill patternType="gray125"/></fill>
552
- </fills>
553
- <borders count="1">
554
- <border><left/><right/><top/><bottom/><diagonal/></border>
555
- </borders>
556
- <cellStyleXfs count="1">
557
- <xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>
558
- </cellStyleXfs>
559
- <cellXfs count="${totalXf}">
560
- ${xfEntries.join('\n')}
561
- </cellXfs>
562
- <cellStyles count="1">
563
- <cellStyle name="Normal" xfId="0" builtinId="0"/>
564
- </cellStyles>
565
- <dxfs count="0"/>
566
- <tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/>
567
- </styleSheet>`;
568
- this.archive.append(styles, { name: 'xl/styles.xml' });
569
- }
570
- _writeWorkbook() {
571
- let xml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
572
- <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
573
- <fileVersion appName="xl" lastEdited="4" lowestEdited="4" rupBuild="4505"/>
574
- <workbookPr defaultThemeVersion="124226"/>
575
- <bookViews><workbookView xWindow="240" yWindow="15" windowWidth="16095" windowHeight="9660"/></bookViews>
576
- <sheets>`;
577
- for (const sheet of this.sheetList) {
578
- const state = sheet.hidden ? ' state="hidden"' : '';
579
- const escapedName = this._escapeSheetNameForXml(sheet.name);
580
- xml += `<sheet name="${escapedName}" sheetId="${sheet.sheetId}"${state} r:id="${sheet.rId}"/>`;
581
- }
582
- xml += `</sheets>`;
583
- if (this._autofilterIsOn) {
584
- xml += '<definedNames>';
585
- for (const sheet of this.sheetList) {
586
- if (sheet.filterHeaderRange) {
587
- const localSheetId = sheet.sheetId - 1;
588
- const escapedRange = this._escape(sheet.filterHeaderRange);
589
- xml += `<definedName name="_xlnm._FilterDatabase" localSheetId="${localSheetId}" hidden="1">${escapedRange}</definedName>`;
590
- }
591
- }
592
- xml += '</definedNames>';
593
- }
594
- xml += '<calcPr calcId="124519" fullCalcOnLoad="1"/>';
595
- xml += `</workbook>`;
596
- this.archive.append(xml, { name: 'xl/workbook.xml' });
597
- }
598
- _writeContentTypes() {
599
- let xml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
600
- <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
601
- <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
602
- <Default Extension="xml" ContentType="application/xml"/>
603
- <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
604
- <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
605
- <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>`;
606
- for (const sheet of this.sheetList) {
607
- xml += `<Override PartName="/${sheet.pathInArchive}" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>`;
608
- }
609
- xml += `</Types>`;
610
- this.archive.append(xml, { name: '[Content_Types].xml' });
611
- }
612
- _writeRels() {
613
- const globalRels = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
614
- <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
615
- <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
616
- </Relationships>`;
617
- this.archive.append(globalRels, { name: '_rels/.rels' });
618
- let wbRels = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
619
- <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">`;
620
- for (const sheet of this.sheetList) {
621
- wbRels += `<Relationship Id="${sheet.rId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/${sheet.nameInArchive}"/>`;
622
- }
623
- let nextId = this.sheetList.length + 1;
624
- wbRels += `<Relationship Id="rId${nextId++}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>`;
625
- wbRels += `<Relationship Id="rId${nextId++}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>`;
626
- wbRels += `</Relationships>`;
627
- this.archive.append(wbRels, { name: 'xl/_rels/workbook.xml.rels' });
628
- }
629
- }
630
- exports.XlsxWriter = XlsxWriter;
631
- exports.default = XlsxWriter;
632
- //# sourceMappingURL=XlsxWriter.js.map