@shbernal/ts-xlsx 2.1.0 → 3.1.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 +4 -1
- package/dist/bytes.d.ts +7 -0
- package/dist/bytes.js +22 -0
- package/dist/core/address.d.ts +60 -2
- package/dist/core/address.js +40 -24
- package/dist/core/autofilter.d.ts +5 -4
- package/dist/core/autofilter.js +34 -35
- package/dist/core/axis-handle.d.ts +10 -0
- package/dist/core/axis-handle.js +17 -0
- package/dist/core/cell.d.ts +25 -0
- package/dist/core/cell.js +9 -3
- package/dist/core/clone.d.ts +29 -0
- package/dist/core/clone.js +24 -0
- package/dist/core/color-resolution.js +2 -4
- package/dist/core/column.d.ts +5 -1
- package/dist/core/column.js +34 -35
- package/dist/core/comment-thread.js +2 -1
- package/dist/core/conditional-formatting-overlay.d.ts +2 -1
- package/dist/core/conditional-formatting-overlay.js +2 -2
- package/dist/core/conditional-formatting.d.ts +14 -6
- package/dist/core/conditional-formatting.js +45 -43
- package/dist/core/containers.d.ts +12 -0
- package/dist/core/containers.js +5 -0
- package/dist/core/data-validation-overlay.d.ts +2 -1
- package/dist/core/data-validation-overlay.js +4 -4
- package/dist/core/data-validation.d.ts +9 -3
- package/dist/core/data-validation.js +21 -18
- package/dist/core/date-format.d.ts +20 -0
- package/dist/core/date-format.js +160 -0
- package/dist/core/date.d.ts +43 -8
- package/dist/core/date.js +18 -2
- package/dist/core/formula.d.ts +26 -0
- package/dist/core/formula.js +20 -4
- package/dist/core/grid-edits.d.ts +2 -3
- package/dist/core/grid-edits.js +69 -70
- package/dist/core/grid-shift.d.ts +58 -9
- package/dist/core/grid-shift.js +26 -4
- package/dist/core/image.d.ts +14 -10
- package/dist/core/image.js +9 -9
- package/dist/core/internal.d.ts +8 -2
- package/dist/core/limits.d.ts +23 -0
- package/dist/core/limits.js +4 -0
- package/dist/core/merge-index.d.ts +31 -0
- package/dist/core/merge-index.js +60 -0
- package/dist/core/merge.d.ts +5 -14
- package/dist/core/merge.js +18 -27
- package/dist/core/page-setup.d.ts +72 -2
- package/dist/core/page-setup.js +34 -8
- package/dist/core/pivot-table.d.ts +1 -1
- package/dist/core/pivot-table.js +67 -53
- package/dist/core/protection.js +2 -11
- package/dist/core/range.js +34 -30
- package/dist/core/row-input.js +2 -2
- package/dist/core/row.d.ts +5 -1
- package/dist/core/row.js +22 -23
- package/dist/core/style.d.ts +134 -75
- package/dist/core/style.js +112 -53
- package/dist/core/table-style.d.ts +1 -1
- package/dist/core/table-style.js +4 -4
- package/dist/core/table.d.ts +28 -10
- package/dist/core/table.js +54 -39
- package/dist/core/theme.js +6 -5
- package/dist/core/used-extent.d.ts +44 -0
- package/dist/core/used-extent.js +102 -0
- package/dist/core/value.d.ts +9 -0
- package/dist/core/value.js +36 -34
- package/dist/core/workbook-media.d.ts +34 -0
- package/dist/core/workbook-media.js +44 -0
- package/dist/core/workbook-styles.d.ts +67 -1
- package/dist/core/workbook-vba.js +3 -2
- package/dist/core/workbook.d.ts +23 -2
- package/dist/core/workbook.js +24 -40
- package/dist/core/worksheet-comments.d.ts +2 -1
- package/dist/core/worksheet-comments.js +20 -13
- package/dist/core/worksheet-merges.d.ts +44 -0
- package/dist/core/worksheet-merges.js +59 -0
- package/dist/core/worksheet-model.d.ts +9 -1
- package/dist/core/worksheet-model.js +24 -9
- package/dist/core/worksheet.d.ts +72 -12
- package/dist/core/worksheet.js +68 -70
- package/dist/customui/ribbon.js +6 -7
- package/dist/entries/core.d.ts +18 -13
- package/dist/entries/core.js +12 -6
- 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/csv/delimiter.d.ts +9 -0
- package/dist/io/csv/delimiter.js +6 -0
- package/dist/io/csv/read.js +11 -4
- package/dist/io/csv/write.d.ts +9 -2
- package/dist/io/csv/write.js +9 -38
- package/dist/io/opc/inflate.js +15 -1
- 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 +10 -0
- package/dist/io/opc/part-paths.js +16 -1
- package/dist/io/opc/read-opc.d.ts +69 -10
- package/dist/io/opc/read-opc.js +49 -55
- package/dist/io/opc/read-options.d.ts +5 -1
- package/dist/io/opc/rels.d.ts +1 -6
- package/dist/io/opc/rels.js +1 -4
- package/dist/io/opc/sniff-format.d.ts +3 -3
- package/dist/io/opc/sniff-format.js +2 -2
- package/dist/io/style/xf-style.d.ts +48 -2
- package/dist/io/style/xf-style.js +14 -0
- package/dist/io/xlsb/formula.d.ts +2 -2
- package/dist/io/xlsb/formula.js +49 -34
- 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 +385 -596
- package/dist/io/xlsb/read-styles.js +50 -83
- package/dist/io/xlsb/read-worksheet.d.ts +20 -1
- package/dist/io/xlsb/read-worksheet.js +73 -89
- package/dist/io/xlsb/read.d.ts +6 -3
- package/dist/io/xlsb/read.js +47 -29
- 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 +1 -5
- package/dist/io/xlsb/record-types.js +1 -5
- package/dist/io/xlsx/cell-accumulator.d.ts +9 -2
- package/dist/io/xlsx/cell-accumulator.js +32 -9
- package/dist/io/xlsx/cell-style-resolution.d.ts +25 -0
- package/dist/io/xlsx/cell-style-resolution.js +29 -0
- package/dist/io/xlsx/cell-value.d.ts +5 -3
- package/dist/io/xlsx/cell-value.js +13 -15
- package/dist/io/xlsx/color-xml.js +3 -2
- package/dist/io/xlsx/column-budget.d.ts +26 -0
- package/dist/io/xlsx/column-budget.js +22 -0
- package/dist/io/xlsx/comments.d.ts +6 -2
- package/dist/io/xlsx/comments.js +36 -31
- package/dist/io/xlsx/conditional-formatting.d.ts +9 -5
- package/dist/io/xlsx/conditional-formatting.js +51 -46
- package/dist/io/xlsx/data-validation.d.ts +9 -7
- package/dist/io/xlsx/data-validation.js +38 -35
- package/dist/io/xlsx/edit-vba.d.ts +7 -2
- package/dist/io/xlsx/edit-vba.js +15 -29
- 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 +41 -7
- package/dist/io/xlsx/hyperlinks.js +40 -28
- package/dist/io/xlsx/images.js +24 -25
- package/dist/io/xlsx/namespaces.d.ts +16 -0
- package/dist/io/xlsx/namespaces.js +7 -0
- package/dist/io/xlsx/package-plan.d.ts +23 -3
- package/dist/io/xlsx/package-plan.js +66 -25
- package/dist/io/xlsx/part-names.d.ts +41 -0
- package/dist/io/xlsx/part-names.js +46 -0
- package/dist/io/xlsx/pivot.js +8 -7
- package/dist/io/xlsx/read-parts.d.ts +59 -0
- package/dist/io/xlsx/read-parts.js +252 -0
- package/dist/io/xlsx/read-pivot.js +3 -1
- package/dist/io/xlsx/read-repair.d.ts +26 -0
- package/dist/io/xlsx/read-repair.js +39 -0
- package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +1 -1
- package/dist/io/xlsx/{rich-runs.js → read-rich-runs.js} +7 -3
- package/dist/io/xlsx/read-rows.d.ts +18 -5
- package/dist/io/xlsx/read-rows.js +50 -37
- package/dist/io/xlsx/read-shared-strings.js +5 -3
- package/dist/io/xlsx/read-styles.d.ts +1 -6
- package/dist/io/xlsx/read-styles.js +65 -109
- package/dist/io/xlsx/read-workbook-xml.d.ts +36 -0
- package/dist/io/xlsx/read-workbook-xml.js +170 -0
- package/dist/io/xlsx/read-worksheet.d.ts +11 -1
- package/dist/io/xlsx/read-worksheet.js +51 -193
- package/dist/io/xlsx/read.d.ts +5 -13
- package/dist/io/xlsx/read.js +111 -436
- package/dist/io/xlsx/rich-text.js +1 -1
- package/dist/io/xlsx/row-position.d.ts +18 -0
- package/dist/io/xlsx/row-position.js +11 -0
- package/dist/io/xlsx/row-xml.d.ts +128 -0
- package/dist/io/xlsx/row-xml.js +203 -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 +166 -37
- package/dist/io/xlsx/style-elements.d.ts +43 -0
- package/dist/io/xlsx/style-elements.js +156 -0
- package/dist/io/xlsx/styles.d.ts +12 -3
- package/dist/io/xlsx/styles.js +5 -204
- package/dist/io/xlsx/tables.js +11 -14
- package/dist/io/xlsx/theme-xml.d.ts +26 -4
- package/dist/io/xlsx/theme-xml.js +107 -69
- package/dist/io/xlsx/threaded-comments.d.ts +8 -10
- package/dist/io/xlsx/threaded-comments.js +3 -1
- package/dist/io/xlsx/workbook-xml.d.ts +54 -4
- package/dist/io/xlsx/workbook-xml.js +84 -57
- package/dist/io/xlsx/worksheet-xml.d.ts +23 -70
- package/dist/io/xlsx/worksheet-xml.js +59 -242
- package/dist/io/xlsx/write-stream.d.ts +71 -16
- package/dist/io/xlsx/write-stream.js +79 -41
- package/dist/io/xlsx/write.d.ts +6 -2
- package/dist/io/xlsx/write.js +217 -153
- package/dist/rel-type.d.ts +16 -0
- package/dist/rel-type.js +6 -0
- package/dist/token-set.d.ts +28 -0
- package/dist/token-set.js +7 -0
- package/dist/vba/bytes.d.ts +14 -5
- package/dist/vba/bytes.js +16 -6
- package/dist/vba/cfb-format.d.ts +32 -0
- package/dist/vba/cfb-format.js +13 -0
- package/dist/vba/cfb-writer.d.ts +9 -0
- package/dist/vba/cfb-writer.js +28 -25
- package/dist/vba/cfb.d.ts +13 -1
- package/dist/vba/cfb.js +73 -57
- package/dist/vba/codepage.js +2 -1
- package/dist/vba/errors.d.ts +7 -0
- package/dist/vba/ms-ovba.js +79 -23
- package/dist/vba/project-editor.js +35 -40
- package/dist/vba/project.d.ts +11 -1
- package/dist/vba/project.js +40 -21
- package/dist/vba/vba-encoding.js +5 -6
- 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 +128 -81
- package/dist/xml/xml-read.js +161 -178
- package/dist/xml/xml-scan.d.ts +78 -0
- package/dist/xml/xml-scan.js +180 -0
- package/dist/xml/xml.d.ts +29 -28
- package/dist/xml/xml.js +24 -24
- package/package.json +13 -9
package/dist/core/worksheet.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AuthoringError } from '../errors.js';
|
|
2
|
-
import {
|
|
2
|
+
import { tokenSet } from '../token-set.js';
|
|
3
|
+
import { assertAxisInBounds, decodeCellRef, encodeAddress, tryDecodeCellRef } from './address.js';
|
|
3
4
|
import { canonicalizeAutoFilter } from './autofilter.js';
|
|
4
5
|
import { applyCellStyle, Cell, copyCellContent } from './cell.js';
|
|
5
6
|
import { Column } from './column.js';
|
|
@@ -7,25 +8,25 @@ import { ConditionalFormattingOverlay } from './conditional-formatting-overlay.j
|
|
|
7
8
|
import { DataValidationOverlay } from './data-validation-overlay.js';
|
|
8
9
|
import { GridEdits } from './grid-edits.js';
|
|
9
10
|
import { INTERNAL } from './internal.js';
|
|
10
|
-
import { clearCoveredValues
|
|
11
|
+
import { clearCoveredValues } from './merge.js';
|
|
11
12
|
import { PivotTable } from './pivot-table.js';
|
|
12
13
|
import { deriveCredential, } from './protection.js';
|
|
13
14
|
import { Range, rangeFrom } from './range.js';
|
|
14
15
|
import { buildRowCells, positionalPlacements, rowPlacements } from './row-input.js';
|
|
15
16
|
import { Row } from './row.js';
|
|
16
17
|
import { Table } from './table.js';
|
|
18
|
+
import { UsedExtent } from './used-extent.js';
|
|
17
19
|
import { WorksheetComments } from './worksheet-comments.js';
|
|
20
|
+
import { WorksheetMerges } from './worksheet-merges.js';
|
|
18
21
|
import { WORKSHEET_MODEL_FACETS } from './worksheet-model.js';
|
|
19
22
|
import { WorksheetPictures } from './worksheet-pictures.js';
|
|
20
|
-
const
|
|
21
|
-
export function isVisibility(value) {
|
|
22
|
-
return Object.hasOwn(VISIBILITIES, value);
|
|
23
|
-
}
|
|
23
|
+
export const isVisibility = tokenSet({ visible: true, hidden: true, veryHidden: true });
|
|
24
24
|
export class Worksheet {
|
|
25
25
|
name;
|
|
26
26
|
id;
|
|
27
27
|
state;
|
|
28
28
|
tabColor;
|
|
29
|
+
codeName;
|
|
29
30
|
properties = {};
|
|
30
31
|
outline = {};
|
|
31
32
|
view = {};
|
|
@@ -42,28 +43,33 @@ export class Worksheet {
|
|
|
42
43
|
#pivotTables = [];
|
|
43
44
|
#loadedPivotTables = [];
|
|
44
45
|
#comments = new WorksheetComments(() => this.name);
|
|
45
|
-
#merges =
|
|
46
|
+
#merges = new WorksheetMerges();
|
|
46
47
|
#images = new WorksheetPictures({
|
|
47
48
|
columnWidth: (col) => this.#columns.get(col + 1)?.width ?? this.properties.defaultColWidth,
|
|
48
49
|
rowHeight: (row) => this.#rowProperties.get(row + 1)?.height ?? this.properties.defaultRowHeight,
|
|
49
50
|
});
|
|
50
51
|
#preservedReferences = [];
|
|
51
|
-
#mergeRects = [];
|
|
52
52
|
#dataValidations = new DataValidationOverlay();
|
|
53
53
|
#conditionalFormattings = new ConditionalFormattingOverlay();
|
|
54
54
|
#protection;
|
|
55
55
|
#autoFilter;
|
|
56
56
|
#edits;
|
|
57
|
+
#extent;
|
|
57
58
|
constructor(name, id, state = 'visible') {
|
|
58
59
|
this.name = name;
|
|
59
60
|
this.id = id;
|
|
60
61
|
this.state = state;
|
|
62
|
+
this.#extent = new UsedExtent({
|
|
63
|
+
rows: this.#rows,
|
|
64
|
+
rowProperties: this.#rowProperties,
|
|
65
|
+
columns: this.#columns,
|
|
66
|
+
mergeRects: this.#merges.rects,
|
|
67
|
+
});
|
|
61
68
|
this.#edits = new GridEdits({
|
|
62
69
|
rows: this.#rows,
|
|
63
70
|
rowProperties: this.#rowProperties,
|
|
64
71
|
columns: this.#columns,
|
|
65
72
|
merges: this.#merges,
|
|
66
|
-
mergeRects: this.#mergeRects,
|
|
67
73
|
tables: this.#tables,
|
|
68
74
|
images: this.#images.anchors,
|
|
69
75
|
dataValidations: this.#dataValidations,
|
|
@@ -79,8 +85,7 @@ export class Worksheet {
|
|
|
79
85
|
}
|
|
80
86
|
getCell(reference) {
|
|
81
87
|
const { col, row } = decodeCellRef(reference);
|
|
82
|
-
|
|
83
|
-
return this.#cellAt(master.row, master.col);
|
|
88
|
+
return this[INTERNAL].masterAt(row, col);
|
|
84
89
|
}
|
|
85
90
|
hasCell(row, col) {
|
|
86
91
|
return this.#rows.get(row)?.has(col) ?? false;
|
|
@@ -94,33 +99,24 @@ export class Worksheet {
|
|
|
94
99
|
getRange(referenceOrTop, left, bottom, right) {
|
|
95
100
|
if (typeof referenceOrTop === 'string')
|
|
96
101
|
return rangeFrom(this, referenceOrTop);
|
|
97
|
-
|
|
102
|
+
const corners = [left, bottom, right].filter((corner) => corner !== undefined).length + 1;
|
|
103
|
+
if (left === undefined || bottom === undefined || right === undefined) {
|
|
104
|
+
throw new AuthoringError(`getRange(top, left, bottom, right) needs all four corners; got ${corners}`);
|
|
105
|
+
}
|
|
106
|
+
return new Range(this, referenceOrTop, left, bottom, right);
|
|
98
107
|
}
|
|
99
108
|
get rowCount() {
|
|
100
|
-
|
|
101
|
-
for (const [number, cols] of this.#rows) {
|
|
102
|
-
if (number > last && this.#rowHasContent(cols))
|
|
103
|
-
last = number;
|
|
104
|
-
}
|
|
105
|
-
for (const number of this.#rowProperties.keys()) {
|
|
106
|
-
if (number > last)
|
|
107
|
-
last = number;
|
|
108
|
-
}
|
|
109
|
-
for (const rect of this.#mergeRects) {
|
|
110
|
-
if (rect.bottom > last)
|
|
111
|
-
last = rect.bottom;
|
|
112
|
-
}
|
|
113
|
-
return last;
|
|
109
|
+
return this.#extent.lastRow;
|
|
114
110
|
}
|
|
115
111
|
get actualRowCount() {
|
|
116
112
|
let count = 0;
|
|
117
113
|
for (const cols of this.#rows.values()) {
|
|
118
|
-
if (this.#
|
|
114
|
+
if (this.#rowIsPopulated(cols))
|
|
119
115
|
count++;
|
|
120
116
|
}
|
|
121
117
|
return count;
|
|
122
118
|
}
|
|
123
|
-
#
|
|
119
|
+
#rowIsPopulated(cols) {
|
|
124
120
|
for (const cell of cols.values()) {
|
|
125
121
|
if (cell.value !== null)
|
|
126
122
|
return true;
|
|
@@ -128,22 +124,7 @@ export class Worksheet {
|
|
|
128
124
|
return false;
|
|
129
125
|
}
|
|
130
126
|
get columnCount() {
|
|
131
|
-
|
|
132
|
-
for (const cols of this.#rows.values()) {
|
|
133
|
-
for (const [col, cell] of cols) {
|
|
134
|
-
if (cell.value !== null && col > last)
|
|
135
|
-
last = col;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
for (const index of this.#columns.keys()) {
|
|
139
|
-
if (index > last)
|
|
140
|
-
last = index;
|
|
141
|
-
}
|
|
142
|
-
for (const rect of this.#mergeRects) {
|
|
143
|
-
if (rect.right > last)
|
|
144
|
-
last = rect.right;
|
|
145
|
-
}
|
|
146
|
-
return last;
|
|
127
|
+
return this.#extent.lastColumn;
|
|
147
128
|
}
|
|
148
129
|
get usedRange() {
|
|
149
130
|
const bottom = this.rowCount;
|
|
@@ -228,20 +209,14 @@ export class Worksheet {
|
|
|
228
209
|
return this.#preservedReferences;
|
|
229
210
|
}
|
|
230
211
|
mergeCells(range) {
|
|
231
|
-
const
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
const clash = this.#mergeRects.find((existing) => rectsOverlap(existing, rect));
|
|
235
|
-
if (clash) {
|
|
236
|
-
throw new AuthoringError(`merged range "${range}" overlaps an existing merged region`);
|
|
237
|
-
}
|
|
238
|
-
this.#mergeRects.push(rect);
|
|
212
|
+
const rect = this.#merges.add(range);
|
|
213
|
+
if (rect !== undefined) {
|
|
214
|
+
this.#extent.noteMerge(rect);
|
|
239
215
|
clearCoveredValues(this.#rows, rect);
|
|
240
216
|
}
|
|
241
|
-
this.#merges.push(range);
|
|
242
217
|
}
|
|
243
218
|
get merges() {
|
|
244
|
-
return this.#merges;
|
|
219
|
+
return this.#merges.ranges;
|
|
245
220
|
}
|
|
246
221
|
get autoFilter() {
|
|
247
222
|
return this.#autoFilter;
|
|
@@ -250,17 +225,10 @@ export class Worksheet {
|
|
|
250
225
|
this.#autoFilter = filter === undefined ? undefined : canonicalizeAutoFilter(filter);
|
|
251
226
|
}
|
|
252
227
|
unmergeCells(range) {
|
|
253
|
-
const
|
|
254
|
-
if (
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const { top, left, bottom, right } = decodeRange(range);
|
|
258
|
-
if (top !== undefined && left !== undefined && bottom !== undefined && right !== undefined) {
|
|
259
|
-
const rectIndex = this.#mergeRects.findIndex((r) => r.top === top && r.left === left && r.bottom === bottom && r.right === right);
|
|
260
|
-
if (rectIndex !== -1)
|
|
261
|
-
this.#mergeRects.splice(rectIndex, 1);
|
|
262
|
-
}
|
|
263
|
-
return true;
|
|
228
|
+
const { existed, rectsChanged } = this.#merges.remove(range);
|
|
229
|
+
if (rectsChanged)
|
|
230
|
+
this.#extent.invalidate();
|
|
231
|
+
return existed;
|
|
264
232
|
}
|
|
265
233
|
addDataValidation(sqref, rule, options = {}) {
|
|
266
234
|
this.#dataValidations.add(sqref, rule, options);
|
|
@@ -282,6 +250,8 @@ export class Worksheet {
|
|
|
282
250
|
assertStartAndCount('splice', 'row', start, count);
|
|
283
251
|
const inserted = inserts.map((values, i) => buildRowCells(start + i, values, this.#columns));
|
|
284
252
|
this.#edits.spliceRows(start, count, inserted);
|
|
253
|
+
this.#merges.invalidate();
|
|
254
|
+
this.#extent.invalidate();
|
|
285
255
|
}
|
|
286
256
|
insertRow(pos, values) {
|
|
287
257
|
this.spliceRows(pos, 0, values);
|
|
@@ -323,6 +293,7 @@ export class Worksheet {
|
|
|
323
293
|
const { count = 1, insert = true } = options;
|
|
324
294
|
assertStartAndCount('duplicate', 'row', start, count);
|
|
325
295
|
const source = this.#rows.get(start);
|
|
296
|
+
const sourceProperties = this.#rowProperties.get(start);
|
|
326
297
|
const snapshot = (destRow) => {
|
|
327
298
|
const row = new Map();
|
|
328
299
|
if (source) {
|
|
@@ -334,18 +305,30 @@ export class Worksheet {
|
|
|
334
305
|
}
|
|
335
306
|
return row;
|
|
336
307
|
};
|
|
308
|
+
const copyProperties = (destRow) => {
|
|
309
|
+
if (sourceProperties === undefined)
|
|
310
|
+
this.#rowProperties.delete(destRow);
|
|
311
|
+
else
|
|
312
|
+
this.#rowProperties.set(destRow, { ...sourceProperties });
|
|
313
|
+
};
|
|
337
314
|
if (insert) {
|
|
338
315
|
const copies = Array.from({ length: count }, () => snapshot(start));
|
|
339
316
|
this.#edits.spliceRows(start + 1, 0, copies);
|
|
317
|
+
this.#merges.invalidate();
|
|
340
318
|
}
|
|
341
319
|
else {
|
|
342
320
|
for (let i = 1; i <= count; i++)
|
|
343
321
|
this.#rows.set(start + i, snapshot(start + i));
|
|
344
322
|
}
|
|
323
|
+
for (let i = 1; i <= count; i++)
|
|
324
|
+
copyProperties(start + i);
|
|
325
|
+
this.#extent.invalidate();
|
|
345
326
|
}
|
|
346
327
|
spliceColumns(start, count, ...inserts) {
|
|
347
328
|
assertStartAndCount('splice', 'column', start, count);
|
|
348
329
|
this.#edits.spliceColumns(start, count, inserts);
|
|
330
|
+
this.#merges.invalidate();
|
|
331
|
+
this.#extent.invalidate();
|
|
349
332
|
}
|
|
350
333
|
insertColumn(pos, values) {
|
|
351
334
|
this.spliceColumns(pos, 0, values);
|
|
@@ -374,11 +357,11 @@ export class Worksheet {
|
|
|
374
357
|
this.#rows.clear();
|
|
375
358
|
this.#columns.clear();
|
|
376
359
|
this.#rowProperties.clear();
|
|
377
|
-
this.#merges.
|
|
378
|
-
this.#mergeRects.length = 0;
|
|
360
|
+
this.#merges.clear();
|
|
379
361
|
this.#dataValidations.clear();
|
|
380
362
|
this.#conditionalFormattings.clear();
|
|
381
363
|
this.#tables.length = 0;
|
|
364
|
+
this.#extent.reset();
|
|
382
365
|
}
|
|
383
366
|
set model(model) {
|
|
384
367
|
this.#resetContent();
|
|
@@ -412,12 +395,14 @@ export class Worksheet {
|
|
|
412
395
|
cell = new Cell(row, col);
|
|
413
396
|
cols.set(col, cell);
|
|
414
397
|
}
|
|
398
|
+
this.#extent.noteCell(row, col);
|
|
415
399
|
return cell;
|
|
416
400
|
}
|
|
417
401
|
[INTERNAL] = {
|
|
418
402
|
evictRow: (number) => {
|
|
419
403
|
this.#rows.delete(number);
|
|
420
404
|
this.#rowProperties.delete(number);
|
|
405
|
+
this.#extent.invalidate();
|
|
421
406
|
},
|
|
422
407
|
addLoadedPivotTable: (pivot) => {
|
|
423
408
|
this.#loadedPivotTables.push(pivot);
|
|
@@ -432,6 +417,11 @@ export class Worksheet {
|
|
|
432
417
|
this.#protection = protection;
|
|
433
418
|
},
|
|
434
419
|
cellAt: (row, col) => this.#cellAt(row, col),
|
|
420
|
+
masterAt: (row, col) => {
|
|
421
|
+
const master = this.#merges.masterOf(row, col);
|
|
422
|
+
return this.#cellAt(master.row, master.col);
|
|
423
|
+
},
|
|
424
|
+
peekCell: (row, col) => this.#rows.get(row)?.get(col),
|
|
435
425
|
rowPropertiesOf: (number) => this.#rowProperties.get(number),
|
|
436
426
|
ensureRowProperties: (number) => {
|
|
437
427
|
let properties = this.#rowProperties.get(number);
|
|
@@ -439,8 +429,13 @@ export class Worksheet {
|
|
|
439
429
|
properties = {};
|
|
440
430
|
this.#rowProperties.set(number, properties);
|
|
441
431
|
}
|
|
432
|
+
this.#extent.noteDeclaredRow(number);
|
|
442
433
|
return properties;
|
|
443
434
|
},
|
|
435
|
+
dropRowProperties: (number) => {
|
|
436
|
+
if (this.#rowProperties.delete(number))
|
|
437
|
+
this.#extent.invalidate();
|
|
438
|
+
},
|
|
444
439
|
rowCells: (number) => {
|
|
445
440
|
const cols = this.#rows.get(number);
|
|
446
441
|
return cols ? [...cols].sort(([a], [b]) => a - b).map(([, cell]) => cell) : [];
|
|
@@ -452,8 +447,13 @@ export class Worksheet {
|
|
|
452
447
|
properties = {};
|
|
453
448
|
this.#columns.set(index, properties);
|
|
454
449
|
}
|
|
450
|
+
this.#extent.noteDeclaredColumn(index);
|
|
455
451
|
return properties;
|
|
456
452
|
},
|
|
453
|
+
dropColumnProperties: (index) => {
|
|
454
|
+
if (this.#columns.delete(index))
|
|
455
|
+
this.#extent.invalidate();
|
|
456
|
+
},
|
|
457
457
|
columnCells: (index) => {
|
|
458
458
|
const cells = [];
|
|
459
459
|
for (const number of [...this.#rows.keys()].sort((a, b) => a - b)) {
|
|
@@ -466,9 +466,7 @@ export class Worksheet {
|
|
|
466
466
|
};
|
|
467
467
|
}
|
|
468
468
|
function assertStartAndCount(verb, axis, start, count) {
|
|
469
|
-
|
|
470
|
-
throw new RangeError(`${verb} start ${start} is out of bounds: ${axis}s start at 1`);
|
|
471
|
-
}
|
|
469
|
+
assertAxisInBounds(axis, start);
|
|
472
470
|
if (!Number.isInteger(count) || count < 0) {
|
|
473
471
|
throw new RangeError(`${verb} count ${count} is invalid: it must be a non-negative integer`);
|
|
474
472
|
}
|
package/dist/customui/ribbon.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { strFromU8 } from 'fflate';
|
|
2
|
-
import {
|
|
2
|
+
import { isRelType } from '../rel-type.js';
|
|
3
|
+
import { tokenSet } from '../token-set.js';
|
|
4
|
+
import { boolStrict, localName, xmlEvents } from '../xml/xml-scan.js';
|
|
3
5
|
import { CustomUiParseError } from './errors.js';
|
|
4
6
|
export const CUSTOMUI_2006_NAMESPACE = 'http://schemas.microsoft.com/office/2006/01/customui';
|
|
5
7
|
export const CUSTOMUI_2009_NAMESPACE = 'http://schemas.microsoft.com/office/2009/07/customui';
|
|
6
8
|
export const CUSTOMUI_2007_REL_TYPE = 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility';
|
|
7
9
|
export const CUSTOMUI_2010_REL_TYPE = 'http://schemas.microsoft.com/office/2007/relationships/ui/extensibility';
|
|
8
10
|
export function isCustomUiRelType(type) {
|
|
9
|
-
return type
|
|
11
|
+
return isRelType(type, 'ui/extensibility');
|
|
10
12
|
}
|
|
11
13
|
const MAX_DEPTH = 256;
|
|
12
|
-
const
|
|
14
|
+
const isKnownControlKind = tokenSet({
|
|
13
15
|
button: true,
|
|
14
16
|
toggleButton: true,
|
|
15
17
|
checkBox: true,
|
|
@@ -28,10 +30,7 @@ const KNOWN_KINDS = {
|
|
|
28
30
|
dialogBoxLauncher: true,
|
|
29
31
|
control: true,
|
|
30
32
|
item: true,
|
|
31
|
-
};
|
|
32
|
-
function isKnownControlKind(local) {
|
|
33
|
-
return Object.hasOwn(KNOWN_KINDS, local);
|
|
34
|
-
}
|
|
33
|
+
});
|
|
35
34
|
export function parseCustomUi(input) {
|
|
36
35
|
const xml = typeof input === 'string' ? input : strFromU8(input);
|
|
37
36
|
let root;
|
package/dist/entries/core.d.ts
CHANGED
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
export { type CellAddress, columnToNumber, decodeAddress, decodeRange, encodeAddress, type GridRect, MAX_COLUMN, MAX_ROW, numberToColumn, type RangeAddress, } from '../core/address.ts';
|
|
2
|
-
export type
|
|
1
|
+
export { type CellAddress, type CellPosition, columnToNumber, decodeAddress, decodeRange, encodeAddress, type GridRect, MAX_COLUMN, MAX_ROW, numberToColumn, type RangeAddress, } from '../core/address.ts';
|
|
2
|
+
export { type AutoFilter, type CustomFilter, type CustomFilterOperator, type CustomFilterPredicate, type FilterColumn, type FilterCriteria, isCustomFilterOperator, type ValuesFilter, } from '../core/autofilter.ts';
|
|
3
3
|
export { Cell } from '../core/cell.ts';
|
|
4
4
|
export { applyTint, type ColorResolutionContext, DEFAULT_INDEXED_COLORS, resolveColor, SYSTEM_INDEXED_COLORS, } from '../core/color-resolution.ts';
|
|
5
|
+
export { AxisHandle } from '../core/axis-handle.ts';
|
|
5
6
|
export { Column } from '../core/column.ts';
|
|
7
|
+
export type { DateEpoch } from '../core/date.ts';
|
|
6
8
|
export type { Comment, CommentThread, Mention, MentionRef, Person } from '../core/comment-thread.ts';
|
|
7
|
-
export type
|
|
8
|
-
export type
|
|
9
|
-
export
|
|
10
|
-
export {
|
|
11
|
-
export type {
|
|
12
|
-
export {
|
|
9
|
+
export { type CfTimePeriod, type CfValueObject, type CfValueObjectType, type ConditionalFormatting, type ConditionalFormattingOperator, type ConditionalFormattingRule, type ConditionalFormattingType, type IconSetType, isCfTimePeriod, isCfValueObjectType, isConditionalFormattingOperator, isConditionalFormattingType, isIconSetType, } from '../core/conditional-formatting.ts';
|
|
10
|
+
export { type DataValidation, type DataValidationEntry, type DataValidationErrorStyle, type DataValidationOperator, type DataValidationType, isDataValidationErrorStyle, isDataValidationOperator, isDataValidationType, } from '../core/data-validation.ts';
|
|
11
|
+
export type { AxisSplice } from '../core/grid-shift.ts';
|
|
12
|
+
export { type AnchoredImage, type AnchorPoint, type Extent, type ImageAnchor, type ImageEditAs, isImageEditAs, isOneCellAnchor, type OneCellAnchor, type PortableImage, PX_TO_EMU, type TwoCellAnchor, type WorkbookImage, type WorksheetImages, } from '../core/image.ts';
|
|
13
|
+
export type { ReadPackageOptions } from '../io/opc/read-options.ts';
|
|
14
|
+
export { INVALID_SHEET_NAME_CHARS, MAX_COLUMN_WIDTH, MAX_ROW_HEIGHT, MAX_SHEET_NAME_LENGTH, MAX_TABLE_NAME_LENGTH, TABLE_NAME_PATTERN, } from '../core/limits.ts';
|
|
15
|
+
export { type HeaderFooter, isPageOrder, isPageOrientation, type PageBreak, type PageMargins, type PageOrder, type PageOrientation, type PageSetup, type PrintOptions, } from '../core/page-setup.ts';
|
|
16
|
+
export { type ParsedPivotField, type ParsedPivotSource, type ParsedPivotTable, type PivotCacheField, type PivotItem, type PivotMetric, type PivotNumericSummary, isDeclarablePivotSourceKind, type PivotRecordCell, type PivotSourceKind, PivotTable, type PivotTableOptions, } from '../core/pivot-table.ts';
|
|
13
17
|
export type { PreservedPart, PreservedRelationship, PreservedRootReference, PreservedWorksheetReference, } from '../core/preserved.ts';
|
|
14
18
|
export type { SheetProtection, SheetProtectionCredential, SheetProtectionFlags, SheetProtectionOptions, } from '../core/protection.ts';
|
|
15
19
|
export { Range } from '../core/range.ts';
|
|
16
20
|
export { Row } from '../core/row.ts';
|
|
17
|
-
export type
|
|
18
|
-
export { Table, type TableColumn, type TableColumnStyle, type TableOptions, type TableRegion, type TableStyleInfo, } from '../core/table.ts';
|
|
21
|
+
export { type Alignment, type Border, type BorderEdge, type BorderStyle, type CellContent, type CellStyle, type Color, type Fill, type FillPatternType, type Font, type FontScheme, type FontVerticalAlignment, type GradientFill, type GradientStop, type HorizontalAlignment, isBorderStyle, isFillPatternType, isFontScheme, isFontVerticalAlignment, isHorizontalAlignment, isNamedUnderlineStyle, isVerticalAlignment, type PatternFill, type Protection, type UnderlineStyle, type VerticalAlignment, } from '../core/style.ts';
|
|
22
|
+
export { Table, type TableColumn, type TableColumnStyle, isTotalsRowFunction, type TableGrid, type TableOptions, type TableRegion, type TableStyleInfo, type TotalsRowFunction, } from '../core/table.ts';
|
|
23
|
+
export type { DifferentialStyle, NamedCellStyle, TableStyleNamespace, TableStyleTable, } from '../core/workbook-styles.ts';
|
|
19
24
|
export { isTableStyleElementType, STRIPE_ELEMENT_TYPES, TABLE_STYLE_ELEMENT_TYPES, type TableStyle, type TableStyleElement, type TableStyleElementType, } from '../core/table-style.ts';
|
|
20
25
|
export { estimateWrappedLines } from '../core/text-metrics.ts';
|
|
21
|
-
export { DEFAULT_THEME_COLOR_SCHEME, DEFAULT_THEME_FONTS, THEME_COLOR_SLOTS, type ThemeColorScheme, type ThemeColorSlot, type ThemeFontScheme, type ThemeOverrides, } from '../core/theme.ts';
|
|
26
|
+
export { DEFAULT_THEME_COLOR_SCHEME, DEFAULT_THEME_FONTS, isThemeColorSlot, THEME_COLOR_SLOTS, type ThemeColorScheme, type ThemeColorSlot, type ThemeFontScheme, type ThemeOverrides, } from '../core/theme.ts';
|
|
22
27
|
export { type CellValue, cellValueToText, coerceCellValue, type DataTableFormulaValue, detectValueType, ERROR_CODES, type ErrorCode, type ErrorValue, type FormulaResult, type FormulaValue, type HyperlinkValue, isDataTableFormulaValue, isErrorCode, isErrorValue, isFormulaValue, isHyperlinkValue, isRichTextValue, isSharedFormulaValue, type RichTextRun, type RichTextValue, richTextToPlain, type SharedFormulaValue, ValueType, } from '../core/value.ts';
|
|
23
|
-
export { type AddImageOptions, type AddWorksheetOptions, DEFAULT_WORKBOOK_VIEW, type DefinedName, type PreservedWorkbookReference, Workbook, type WorkbookProperties, type WorkbookView, } from '../core/workbook.ts';
|
|
28
|
+
export { type AddImageOptions, type AddWorksheetOptions, DEFAULT_WORKBOOK_VIEW, type DefinedName, type PreservedTheme, type PreservedWorkbookReference, Workbook, type WorkbookProperties, type WorkbookView, } from '../core/workbook.ts';
|
|
24
29
|
export type { WorkbookProtection, WorkbookProtectionCredentialAttr, } from '../core/workbook-protection.ts';
|
|
25
|
-
export { type CellModel, type ColumnProperties, type OutlineProperties, type RowInput, type RowProperties, type SheetView, type Visibility, Worksheet, type WorksheetModel, type WorksheetProperties, type WorksheetState, } from '../core/worksheet.ts';
|
|
30
|
+
export { type CellModel, type ColumnProperties, type OutlineProperties, type RowInput, type RowProperties, type SheetView, isVisibility, type Visibility, Worksheet, type WorksheetModel, type WorksheetProperties, type WorksheetState, } from '../core/worksheet.ts';
|
package/dist/entries/core.js
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
export { columnToNumber, decodeAddress, decodeRange, encodeAddress, MAX_COLUMN, MAX_ROW, numberToColumn, } from '../core/address.js';
|
|
2
|
+
export { isCustomFilterOperator, } from '../core/autofilter.js';
|
|
2
3
|
export { Cell } from '../core/cell.js';
|
|
3
4
|
export { applyTint, DEFAULT_INDEXED_COLORS, resolveColor, SYSTEM_INDEXED_COLORS, } from '../core/color-resolution.js';
|
|
5
|
+
export { AxisHandle } from '../core/axis-handle.js';
|
|
4
6
|
export { Column } from '../core/column.js';
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
7
|
+
export { isCfTimePeriod, isCfValueObjectType, isConditionalFormattingOperator, isConditionalFormattingType, isIconSetType, } from '../core/conditional-formatting.js';
|
|
8
|
+
export { isDataValidationErrorStyle, isDataValidationOperator, isDataValidationType, } from '../core/data-validation.js';
|
|
9
|
+
export { isImageEditAs, isOneCellAnchor, PX_TO_EMU, } from '../core/image.js';
|
|
10
|
+
export { INVALID_SHEET_NAME_CHARS, MAX_COLUMN_WIDTH, MAX_ROW_HEIGHT, MAX_SHEET_NAME_LENGTH, MAX_TABLE_NAME_LENGTH, TABLE_NAME_PATTERN, } from '../core/limits.js';
|
|
11
|
+
export { isPageOrder, isPageOrientation, } from '../core/page-setup.js';
|
|
12
|
+
export { isDeclarablePivotSourceKind, PivotTable, } from '../core/pivot-table.js';
|
|
8
13
|
export { Range } from '../core/range.js';
|
|
9
14
|
export { Row } from '../core/row.js';
|
|
10
|
-
export {
|
|
15
|
+
export { isBorderStyle, isFillPatternType, isFontScheme, isFontVerticalAlignment, isHorizontalAlignment, isNamedUnderlineStyle, isVerticalAlignment, } from '../core/style.js';
|
|
16
|
+
export { Table, isTotalsRowFunction, } from '../core/table.js';
|
|
11
17
|
export { isTableStyleElementType, STRIPE_ELEMENT_TYPES, TABLE_STYLE_ELEMENT_TYPES, } from '../core/table-style.js';
|
|
12
18
|
export { estimateWrappedLines } from '../core/text-metrics.js';
|
|
13
|
-
export { DEFAULT_THEME_COLOR_SCHEME, DEFAULT_THEME_FONTS, THEME_COLOR_SLOTS, } from '../core/theme.js';
|
|
19
|
+
export { DEFAULT_THEME_COLOR_SCHEME, DEFAULT_THEME_FONTS, isThemeColorSlot, THEME_COLOR_SLOTS, } from '../core/theme.js';
|
|
14
20
|
export { cellValueToText, coerceCellValue, detectValueType, ERROR_CODES, isDataTableFormulaValue, isErrorCode, isErrorValue, isFormulaValue, isHyperlinkValue, isRichTextValue, isSharedFormulaValue, richTextToPlain, ValueType, } from '../core/value.js';
|
|
15
21
|
export { DEFAULT_WORKBOOK_VIEW, Workbook, } from '../core/workbook.js';
|
|
16
|
-
export { Worksheet, } from '../core/worksheet.js';
|
|
22
|
+
export { isVisibility, Worksheet, } from '../core/worksheet.js';
|
package/dist/entries/xlsx.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { editXlsxVbaAddReference, editXlsxVbaRemoveModule } from '../io/xlsx/edit-vba.ts';
|
|
2
|
-
export {
|
|
2
|
+
export { readXlsx } from '../io/xlsx/read.ts';
|
|
3
3
|
export { type ReadSheetRowsOptions, readSheetRows, readWorkbookStream, } from '../io/xlsx/read-rows.ts';
|
|
4
4
|
export { DEFAULT_THEME_XML, parseThemeColorScheme, parseThemeFontScheme, } from '../io/xlsx/theme-xml.ts';
|
|
5
5
|
export { type WriteOptions, writeXlsx, writeXlsxAsync } from '../io/xlsx/write.ts';
|
package/dist/errors.d.ts
CHANGED
|
@@ -77,3 +77,67 @@ export declare class InternalError extends XlsxError {
|
|
|
77
77
|
readonly code = "internal";
|
|
78
78
|
constructor(message?: string, options?: ErrorOptions);
|
|
79
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* A name as it should appear inside an error message: quoted, and unambiguous whatever it contains.
|
|
82
|
+
*
|
|
83
|
+
* Almost every message this library throws names something the caller or the file chose - a sheet, a
|
|
84
|
+
* table, a defined name, a module stream, a part path - and the tree had grown three ways of setting
|
|
85
|
+
* that name off from the prose, split by directory rather than by intent: `"..."`, `'...'`, and
|
|
86
|
+
* `JSON.stringify`. Only the third survives a name that itself contains a quote, which is exactly the
|
|
87
|
+
* class of name a spreadsheet permits: a sheet called `Q1 "draft"` renders under either literal
|
|
88
|
+
* spelling as a message whose reader cannot tell where the name ends. It also renders a name
|
|
89
|
+
* containing a newline or a zero-width character as one that looks identical to a name that does not,
|
|
90
|
+
* which for a library whose input is untrusted is the difference between a diagnostic and a decoy.
|
|
91
|
+
*
|
|
92
|
+
* So: one spelling, and the one that escapes. `JSON.stringify` is the whole implementation - the
|
|
93
|
+
* point is not the algorithm but that every throw site reaches the same one.
|
|
94
|
+
*
|
|
95
|
+
* Not exported from the `/errors` entry: this is how messages are written, not part of the taxonomy
|
|
96
|
+
* a caller catches.
|
|
97
|
+
*/
|
|
98
|
+
export declare function quoted(name: string): string;
|
|
99
|
+
/**
|
|
100
|
+
* The one message for "that token is not in the enumeration", owned here because both sides of a
|
|
101
|
+
* layering boundary throw it.
|
|
102
|
+
*
|
|
103
|
+
* `checkedToken` in `src/xml/xml.ts` is the general form, and `core/` may not import a serialisation
|
|
104
|
+
* to reach it. The response to that constraint had been to transcribe the sentence into
|
|
105
|
+
* `core/table-style.ts` character for character, which is a copy that no gate can see is a copy. This
|
|
106
|
+
* module is the one place below both of them, so the template lives here and neither side owns it.
|
|
107
|
+
*/
|
|
108
|
+
export declare function invalidToken(kind: string, value: string): AuthoringError;
|
|
109
|
+
/**
|
|
110
|
+
* Refuse a number OOXML cannot spell. Every numeric attribute in the format is `xsd:double`,
|
|
111
|
+
* `xsd:unsignedInt` or a bounded flavour of one, and none of those lexical spaces has a form for a
|
|
112
|
+
* NaN or an infinity, so a value that reaches the file as `NaN` is a package Excel reports as
|
|
113
|
+
* damaged. Neither has the formula grammar, which is why the guard is here rather than in the XML
|
|
114
|
+
* serialiser: the two spellings of a number this library writes -- an attribute's and a formula
|
|
115
|
+
* literal's -- sit on opposite sides of the `core`/`xml` boundary and refuse the same values.
|
|
116
|
+
*
|
|
117
|
+
* Exported for the callers that must refuse before they write. A number can be unwritable and still
|
|
118
|
+
* be read on the way to the bytes: compared, summed, walked. A comparison against `NaN` or an
|
|
119
|
+
* infinity silently takes the wrong branch long before the value would have been serialised.
|
|
120
|
+
*
|
|
121
|
+
* @throws {AuthoringError} naming the value.
|
|
122
|
+
*/
|
|
123
|
+
export declare function assertWritableNumber(value: number): void;
|
|
124
|
+
/** `U+0001`-style spelling of a code point, for an escape body or an error message. */
|
|
125
|
+
export declare function codePointHex(codePoint: number): string;
|
|
126
|
+
/**
|
|
127
|
+
* The error for a string carrying a character the target format cannot encode, or `undefined` when
|
|
128
|
+
* it carries none. Naming the code point and its offset is the whole value of the message: these
|
|
129
|
+
* strings arrive from a database column or a CSV field, not from a literal the author can see.
|
|
130
|
+
*
|
|
131
|
+
* Two formats refuse characters for unrelated reasons -- XML 1.0's `Char` production, and UTF-8's
|
|
132
|
+
* inability to encode a lone surrogate -- and each had grown its own copy of the rendering, which
|
|
133
|
+
* had already drifted: the CSV one omitted the zero padding, invisibly, because a surrogate is
|
|
134
|
+
* always four digits and nothing narrower had been added yet. The *patterns* stay beside their
|
|
135
|
+
* consumers, which is where they are understood; only the spelling and the message skeleton are
|
|
136
|
+
* shared, which is where they were wrong.
|
|
137
|
+
*
|
|
138
|
+
* `pattern` must not carry the `g` flag: a stateful `lastIndex` would make the same string answer
|
|
139
|
+
* differently on a second call.
|
|
140
|
+
*
|
|
141
|
+
* @param why the clause explaining the refusal, appended after the offset.
|
|
142
|
+
*/
|
|
143
|
+
export declare function unrepresentable(text: string, pattern: RegExp, why: string): AuthoringError | undefined;
|
package/dist/errors.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { hex } from './hex.js';
|
|
1
2
|
export class XlsxError extends Error {
|
|
2
3
|
}
|
|
3
4
|
export class AuthoringError extends XlsxError {
|
|
@@ -13,3 +14,24 @@ export class InternalError extends XlsxError {
|
|
|
13
14
|
super(message === undefined ? REPORT_NOTICE : `${message}\n\n${REPORT_NOTICE}`, options);
|
|
14
15
|
}
|
|
15
16
|
}
|
|
17
|
+
export function quoted(name) {
|
|
18
|
+
return JSON.stringify(name);
|
|
19
|
+
}
|
|
20
|
+
export function invalidToken(kind, value) {
|
|
21
|
+
return new AuthoringError(`Invalid ${kind} ${quoted(value)}: not a value the OOXML enumeration allows`);
|
|
22
|
+
}
|
|
23
|
+
export function assertWritableNumber(value) {
|
|
24
|
+
if (Number.isFinite(value))
|
|
25
|
+
return;
|
|
26
|
+
throw new AuthoringError(`cannot write a non-finite number (${value}): it has no OOXML representation`);
|
|
27
|
+
}
|
|
28
|
+
export function codePointHex(codePoint) {
|
|
29
|
+
return hex(codePoint, 4);
|
|
30
|
+
}
|
|
31
|
+
export function unrepresentable(text, pattern, why) {
|
|
32
|
+
const found = pattern.exec(text);
|
|
33
|
+
if (found === null)
|
|
34
|
+
return undefined;
|
|
35
|
+
const codePoint = text.codePointAt(found.index);
|
|
36
|
+
return new AuthoringError(`cannot write U+${codePointHex(codePoint)} at offset ${found.index}: ${why}`);
|
|
37
|
+
}
|
package/dist/hex.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `value` in uppercase hexadecimal, zero-padded to at least `digits`.
|
|
3
|
+
*
|
|
4
|
+
* Uppercase because five of the six sites this replaced were, because OOXML writes `ARGB` values that
|
|
5
|
+
* way, and because a hex digit read by a human beside a decimal number is easier to tell apart when
|
|
6
|
+
* it is not lowercase. A value wider than `digits` is not truncated: padding is a minimum.
|
|
7
|
+
*/
|
|
8
|
+
export declare function hex(value: number, digits: number): string;
|
package/dist/hex.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refuse a delimiter the codec cannot honour.
|
|
3
|
+
*
|
|
4
|
+
* A `RangeError` rather than an `AuthoringError`: this is a single scalar out of range, which
|
|
5
|
+
* `src/errors.ts` reserves for the native types on the grounds that they exist for exactly that.
|
|
6
|
+
*
|
|
7
|
+
* @throws {RangeError} if the delimiter is not exactly one character.
|
|
8
|
+
*/
|
|
9
|
+
export declare function assertDelimiter(delimiter: string): void;
|
package/dist/io/csv/read.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Workbook } from '../../core/workbook.js';
|
|
2
|
+
import { assertDelimiter } from './delimiter.js';
|
|
2
3
|
export function readCsv(input, options = {}) {
|
|
3
4
|
const text = stripBom(typeof input === 'string' ? input : new TextDecoder('utf-8', { ignoreBOM: true }).decode(input));
|
|
4
5
|
const delimiter = options.delimiter ?? ',';
|
|
5
|
-
|
|
6
|
-
throw new RangeError(`CSV delimiter must be a single character, got ${JSON.stringify(delimiter)}`);
|
|
7
|
-
}
|
|
6
|
+
assertDelimiter(delimiter);
|
|
8
7
|
let rows = parseCsvRows(text, delimiter);
|
|
9
8
|
if (options.headers)
|
|
10
9
|
rows = rows.slice(1);
|
|
@@ -52,7 +51,15 @@ function parseCsvRows(text, delimiter) {
|
|
|
52
51
|
row = [];
|
|
53
52
|
field = '';
|
|
54
53
|
}
|
|
55
|
-
else if (ch
|
|
54
|
+
else if (ch === '\r') {
|
|
55
|
+
if (text[i + 1] !== '\n') {
|
|
56
|
+
row.push(field);
|
|
57
|
+
rows.push(row);
|
|
58
|
+
row = [];
|
|
59
|
+
field = '';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
56
63
|
field += ch;
|
|
57
64
|
}
|
|
58
65
|
}
|
package/dist/io/csv/write.d.ts
CHANGED
|
@@ -18,8 +18,15 @@ export interface CsvWriteOptions {
|
|
|
18
18
|
readonly delimiter?: string;
|
|
19
19
|
/** Line separator between rows; defaults to `"\n"`. */
|
|
20
20
|
readonly rowDelimiter?: string;
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
21
|
+
/**
|
|
22
|
+
* An Excel number-format code (e.g. `"yyyy-mm-dd"`, `"d mmm yy hh:mm"`) for Date cells; without it
|
|
23
|
+
* a Date renders as a full ISO-8601 timestamp.
|
|
24
|
+
*
|
|
25
|
+
* The same vocabulary as {@link Cell.numFmt}, so `writeCsv(wb, {dateFormat: cell.numFmt})` renders
|
|
26
|
+
* what the cell would show. It used to be a moment.js-style token set, which is case-sensitive and
|
|
27
|
+
* spells the month `MM` and the minute `mm`: passing this library's own format codes to it produced
|
|
28
|
+
* `2024-45-dd` with no throw and no warning. See ADR 0041.
|
|
29
|
+
*/
|
|
23
30
|
readonly dateFormat?: string;
|
|
24
31
|
/** Render Date cells in UTC rather than the runner's local time. */
|
|
25
32
|
readonly dateUTC?: boolean;
|