@shbernal/ts-xlsx 3.0.0 → 3.2.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.
- package/README.md +34 -24
- package/dist/bytes.d.ts +10 -2
- package/dist/bytes.js +22 -0
- package/dist/core/address.d.ts +96 -2
- package/dist/core/address.js +87 -33
- package/dist/core/array-formula-ranges.d.ts +33 -0
- package/dist/core/array-formula-ranges.js +62 -0
- package/dist/core/autofilter.d.ts +4 -3
- package/dist/core/autofilter.js +31 -30
- package/dist/core/axis-handle.d.ts +2 -0
- package/dist/core/axis-handle.js +5 -2
- package/dist/core/cell.d.ts +4 -3
- package/dist/core/cell.js +4 -6
- package/dist/core/clone.d.ts +29 -0
- package/dist/core/clone.js +24 -0
- package/dist/core/color-resolution.js +4 -6
- package/dist/core/column.d.ts +1 -0
- package/dist/core/column.js +6 -2
- package/dist/core/comment-thread.d.ts +7 -3
- package/dist/core/comment-thread.js +2 -1
- package/dist/core/conditional-formatting-overlay.d.ts +11 -1
- package/dist/core/conditional-formatting-overlay.js +30 -3
- package/dist/core/conditional-formatting.d.ts +107 -11
- package/dist/core/conditional-formatting.js +76 -19
- package/dist/core/containers.d.ts +12 -0
- package/dist/core/containers.js +5 -0
- package/dist/core/data-validation-overlay.d.ts +7 -1
- package/dist/core/data-validation-overlay.js +19 -4
- package/dist/core/data-validation.d.ts +22 -0
- package/dist/core/data-validation.js +30 -4
- package/dist/core/date-format.d.ts +20 -0
- package/dist/core/date-format.js +170 -0
- package/dist/core/date.d.ts +43 -8
- package/dist/core/date.js +19 -3
- package/dist/core/formula-references.d.ts +26 -0
- package/dist/core/formula-references.js +173 -0
- package/dist/core/formula-scan.d.ts +2 -0
- package/dist/core/formula-scan.js +58 -0
- package/dist/core/formula.d.ts +76 -17
- package/dist/core/formula.js +87 -80
- package/dist/core/function-values.d.ts +4 -0
- package/dist/core/function-values.js +58 -0
- package/dist/core/future-functions.d.ts +3 -0
- package/dist/core/{modern-functions.js → future-functions.js} +119 -88
- package/dist/core/grid-edits.d.ts +30 -3
- package/dist/core/grid-edits.js +248 -81
- package/dist/core/grid-shift.d.ts +58 -9
- package/dist/core/grid-shift.js +26 -4
- package/dist/core/hyperlink.d.ts +39 -0
- package/dist/core/hyperlink.js +88 -0
- package/dist/core/image.d.ts +49 -14
- package/dist/core/image.js +16 -5
- package/dist/core/internal.d.ts +10 -2
- package/dist/core/limits.d.ts +25 -0
- package/dist/core/limits.js +4 -0
- package/dist/core/merge.d.ts +18 -4
- package/dist/core/merge.js +33 -20
- package/dist/core/page-setup.d.ts +26 -11
- package/dist/core/pivot-table.d.ts +49 -10
- package/dist/core/pivot-table.js +112 -60
- package/dist/core/protection.d.ts +66 -4
- package/dist/core/protection.js +6 -11
- package/dist/core/range.js +34 -30
- package/dist/core/row-input.js +2 -2
- package/dist/core/row.d.ts +1 -0
- package/dist/core/row.js +6 -2
- package/dist/core/structured-reference.d.ts +7 -0
- package/dist/core/structured-reference.js +7 -0
- package/dist/core/style.d.ts +85 -70
- package/dist/core/style.js +92 -28
- package/dist/core/table-style.d.ts +1 -1
- package/dist/core/table-style.js +4 -4
- package/dist/core/table.d.ts +64 -16
- package/dist/core/table.js +87 -40
- package/dist/core/theme.d.ts +2 -0
- package/dist/core/theme.js +9 -5
- package/dist/core/value.d.ts +60 -28
- package/dist/core/value.js +48 -43
- package/dist/core/workbook-media.d.ts +34 -0
- package/dist/core/workbook-media.js +44 -0
- package/dist/core/workbook-styles.d.ts +83 -1
- package/dist/core/workbook-styles.js +4 -0
- package/dist/core/workbook-theme.js +5 -3
- package/dist/core/workbook-vba.js +3 -2
- package/dist/core/workbook.d.ts +41 -3
- package/dist/core/workbook.js +46 -41
- package/dist/core/worksheet-comments.d.ts +2 -1
- package/dist/core/worksheet-comments.js +20 -13
- package/dist/core/worksheet-merges.d.ts +49 -0
- package/dist/core/worksheet-merges.js +65 -0
- package/dist/core/worksheet-model.d.ts +10 -2
- package/dist/core/worksheet-model.js +28 -9
- package/dist/core/worksheet-pictures.d.ts +3 -3
- package/dist/core/worksheet-pictures.js +7 -6
- package/dist/core/worksheet.d.ts +165 -27
- package/dist/core/worksheet.js +206 -89
- package/dist/customui/ribbon.js +2 -1
- package/dist/entries/core.d.ts +21 -14
- package/dist/entries/core.js +14 -7
- package/dist/entries/errors.d.ts +1 -0
- package/dist/entries/errors.js +1 -0
- package/dist/entries/xlsx.d.ts +1 -1
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +22 -0
- package/dist/hex.d.ts +8 -0
- package/dist/hex.js +3 -0
- package/dist/io/cell-metadata/metadata.d.ts +42 -0
- package/dist/io/cell-metadata/metadata.js +35 -0
- package/dist/io/cell-metadata/rich-values.d.ts +11 -0
- package/dist/io/cell-metadata/rich-values.js +80 -0
- package/dist/io/csv/delimiter.d.ts +21 -0
- package/dist/io/csv/delimiter.js +18 -0
- package/dist/io/csv/errors.d.ts +14 -0
- package/dist/io/csv/errors.js +5 -0
- package/dist/io/csv/read.d.ts +6 -1
- package/dist/io/csv/read.js +51 -22
- package/dist/io/csv/write.d.ts +19 -5
- package/dist/io/csv/write.js +24 -44
- package/dist/io/opc/inflate.js +14 -0
- package/dist/io/opc/namespaces.d.ts +16 -0
- package/dist/io/opc/namespaces.js +4 -0
- package/dist/io/opc/part-paths.d.ts +9 -0
- package/dist/io/opc/part-paths.js +5 -5
- package/dist/io/opc/read-opc.d.ts +58 -14
- package/dist/io/opc/read-opc.js +49 -21
- package/dist/io/opc/read-options.d.ts +5 -1
- package/dist/io/opc/sniff-format.d.ts +3 -3
- package/dist/io/opc/sniff-format.js +2 -2
- package/dist/io/opc/strict-relationships.d.ts +2 -0
- package/dist/io/opc/strict-relationships.js +12 -0
- package/dist/io/read-policy/column-budget.d.ts +26 -0
- package/dist/io/read-policy/column-budget.js +18 -0
- package/dist/io/read-policy/read-repair.d.ts +74 -0
- package/dist/io/read-policy/read-repair.js +119 -0
- package/dist/io/style/cell-style-resolution.d.ts +25 -0
- package/dist/io/style/cell-style-resolution.js +30 -0
- package/dist/io/style/xf-style.d.ts +23 -1
- package/dist/io/style/xf-style.js +8 -0
- package/dist/io/xlsb/formula.d.ts +2 -2
- package/dist/io/xlsb/formula.js +52 -35
- package/dist/io/xlsb/primitives.js +8 -14
- package/dist/io/xlsb/ptg-functions.d.ts +19 -10
- package/dist/io/xlsb/ptg-functions.js +495 -596
- package/dist/io/xlsb/read-metadata.d.ts +7 -0
- package/dist/io/xlsb/read-metadata.js +69 -0
- package/dist/io/xlsb/read-styles.js +45 -81
- package/dist/io/xlsb/read-worksheet.d.ts +26 -1
- package/dist/io/xlsb/read-worksheet.js +148 -106
- package/dist/io/xlsb/read.d.ts +6 -3
- package/dist/io/xlsb/read.js +70 -31
- package/dist/io/xlsb/record-stream.d.ts +30 -0
- package/dist/io/xlsb/record-stream.js +20 -0
- package/dist/io/xlsb/record-types.d.ts +14 -5
- package/dist/io/xlsb/record-types.js +14 -5
- package/dist/io/xlsb/sheet-protection.d.ts +20 -0
- package/dist/io/xlsb/sheet-protection.js +60 -0
- package/dist/io/xlsx/cell-accumulator.d.ts +24 -9
- package/dist/io/xlsx/cell-accumulator.js +74 -21
- package/dist/io/xlsx/cell-metadata.d.ts +39 -0
- package/dist/io/xlsx/cell-metadata.js +162 -0
- package/dist/io/xlsx/cell-value.d.ts +19 -5
- package/dist/io/xlsx/cell-value.js +45 -30
- package/dist/io/xlsx/color-xml.js +3 -2
- package/dist/io/xlsx/column-span.d.ts +11 -0
- package/dist/io/xlsx/column-span.js +9 -0
- package/dist/io/xlsx/comments.d.ts +9 -30
- package/dist/io/xlsx/comments.js +25 -83
- package/dist/io/xlsx/conditional-formatting.d.ts +43 -23
- package/dist/io/xlsx/conditional-formatting.js +437 -138
- package/dist/io/xlsx/data-validation.d.ts +12 -7
- package/dist/io/xlsx/data-validation.js +67 -53
- package/dist/io/xlsx/edit-vba.d.ts +7 -2
- package/dist/io/xlsx/edit-vba.js +52 -52
- package/dist/io/xlsx/font-xml.d.ts +7 -0
- package/dist/io/xlsx/font-xml.js +104 -0
- package/dist/io/xlsx/hyperlinks.d.ts +19 -21
- package/dist/io/xlsx/hyperlinks.js +12 -32
- package/dist/io/xlsx/images.d.ts +49 -16
- package/dist/io/xlsx/images.js +149 -50
- package/dist/io/xlsx/namespaces.d.ts +24 -0
- package/dist/io/xlsx/namespaces.js +11 -0
- package/dist/io/xlsx/package-plan.d.ts +60 -15
- package/dist/io/xlsx/package-plan.js +83 -18
- package/dist/io/xlsx/part-names.d.ts +6 -8
- package/dist/io/xlsx/part-names.js +3 -7
- package/dist/io/xlsx/pivot.d.ts +5 -5
- package/dist/io/xlsx/pivot.js +26 -24
- package/dist/io/xlsx/preserved-splices.d.ts +6 -0
- package/dist/io/xlsx/preserved-splices.js +74 -0
- package/dist/io/xlsx/read-comments.d.ts +29 -0
- package/dist/io/xlsx/read-comments.js +75 -0
- package/dist/io/xlsx/read-parts.d.ts +59 -0
- package/dist/io/xlsx/read-parts.js +259 -0
- package/dist/io/xlsx/read-pivot.js +11 -4
- package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +8 -5
- package/dist/io/xlsx/{rich-runs.js → read-rich-runs.js} +24 -4
- package/dist/io/xlsx/read-rows.d.ts +35 -11
- package/dist/io/xlsx/read-rows.js +73 -49
- package/dist/io/xlsx/read-shared-strings.js +3 -2
- package/dist/io/xlsx/read-styles.d.ts +0 -30
- package/dist/io/xlsx/read-styles.js +45 -105
- package/dist/io/xlsx/read-workbook-xml.d.ts +42 -0
- package/dist/io/xlsx/read-workbook-xml.js +175 -0
- package/dist/io/xlsx/read-worksheet.d.ts +9 -3
- package/dist/io/xlsx/read-worksheet.js +70 -177
- package/dist/io/xlsx/read.d.ts +3 -14
- package/dist/io/xlsx/read.js +74 -411
- package/dist/io/xlsx/relationships.d.ts +3 -0
- package/dist/io/xlsx/relationships.js +4 -0
- package/dist/io/xlsx/rich-text.js +1 -1
- package/dist/io/xlsx/row-position.d.ts +20 -0
- package/dist/io/xlsx/row-position.js +11 -0
- package/dist/io/xlsx/row-xml.d.ts +139 -0
- package/dist/io/xlsx/row-xml.js +222 -0
- package/dist/io/xlsx/shared-formulas.js +2 -2
- package/dist/io/xlsx/sheet-properties.d.ts +10 -1
- package/dist/io/xlsx/sheet-properties.js +182 -20
- package/dist/io/xlsx/strict-parts.d.ts +7 -0
- package/dist/io/xlsx/strict-parts.js +171 -0
- package/dist/io/xlsx/style-elements.d.ts +41 -0
- package/dist/io/xlsx/style-elements.js +136 -0
- package/dist/io/xlsx/styles.d.ts +17 -3
- package/dist/io/xlsx/styles.js +13 -209
- package/dist/io/xlsx/tables.d.ts +10 -2
- package/dist/io/xlsx/tables.js +55 -52
- package/dist/io/xlsx/theme-xml.d.ts +32 -4
- package/dist/io/xlsx/theme-xml.js +106 -71
- package/dist/io/xlsx/threaded-comments.d.ts +14 -11
- package/dist/io/xlsx/threaded-comments.js +16 -8
- package/dist/io/xlsx/workbook-xml.d.ts +45 -6
- package/dist/io/xlsx/workbook-xml.js +62 -54
- package/dist/io/xlsx/worksheet-xml.d.ts +26 -70
- package/dist/io/xlsx/worksheet-xml.js +69 -282
- package/dist/io/xlsx/write-stream.d.ts +90 -19
- package/dist/io/xlsx/write-stream.js +80 -25
- package/dist/io/xlsx/write.d.ts +12 -6
- package/dist/io/xlsx/write.js +226 -123
- package/dist/rel-type.d.ts +25 -0
- package/dist/rel-type.js +9 -0
- package/dist/token-set.d.ts +13 -0
- package/dist/token-set.js +4 -1
- package/dist/vba/bytes.d.ts +16 -5
- package/dist/vba/bytes.js +27 -6
- package/dist/vba/cfb-format.d.ts +55 -0
- package/dist/vba/cfb-format.js +35 -0
- package/dist/vba/cfb-writer.d.ts +8 -0
- package/dist/vba/cfb-writer.js +40 -40
- package/dist/vba/cfb.d.ts +21 -4
- package/dist/vba/cfb.js +124 -90
- package/dist/vba/codepage.js +2 -1
- package/dist/vba/dir-records.d.ts +6 -0
- package/dist/vba/dir-records.js +10 -2
- package/dist/vba/errors.d.ts +11 -4
- package/dist/vba/index.d.ts +0 -2
- package/dist/vba/index.js +0 -2
- package/dist/vba/ms-ovba.d.ts +6 -2
- package/dist/vba/ms-ovba.js +66 -22
- package/dist/vba/project-editor.js +129 -119
- package/dist/vba/project.d.ts +15 -1
- package/dist/vba/project.js +38 -13
- package/dist/vba/vba-encoding.d.ts +4 -10
- package/dist/vba/vba-encoding.js +3 -17
- package/dist/xml/xml-attrs.d.ts +37 -0
- package/dist/xml/xml-attrs.js +30 -0
- package/dist/xml/xml-chars.d.ts +40 -0
- package/dist/xml/xml-chars.js +12 -0
- package/dist/xml/xml-namespaces.d.ts +31 -0
- package/dist/xml/xml-namespaces.js +50 -0
- package/dist/xml/xml-read.d.ts +101 -11
- package/dist/xml/xml-read.js +150 -18
- package/dist/xml/xml-scan.d.ts +25 -34
- package/dist/xml/xml-scan.js +69 -46
- package/dist/xml/xml.d.ts +59 -26
- package/dist/xml/xml.js +45 -23
- package/package.json +15 -9
- package/skills/ts-xlsx-upstream/SKILL.md +21 -13
- package/dist/core/modern-functions.d.ts +0 -1
|
@@ -3,12 +3,17 @@ import { PassThrough } from 'node:stream';
|
|
|
3
3
|
import { Zip, ZipDeflate } from 'fflate';
|
|
4
4
|
import { concat } from '../../bytes.js';
|
|
5
5
|
import { encodeAddress, tryDecodeCellRef } from '../../core/address.js';
|
|
6
|
+
import { formulaPlacement } from '../../core/array-formula-ranges.js';
|
|
7
|
+
import { formulaNamesInScope } from '../../core/formula.js';
|
|
6
8
|
import { INTERNAL } from '../../core/internal.js';
|
|
7
9
|
import { isSharedFormulaValue } from '../../core/value.js';
|
|
8
|
-
import { Workbook } from '../../core/workbook.js';
|
|
9
|
-
import { AuthoringError } from '../../errors.js';
|
|
10
|
+
import { Workbook, } from '../../core/workbook.js';
|
|
11
|
+
import { AuthoringError, quoted } from '../../errors.js';
|
|
10
12
|
import { FIXED_ENTRY_MTIME } from '../opc/zip-mtime.js';
|
|
11
|
-
import {
|
|
13
|
+
import { WorkbookMetadataTable } from './cell-metadata.js';
|
|
14
|
+
import { collectNotes } from './comments.js';
|
|
15
|
+
import { buildColumnDefaults, Extent, renderRow, } from './row-xml.js';
|
|
16
|
+
import { buildPackageParts, createStyleRegistry } from './write.js';
|
|
12
17
|
export class StreamedRow {
|
|
13
18
|
#cells;
|
|
14
19
|
#sheet;
|
|
@@ -19,6 +24,11 @@ export class StreamedRow {
|
|
|
19
24
|
this.#sheet = sheet;
|
|
20
25
|
this.#number = number;
|
|
21
26
|
}
|
|
27
|
+
static [INTERNAL] = {
|
|
28
|
+
create(cells, sheet, number) {
|
|
29
|
+
return new StreamedRow(cells, sheet, number);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
22
32
|
get cells() {
|
|
23
33
|
return this.#cells;
|
|
24
34
|
}
|
|
@@ -26,7 +36,7 @@ export class StreamedRow {
|
|
|
26
36
|
if (this.#committed)
|
|
27
37
|
return;
|
|
28
38
|
this.#committed = true;
|
|
29
|
-
this.#sheet?.flushRow(this.#number
|
|
39
|
+
this.#sheet?.[INTERNAL].flushRow(this.#number);
|
|
30
40
|
}
|
|
31
41
|
}
|
|
32
42
|
export class WorksheetStreamWriter {
|
|
@@ -39,12 +49,25 @@ export class WorksheetStreamWriter {
|
|
|
39
49
|
#flushedRows = [];
|
|
40
50
|
#flushedNumbers = new Set();
|
|
41
51
|
#extent = new Extent();
|
|
42
|
-
#
|
|
43
|
-
|
|
52
|
+
#rowOutline = new Map();
|
|
53
|
+
#notes = [];
|
|
54
|
+
#formulas = [];
|
|
55
|
+
#dateEpoch;
|
|
56
|
+
#definedNames;
|
|
57
|
+
#cellMetadata;
|
|
58
|
+
constructor(sheet, eager, styles, cellMetadata, dateEpoch, definedNames) {
|
|
44
59
|
this.#sheet = sheet;
|
|
45
60
|
this.#eager = eager;
|
|
46
61
|
this.#styles = styles;
|
|
62
|
+
this.#cellMetadata = cellMetadata;
|
|
63
|
+
this.#dateEpoch = dateEpoch;
|
|
64
|
+
this.#definedNames = definedNames;
|
|
47
65
|
}
|
|
66
|
+
static [INTERNAL] = {
|
|
67
|
+
create(sheet, eager, styles, cellMetadata, dateEpoch, definedNames) {
|
|
68
|
+
return new WorksheetStreamWriter(sheet, eager, styles, cellMetadata, dateEpoch, definedNames);
|
|
69
|
+
},
|
|
70
|
+
};
|
|
48
71
|
get name() {
|
|
49
72
|
return this.#sheet.name;
|
|
50
73
|
}
|
|
@@ -54,14 +77,14 @@ export class WorksheetStreamWriter {
|
|
|
54
77
|
addRow(values) {
|
|
55
78
|
this.#assertOpen();
|
|
56
79
|
if (!this.#eager)
|
|
57
|
-
return
|
|
80
|
+
return StreamedRow[INTERNAL].create(this.#sheet.addRow(values), null, 0);
|
|
58
81
|
const number = this.#nextRowNumber();
|
|
59
|
-
return
|
|
82
|
+
return StreamedRow[INTERNAL].create(this.#placeRow(number, values), this, number);
|
|
60
83
|
}
|
|
61
84
|
addRows(rows) {
|
|
62
85
|
this.#assertOpen();
|
|
63
86
|
if (!this.#eager)
|
|
64
|
-
return this.#sheet.addRows(rows).map((cells) =>
|
|
87
|
+
return this.#sheet.addRows(rows).map((cells) => StreamedRow[INTERNAL].create(cells, null, 0));
|
|
65
88
|
return rows.map((values) => this.addRow(values));
|
|
66
89
|
}
|
|
67
90
|
#nextRowNumber() {
|
|
@@ -77,45 +100,61 @@ export class WorksheetStreamWriter {
|
|
|
77
100
|
});
|
|
78
101
|
return cells;
|
|
79
102
|
}
|
|
80
|
-
flushRow(number
|
|
103
|
+
#flushRow(number) {
|
|
104
|
+
const row = this.#sheet.getRow(number);
|
|
105
|
+
const { cells } = row;
|
|
81
106
|
for (const cell of cells) {
|
|
82
107
|
if (isSharedFormulaValue(cell.value)) {
|
|
83
|
-
throw new AuthoringError(`row ${number} of streamed sheet
|
|
108
|
+
throw new AuthoringError(`row ${number} of streamed sheet ${quoted(this.#sheet.name)} carries a shared-formula cell; a ` +
|
|
84
109
|
'committed row is finalised before the sheet is planned, so author shared formulas through ' +
|
|
85
110
|
'getCell (leaving the row uncommitted) instead');
|
|
86
111
|
}
|
|
87
112
|
}
|
|
88
113
|
this.#columnDefaults ??= buildColumnDefaults(this.#sheet);
|
|
89
|
-
const properties =
|
|
90
|
-
this.#
|
|
91
|
-
|
|
114
|
+
const { properties } = row;
|
|
115
|
+
this.#rowOutline.set(number, {
|
|
116
|
+
outlineLevel: properties?.outlineLevel ?? 0,
|
|
117
|
+
hidden: properties?.hidden ?? false,
|
|
118
|
+
});
|
|
119
|
+
this.#notes.push(...collectNotes(cells));
|
|
120
|
+
for (const cell of cells) {
|
|
121
|
+
const placement = formulaPlacement(cell.address, cell.col, cell.row, cell.value);
|
|
122
|
+
if (placement !== undefined)
|
|
123
|
+
this.#formulas.push(placement);
|
|
124
|
+
}
|
|
125
|
+
const { xml, attrs, minCol, maxCol } = renderRow({ number, cells, properties }, {
|
|
92
126
|
columnDefaults: this.#columnDefaults,
|
|
93
127
|
styles: this.#styles,
|
|
94
128
|
sharedStrings: null,
|
|
95
129
|
sharedRoles: new Map(),
|
|
96
130
|
collapsedSummaries: new Set(),
|
|
131
|
+
dateEpoch: this.#dateEpoch,
|
|
132
|
+
formulaNames: formulaNamesInScope(this.#definedNames, this.#sheet.name),
|
|
133
|
+
cellMetadata: this.#cellMetadata,
|
|
97
134
|
});
|
|
98
135
|
if (xml !== '') {
|
|
99
|
-
this.#flushedRows.push({ number, xml });
|
|
136
|
+
this.#flushedRows.push({ number, xml, attrs });
|
|
100
137
|
this.#extent.add(number, minCol, maxCol);
|
|
101
138
|
}
|
|
102
139
|
this.#flushedNumbers.add(number);
|
|
103
140
|
this.#sheet[INTERNAL].evictRow(number);
|
|
104
141
|
}
|
|
105
|
-
flushedSheet() {
|
|
142
|
+
#flushedSheet() {
|
|
106
143
|
if (this.#flushedRows.length === 0)
|
|
107
144
|
return undefined;
|
|
108
145
|
return {
|
|
109
146
|
rows: this.#flushedRows,
|
|
110
147
|
extent: this.#extent,
|
|
111
|
-
|
|
148
|
+
rowOutline: this.#rowOutline,
|
|
149
|
+
notes: this.#notes,
|
|
150
|
+
formulas: this.#formulas,
|
|
112
151
|
};
|
|
113
152
|
}
|
|
114
153
|
getCell(reference) {
|
|
115
154
|
this.#assertOpen();
|
|
116
155
|
const target = tryDecodeCellRef(reference);
|
|
117
156
|
if (target !== undefined && this.#flushedNumbers.has(target.row)) {
|
|
118
|
-
throw new AuthoringError(`cell ${reference} of streamed sheet
|
|
157
|
+
throw new AuthoringError(`cell ${reference} of streamed sheet ${quoted(this.#sheet.name)} is in row ${target.row}, which is ` +
|
|
119
158
|
'already committed: its bytes are written and its cells released, so this value could only ' +
|
|
120
159
|
'be emitted as a second row with that number. Style a row before committing it.');
|
|
121
160
|
}
|
|
@@ -125,6 +164,10 @@ export class WorksheetStreamWriter {
|
|
|
125
164
|
this.#assertOpen();
|
|
126
165
|
this.#sheet.addDataValidation(sqref, rule, options);
|
|
127
166
|
}
|
|
167
|
+
addHyperlink(link) {
|
|
168
|
+
this.#assertOpen();
|
|
169
|
+
this.#sheet.addHyperlink(link);
|
|
170
|
+
}
|
|
128
171
|
addConditionalFormatting(formatting) {
|
|
129
172
|
this.#assertOpen();
|
|
130
173
|
this.#sheet.addConditionalFormatting(formatting);
|
|
@@ -153,9 +196,15 @@ export class WorksheetStreamWriter {
|
|
|
153
196
|
get model() {
|
|
154
197
|
return this.#sheet;
|
|
155
198
|
}
|
|
199
|
+
[INTERNAL] = {
|
|
200
|
+
flushRow: (number) => {
|
|
201
|
+
this.#flushRow(number);
|
|
202
|
+
},
|
|
203
|
+
flushedSheet: () => this.#flushedSheet(),
|
|
204
|
+
};
|
|
156
205
|
#assertOpen() {
|
|
157
206
|
if (this.#committed) {
|
|
158
|
-
throw new AuthoringError(`worksheet
|
|
207
|
+
throw new AuthoringError(`worksheet ${quoted(this.#sheet.name)} is already committed: its rows are finalised and no more can be added`);
|
|
159
208
|
}
|
|
160
209
|
}
|
|
161
210
|
}
|
|
@@ -165,6 +214,7 @@ export class WorkbookStreamWriter {
|
|
|
165
214
|
#writeOptions;
|
|
166
215
|
#sink;
|
|
167
216
|
#styles;
|
|
217
|
+
#cellMetadata = new WorkbookMetadataTable();
|
|
168
218
|
#eager;
|
|
169
219
|
#stream;
|
|
170
220
|
#committed = false;
|
|
@@ -172,6 +222,8 @@ export class WorkbookStreamWriter {
|
|
|
172
222
|
constructor(options = {}) {
|
|
173
223
|
this.#writeOptions = { useSharedStrings: options.useSharedStrings ?? false };
|
|
174
224
|
this.#eager = !this.#writeOptions.useSharedStrings;
|
|
225
|
+
if (options.dateEpoch !== undefined)
|
|
226
|
+
this.#workbook.dateEpoch = options.dateEpoch;
|
|
175
227
|
this.#styles = createStyleRegistry(this.#workbook);
|
|
176
228
|
if (options.stream && options.filename) {
|
|
177
229
|
throw new AuthoringError('provide either a stream or a filename to the streaming writer, not both');
|
|
@@ -192,7 +244,7 @@ export class WorkbookStreamWriter {
|
|
|
192
244
|
}
|
|
193
245
|
addWorksheet(name, options = {}) {
|
|
194
246
|
this.#assertOpen('no more worksheets can be added');
|
|
195
|
-
const sheet =
|
|
247
|
+
const sheet = WorksheetStreamWriter[INTERNAL].create(this.#workbook.addWorksheet(name, options), this.#eager, this.#styles, this.#cellMetadata, this.#workbook.dateEpoch, this.#workbook.definedNames);
|
|
196
248
|
this.#sheets.push(sheet);
|
|
197
249
|
return sheet;
|
|
198
250
|
}
|
|
@@ -205,23 +257,25 @@ export class WorkbookStreamWriter {
|
|
|
205
257
|
this.#workbook.fullCalcOnLoad = true;
|
|
206
258
|
const flushed = new Map();
|
|
207
259
|
for (const sheet of this.#sheets) {
|
|
208
|
-
const sheetFlushed = sheet.flushedSheet();
|
|
260
|
+
const sheetFlushed = sheet[INTERNAL].flushedSheet();
|
|
209
261
|
if (sheetFlushed)
|
|
210
262
|
flushed.set(sheet.model, sheetFlushed);
|
|
211
263
|
}
|
|
212
264
|
const owned = this.#stream;
|
|
213
265
|
const sink = this.#sink;
|
|
266
|
+
const collect = sink === undefined || owned !== undefined;
|
|
214
267
|
const sinkSettled = sink ? settleOnFinish(sink) : undefined;
|
|
215
268
|
try {
|
|
216
269
|
const parts = buildPackageParts(this.#workbook, {
|
|
217
270
|
...this.#writeOptions,
|
|
218
271
|
styles: this.#styles,
|
|
272
|
+
cellMetadata: this.#cellMetadata,
|
|
219
273
|
flushed,
|
|
220
274
|
});
|
|
221
275
|
const bytes = await streamZipPackage(parts, (chunk) => {
|
|
222
276
|
owned?.write(chunk);
|
|
223
277
|
sink?.write(chunk);
|
|
224
|
-
});
|
|
278
|
+
}, collect);
|
|
225
279
|
owned?.end();
|
|
226
280
|
sink?.end();
|
|
227
281
|
await sinkSettled;
|
|
@@ -247,7 +301,7 @@ function settleOnFinish(sink) {
|
|
|
247
301
|
sink.once('error', reject);
|
|
248
302
|
});
|
|
249
303
|
}
|
|
250
|
-
function streamZipPackage(parts, onChunk) {
|
|
304
|
+
function streamZipPackage(parts, onChunk, collect) {
|
|
251
305
|
return new Promise((resolve, reject) => {
|
|
252
306
|
const collected = [];
|
|
253
307
|
const zip = new Zip((err, chunk, final) => {
|
|
@@ -255,10 +309,11 @@ function streamZipPackage(parts, onChunk) {
|
|
|
255
309
|
reject(err);
|
|
256
310
|
return;
|
|
257
311
|
}
|
|
258
|
-
|
|
312
|
+
if (collect)
|
|
313
|
+
collected.push(chunk);
|
|
259
314
|
onChunk(chunk);
|
|
260
315
|
if (final)
|
|
261
|
-
resolve(concat(collected));
|
|
316
|
+
resolve(collect ? concat(collected) : undefined);
|
|
262
317
|
});
|
|
263
318
|
for (const [name, data] of Object.entries(parts)) {
|
|
264
319
|
const entry = new ZipDeflate(name, { level: 6 });
|
package/dist/io/xlsx/write.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { Workbook } from '../../core/workbook.ts';
|
|
2
2
|
import type { Worksheet } from '../../core/worksheet.ts';
|
|
3
|
+
import { WorkbookMetadataTable } from './cell-metadata.ts';
|
|
4
|
+
import type { FlushedSheet } from './row-xml.ts';
|
|
3
5
|
import { StyleRegistry } from './styles.ts';
|
|
4
|
-
import { type FlushedSheet } from './worksheet-xml.ts';
|
|
5
|
-
export { buildColumnDefaults, Extent, type FlushedSheet, type RowRenderContext, renderRow, } from './worksheet-xml.ts';
|
|
6
6
|
/** Options controlling how {@link writeXlsx} serialises a workbook. */
|
|
7
7
|
export interface WriteOptions {
|
|
8
8
|
/**
|
|
9
|
-
* Pool
|
|
10
|
-
* reference by index, rather than storing each
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* Pool string and rich-text cell values into a shared-strings table (`xl/sharedStrings.xml`) that
|
|
10
|
+
* cells reference by index, rather than storing each inline in its cell. Deduplicates repeated text
|
|
11
|
+
* and matches Excel's own storage; a rich value is pooled as a `<si>` of its runs, so its formatting
|
|
12
|
+
* survives. Off by default, which keeps strings inline and omits the part.
|
|
13
13
|
*/
|
|
14
14
|
readonly useSharedStrings?: boolean;
|
|
15
15
|
}
|
|
@@ -28,6 +28,12 @@ export interface InternalWriteOptions extends WriteOptions {
|
|
|
28
28
|
* so its output is unchanged.
|
|
29
29
|
*/
|
|
30
30
|
readonly styles?: StyleRegistry;
|
|
31
|
+
/**
|
|
32
|
+
* The workbook metadata to record into, in place of a fresh table, for the reason {@link styles} is
|
|
33
|
+
* shared: a row the streaming writer rendered eagerly may already point a dynamic-array formula or a
|
|
34
|
+
* rich-value error at the parts this table decides whether to emit.
|
|
35
|
+
*/
|
|
36
|
+
readonly cellMetadata?: WorkbookMetadataTable;
|
|
31
37
|
/**
|
|
32
38
|
* Per-sheet rows already serialised and evicted from the model by the streaming writer, keyed by
|
|
33
39
|
* the model worksheet. Their XML is emitted ahead of the sheet's remaining live rows and their
|