@shbernal/ts-xlsx 3.0.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 +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 +2 -4
- package/dist/core/column.d.ts +1 -0
- package/dist/core/column.js +3 -0
- 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 +9 -1
- package/dist/core/conditional-formatting.js +34 -18
- 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 +6 -0
- package/dist/core/data-validation.js +15 -4
- 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 +13 -9
- package/dist/core/image.js +7 -5
- 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.d.ts +5 -4
- package/dist/core/merge.js +18 -19
- package/dist/core/pivot-table.js +63 -45
- 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 +1 -0
- package/dist/core/row.js +3 -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 +27 -9
- package/dist/core/table.js +51 -34
- package/dist/core/theme.js +6 -5
- 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 +55 -6
- package/dist/core/worksheet.js +36 -44
- package/dist/customui/ribbon.js +2 -1
- 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 +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 +1 -1
- package/dist/io/opc/read-opc.d.ts +54 -14
- package/dist/io/opc/read-opc.js +42 -20
- 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/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 +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 +45 -81
- 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 +44 -23
- 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 +8 -1
- 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 -32
- package/dist/io/xlsx/conditional-formatting.d.ts +6 -3
- package/dist/io/xlsx/conditional-formatting.js +30 -26
- package/dist/io/xlsx/data-validation.js +29 -27
- package/dist/io/xlsx/edit-vba.d.ts +7 -2
- package/dist/io/xlsx/edit-vba.js +14 -21
- 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 +37 -5
- package/dist/io/xlsx/hyperlinks.js +22 -13
- package/dist/io/xlsx/images.js +11 -13
- 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 +14 -2
- package/dist/io/xlsx/package-plan.js +39 -11
- 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 +2 -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.js → read-rich-runs.js} +6 -3
- package/dist/io/xlsx/read-rows.d.ts +18 -5
- package/dist/io/xlsx/read-rows.js +45 -31
- package/dist/io/xlsx/read-shared-strings.js +3 -2
- package/dist/io/xlsx/read-styles.d.ts +1 -6
- package/dist/io/xlsx/read-styles.js +6 -71
- 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 +2 -1
- package/dist/io/xlsx/read-worksheet.js +35 -164
- package/dist/io/xlsx/read.d.ts +5 -12
- package/dist/io/xlsx/read.js +73 -406
- 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 +145 -9
- 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 -207
- package/dist/io/xlsx/tables.js +10 -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 +2 -1
- package/dist/io/xlsx/workbook-xml.d.ts +54 -4
- package/dist/io/xlsx/workbook-xml.js +60 -34
- package/dist/io/xlsx/worksheet-xml.d.ts +23 -70
- package/dist/io/xlsx/worksheet-xml.js +48 -229
- package/dist/io/xlsx/write-stream.d.ts +65 -16
- package/dist/io/xlsx/write-stream.js +50 -20
- package/dist/io/xlsx/write.d.ts +1 -2
- package/dist/io/xlsx/write.js +114 -74
- package/dist/rel-type.d.ts +16 -0
- package/dist/rel-type.js +6 -0
- package/dist/token-set.d.ts +13 -0
- package/dist/token-set.js +4 -1
- package/dist/vba/bytes.d.ts +14 -5
- package/dist/vba/bytes.js +16 -6
- package/dist/vba/cfb-format.d.ts +8 -0
- package/dist/vba/cfb-format.js +1 -0
- package/dist/vba/cfb-writer.d.ts +9 -0
- package/dist/vba/cfb-writer.js +12 -9
- package/dist/vba/cfb.d.ts +13 -1
- package/dist/vba/cfb.js +73 -51
- package/dist/vba/codepage.js +2 -1
- package/dist/vba/errors.d.ts +7 -0
- package/dist/vba/ms-ovba.js +51 -16
- package/dist/vba/project-editor.js +35 -40
- package/dist/vba/project.d.ts +11 -1
- package/dist/vba/project.js +27 -8
- package/dist/vba/vba-encoding.js +4 -5
- 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 +72 -10
- package/dist/xml/xml-read.js +94 -18
- package/dist/xml/xml-scan.d.ts +15 -37
- package/dist/xml/xml-scan.js +12 -40
- package/dist/xml/xml.d.ts +28 -27
- package/dist/xml/xml.js +24 -24
- package/package.json +12 -7
- /package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +0 -0
package/dist/core/worksheet.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { PreservedWorksheetReference } from './preserved.ts';
|
|
|
12
12
|
import { type SheetProtection, type SheetProtectionOptions } from './protection.ts';
|
|
13
13
|
import { Range } from './range.ts';
|
|
14
14
|
import { Row } from './row.ts';
|
|
15
|
-
import type { CellStyle, Color, Fill } from './style.ts';
|
|
15
|
+
import type { CellContent, CellStyle, Color, Fill } from './style.ts';
|
|
16
16
|
import { Table, type TableOptions } from './table.ts';
|
|
17
17
|
import type { CellValue } from './value.ts';
|
|
18
18
|
/**
|
|
@@ -107,8 +107,13 @@ export interface RowProperties {
|
|
|
107
107
|
/** Background fill applied to the row's cells that carry no fill of their own. */
|
|
108
108
|
fill?: Fill;
|
|
109
109
|
}
|
|
110
|
-
/**
|
|
111
|
-
|
|
110
|
+
/**
|
|
111
|
+
* One materialised cell in a {@link WorksheetModel}: its position, value, note, and every facet of its
|
|
112
|
+
* formatting. Extends {@link CellContent} rather than {@link CellStyle} so the quote-prefix flag and
|
|
113
|
+
* the named-style link travel with a model round-trip: they are written and read back like any other
|
|
114
|
+
* facet, and leaving them off the tuple is what made a `dst.model = src.model` drop them.
|
|
115
|
+
*/
|
|
116
|
+
export interface CellModel extends CellContent {
|
|
112
117
|
readonly row: number;
|
|
113
118
|
readonly col: number;
|
|
114
119
|
value: CellValue;
|
|
@@ -177,6 +182,17 @@ export declare class Worksheet {
|
|
|
177
182
|
* never fabricates one.
|
|
178
183
|
*/
|
|
179
184
|
tabColor: Color | undefined;
|
|
185
|
+
/**
|
|
186
|
+
* The sheet's VBA identity (`<sheetPr codeName>`), the name a macro means by `Sheet1`. Undefined
|
|
187
|
+
* for a sheet in a workbook with no VBA project, which is what Excel writes for one.
|
|
188
|
+
*
|
|
189
|
+
* Preserved rather than modeled: nothing here reads it, but a `.xlsm` whose sheet code names are
|
|
190
|
+
* dropped on a round trip has had the binding between its macros and its sheets cut. Deliberately
|
|
191
|
+
* absent from {@link WorksheetModel}, which is the copy shape: a code name identifies *this* sheet
|
|
192
|
+
* to the workbook's VBA project, so copying it onto a second sheet would give the project two
|
|
193
|
+
* sheets answering to one name.
|
|
194
|
+
*/
|
|
195
|
+
codeName?: string;
|
|
180
196
|
/** Sheet-level format defaults. Mutate in place: `sheet.properties.defaultRowHeight = 20`. */
|
|
181
197
|
readonly properties: WorksheetProperties;
|
|
182
198
|
/**
|
|
@@ -267,6 +283,7 @@ export declare class Worksheet {
|
|
|
267
283
|
*
|
|
268
284
|
* @throws {SyntaxError} if the reference is unparseable, names another worksheet, or leaves an
|
|
269
285
|
* axis unbounded.
|
|
286
|
+
* @throws {AuthoringError} if the numeric form is called with fewer than four corners.
|
|
270
287
|
* @throws {RangeError} if a numeric corner is not a positive integer within the sheet's bounds.
|
|
271
288
|
*/
|
|
272
289
|
getRange(reference: string): Range;
|
|
@@ -512,6 +529,9 @@ export declare class Worksheet {
|
|
|
512
529
|
* shift with the rows they cover.
|
|
513
530
|
*
|
|
514
531
|
* @throws {RangeError} if `start` is not a positive integer or `count` is negative.
|
|
532
|
+
* @throws {RangeError} if an inserted row would land past the last row of the grid. The sheet is
|
|
533
|
+
* left untouched, so this is a refused edit rather than half of one: a region pushed off the edge
|
|
534
|
+
* clamps and absorbs the loss, but content pushed off it is what Excel refuses outright.
|
|
515
535
|
*/
|
|
516
536
|
spliceRows(start: number, count: number, ...inserts: RowInput[]): void;
|
|
517
537
|
/**
|
|
@@ -577,6 +597,10 @@ export declare class Worksheet {
|
|
|
577
597
|
* indexed by row (index 0 → row 1); an empty array inserts a blank column.
|
|
578
598
|
*
|
|
579
599
|
* @throws {RangeError} if `start` is not a positive integer or `count` is negative.
|
|
600
|
+
* @throws {RangeError} if an inserted column would land past the last column, or one of its values
|
|
601
|
+
* past the last row. The sheet is left untouched, so this is a refused edit rather than half of
|
|
602
|
+
* one: a region pushed off the edge clamps and absorbs the loss, but content pushed off it is
|
|
603
|
+
* what Excel refuses outright, and {@link addColumn} refuses the same argument identically.
|
|
580
604
|
*/
|
|
581
605
|
spliceColumns(start: number, count: number, ...inserts: CellValue[][]): void;
|
|
582
606
|
/**
|
|
@@ -584,7 +608,8 @@ export declare class Worksheet {
|
|
|
584
608
|
* by one. `values` is an array of values indexed by row (index 0 → row 1), like
|
|
585
609
|
* {@link addColumn}. Shorthand for {@link spliceColumns}`(pos, 0, values)`.
|
|
586
610
|
*
|
|
587
|
-
* @throws {RangeError} if `pos` is not a positive integer
|
|
611
|
+
* @throws {RangeError} if `pos` is not a positive integer, or if the column would land past the
|
|
612
|
+
* last column or one of its values past the last row; see {@link spliceColumns}.
|
|
588
613
|
*/
|
|
589
614
|
insertColumn(pos: number, values: CellValue[]): void;
|
|
590
615
|
/**
|
|
@@ -693,18 +718,42 @@ export interface WorksheetInternals {
|
|
|
693
718
|
*/
|
|
694
719
|
cellAt(row: number, col: number): Cell;
|
|
695
720
|
/**
|
|
696
|
-
* The
|
|
721
|
+
* The cell materialised at a position, or `undefined` when nothing has been written there.
|
|
722
|
+
*
|
|
723
|
+
* Merge-blind and non-materialising, which is what separates it from `Worksheet.getCell`: that
|
|
724
|
+
* resolves a covered address to its merge master, so `hasCell(row, col)` followed by a `getCell` of
|
|
725
|
+
* the same position can hand back a *different* cell. A caller walking a rectangle got the master
|
|
726
|
+
* once per covered position and never saw the covered cells at all, which made a `clearStyle` over a
|
|
727
|
+
* merge clear the master repeatedly and the covered cells not once. A caller that wants merge
|
|
728
|
+
* resolution keeps `getCell`; a caller enumerating what is actually stored wants this.
|
|
729
|
+
*/
|
|
730
|
+
peekCell(row: number, col: number): Cell | undefined;
|
|
731
|
+
/**
|
|
732
|
+
* {@link cellAt} with merge resolution: the cell a write to this position lands on, materialised.
|
|
733
|
+
*
|
|
734
|
+
* What {@link Worksheet.getCell} does, minus the address. `getCell` is the public spelling and takes
|
|
735
|
+
* an A1 reference, so a caller already holding a row and a column had to encode one and have it
|
|
736
|
+
* decoded straight back. That round-trip costs about three times a positional read, and a
|
|
737
|
+
* {@link Range} write performs one per cell: styling a 100x100 block spent 10,000 encodes and 10,000
|
|
738
|
+
* regex decodes on positions it already had.
|
|
739
|
+
*/
|
|
740
|
+
masterAt(row: number, col: number): Cell;
|
|
741
|
+
/**
|
|
742
|
+
* The store behind a {@link Row} or {@link Column} handle. These exist because the handles are
|
|
697
743
|
* views rather than records: they hold a sheet and a position, and every read and write goes
|
|
698
744
|
* through here to the one authoritative map. `…PropertiesOf` never fabricates, so reading a row
|
|
699
745
|
* cannot extend the used range; `ensure…` is what a write calls, so the record appears exactly
|
|
700
|
-
* when a value is set
|
|
746
|
+
* when a value is set; `drop…` is what clearing the last field calls, so the record disappears
|
|
747
|
+
* exactly when the line stops being formatted, which is what keeps the used range honest.
|
|
701
748
|
*/
|
|
702
749
|
rowPropertiesOf(number: number): RowProperties | undefined;
|
|
703
750
|
ensureRowProperties(number: number): RowProperties;
|
|
751
|
+
dropRowProperties(number: number): void;
|
|
704
752
|
/** The row's materialised cells in ascending column order. */
|
|
705
753
|
rowCells(number: number): Cell[];
|
|
706
754
|
columnPropertiesOf(index: number): ColumnProperties | undefined;
|
|
707
755
|
ensureColumnProperties(index: number): ColumnProperties;
|
|
756
|
+
dropColumnProperties(index: number): void;
|
|
708
757
|
/** The column's materialised cells in ascending row order. */
|
|
709
758
|
columnCells(index: number): Cell[];
|
|
710
759
|
}
|
package/dist/core/worksheet.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AuthoringError } from '../errors.js';
|
|
2
2
|
import { tokenSet } from '../token-set.js';
|
|
3
|
-
import {
|
|
3
|
+
import { assertAxisInBounds, decodeCellRef, encodeAddress, tryDecodeCellRef } from './address.js';
|
|
4
4
|
import { canonicalizeAutoFilter } from './autofilter.js';
|
|
5
5
|
import { applyCellStyle, Cell, copyCellContent } from './cell.js';
|
|
6
6
|
import { Column } from './column.js';
|
|
@@ -8,7 +8,6 @@ import { ConditionalFormattingOverlay } from './conditional-formatting-overlay.j
|
|
|
8
8
|
import { DataValidationOverlay } from './data-validation-overlay.js';
|
|
9
9
|
import { GridEdits } from './grid-edits.js';
|
|
10
10
|
import { INTERNAL } from './internal.js';
|
|
11
|
-
import { MergeIndex } from './merge-index.js';
|
|
12
11
|
import { clearCoveredValues } from './merge.js';
|
|
13
12
|
import { PivotTable } from './pivot-table.js';
|
|
14
13
|
import { deriveCredential, } from './protection.js';
|
|
@@ -18,6 +17,7 @@ import { Row } from './row.js';
|
|
|
18
17
|
import { Table } from './table.js';
|
|
19
18
|
import { UsedExtent } from './used-extent.js';
|
|
20
19
|
import { WorksheetComments } from './worksheet-comments.js';
|
|
20
|
+
import { WorksheetMerges } from './worksheet-merges.js';
|
|
21
21
|
import { WORKSHEET_MODEL_FACETS } from './worksheet-model.js';
|
|
22
22
|
import { WorksheetPictures } from './worksheet-pictures.js';
|
|
23
23
|
export const isVisibility = tokenSet({ visible: true, hidden: true, veryHidden: true });
|
|
@@ -26,6 +26,7 @@ export class Worksheet {
|
|
|
26
26
|
id;
|
|
27
27
|
state;
|
|
28
28
|
tabColor;
|
|
29
|
+
codeName;
|
|
29
30
|
properties = {};
|
|
30
31
|
outline = {};
|
|
31
32
|
view = {};
|
|
@@ -42,37 +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
57
|
#extent;
|
|
58
|
-
#mergeIndex;
|
|
59
58
|
constructor(name, id, state = 'visible') {
|
|
60
59
|
this.name = name;
|
|
61
60
|
this.id = id;
|
|
62
61
|
this.state = state;
|
|
63
|
-
this.#mergeIndex = new MergeIndex(this.#mergeRects);
|
|
64
62
|
this.#extent = new UsedExtent({
|
|
65
63
|
rows: this.#rows,
|
|
66
64
|
rowProperties: this.#rowProperties,
|
|
67
65
|
columns: this.#columns,
|
|
68
|
-
mergeRects: this.#
|
|
66
|
+
mergeRects: this.#merges.rects,
|
|
69
67
|
});
|
|
70
68
|
this.#edits = new GridEdits({
|
|
71
69
|
rows: this.#rows,
|
|
72
70
|
rowProperties: this.#rowProperties,
|
|
73
71
|
columns: this.#columns,
|
|
74
72
|
merges: this.#merges,
|
|
75
|
-
mergeRects: this.#mergeRects,
|
|
76
73
|
tables: this.#tables,
|
|
77
74
|
images: this.#images.anchors,
|
|
78
75
|
dataValidations: this.#dataValidations,
|
|
@@ -88,8 +85,7 @@ export class Worksheet {
|
|
|
88
85
|
}
|
|
89
86
|
getCell(reference) {
|
|
90
87
|
const { col, row } = decodeCellRef(reference);
|
|
91
|
-
|
|
92
|
-
return this.#cellAt(master.row, master.col);
|
|
88
|
+
return this[INTERNAL].masterAt(row, col);
|
|
93
89
|
}
|
|
94
90
|
hasCell(row, col) {
|
|
95
91
|
return this.#rows.get(row)?.has(col) ?? false;
|
|
@@ -103,7 +99,11 @@ export class Worksheet {
|
|
|
103
99
|
getRange(referenceOrTop, left, bottom, right) {
|
|
104
100
|
if (typeof referenceOrTop === 'string')
|
|
105
101
|
return rangeFrom(this, referenceOrTop);
|
|
106
|
-
|
|
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);
|
|
107
107
|
}
|
|
108
108
|
get rowCount() {
|
|
109
109
|
return this.#extent.lastRow;
|
|
@@ -209,21 +209,14 @@ export class Worksheet {
|
|
|
209
209
|
return this.#preservedReferences;
|
|
210
210
|
}
|
|
211
211
|
mergeCells(range) {
|
|
212
|
-
const
|
|
213
|
-
if (
|
|
214
|
-
const rect = { top, left, bottom, right };
|
|
215
|
-
if (this.#mergeIndex.overlapping(rect) !== undefined) {
|
|
216
|
-
throw new AuthoringError(`merged range "${range}" overlaps an existing merged region`);
|
|
217
|
-
}
|
|
218
|
-
this.#mergeRects.push(rect);
|
|
219
|
-
this.#mergeIndex.note(rect);
|
|
212
|
+
const rect = this.#merges.add(range);
|
|
213
|
+
if (rect !== undefined) {
|
|
220
214
|
this.#extent.noteMerge(rect);
|
|
221
215
|
clearCoveredValues(this.#rows, rect);
|
|
222
216
|
}
|
|
223
|
-
this.#merges.push(range);
|
|
224
217
|
}
|
|
225
218
|
get merges() {
|
|
226
|
-
return this.#merges;
|
|
219
|
+
return this.#merges.ranges;
|
|
227
220
|
}
|
|
228
221
|
get autoFilter() {
|
|
229
222
|
return this.#autoFilter;
|
|
@@ -232,20 +225,10 @@ export class Worksheet {
|
|
|
232
225
|
this.#autoFilter = filter === undefined ? undefined : canonicalizeAutoFilter(filter);
|
|
233
226
|
}
|
|
234
227
|
unmergeCells(range) {
|
|
235
|
-
const
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const { top, left, bottom, right } = decodeRange(range);
|
|
240
|
-
if (top !== undefined && left !== undefined && bottom !== undefined && right !== undefined) {
|
|
241
|
-
const rectIndex = this.#mergeRects.findIndex((r) => r.top === top && r.left === left && r.bottom === bottom && r.right === right);
|
|
242
|
-
if (rectIndex !== -1) {
|
|
243
|
-
this.#mergeRects.splice(rectIndex, 1);
|
|
244
|
-
this.#mergeIndex.invalidate();
|
|
245
|
-
this.#extent.invalidate();
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
return true;
|
|
228
|
+
const { existed, rectsChanged } = this.#merges.remove(range);
|
|
229
|
+
if (rectsChanged)
|
|
230
|
+
this.#extent.invalidate();
|
|
231
|
+
return existed;
|
|
249
232
|
}
|
|
250
233
|
addDataValidation(sqref, rule, options = {}) {
|
|
251
234
|
this.#dataValidations.add(sqref, rule, options);
|
|
@@ -267,7 +250,7 @@ export class Worksheet {
|
|
|
267
250
|
assertStartAndCount('splice', 'row', start, count);
|
|
268
251
|
const inserted = inserts.map((values, i) => buildRowCells(start + i, values, this.#columns));
|
|
269
252
|
this.#edits.spliceRows(start, count, inserted);
|
|
270
|
-
this.#
|
|
253
|
+
this.#merges.invalidate();
|
|
271
254
|
this.#extent.invalidate();
|
|
272
255
|
}
|
|
273
256
|
insertRow(pos, values) {
|
|
@@ -331,7 +314,7 @@ export class Worksheet {
|
|
|
331
314
|
if (insert) {
|
|
332
315
|
const copies = Array.from({ length: count }, () => snapshot(start));
|
|
333
316
|
this.#edits.spliceRows(start + 1, 0, copies);
|
|
334
|
-
this.#
|
|
317
|
+
this.#merges.invalidate();
|
|
335
318
|
}
|
|
336
319
|
else {
|
|
337
320
|
for (let i = 1; i <= count; i++)
|
|
@@ -344,7 +327,7 @@ export class Worksheet {
|
|
|
344
327
|
spliceColumns(start, count, ...inserts) {
|
|
345
328
|
assertStartAndCount('splice', 'column', start, count);
|
|
346
329
|
this.#edits.spliceColumns(start, count, inserts);
|
|
347
|
-
this.#
|
|
330
|
+
this.#merges.invalidate();
|
|
348
331
|
this.#extent.invalidate();
|
|
349
332
|
}
|
|
350
333
|
insertColumn(pos, values) {
|
|
@@ -374,12 +357,10 @@ 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;
|
|
382
|
-
this.#mergeIndex.invalidate();
|
|
383
364
|
this.#extent.reset();
|
|
384
365
|
}
|
|
385
366
|
set model(model) {
|
|
@@ -436,6 +417,11 @@ export class Worksheet {
|
|
|
436
417
|
this.#protection = protection;
|
|
437
418
|
},
|
|
438
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),
|
|
439
425
|
rowPropertiesOf: (number) => this.#rowProperties.get(number),
|
|
440
426
|
ensureRowProperties: (number) => {
|
|
441
427
|
let properties = this.#rowProperties.get(number);
|
|
@@ -446,6 +432,10 @@ export class Worksheet {
|
|
|
446
432
|
this.#extent.noteDeclaredRow(number);
|
|
447
433
|
return properties;
|
|
448
434
|
},
|
|
435
|
+
dropRowProperties: (number) => {
|
|
436
|
+
if (this.#rowProperties.delete(number))
|
|
437
|
+
this.#extent.invalidate();
|
|
438
|
+
},
|
|
449
439
|
rowCells: (number) => {
|
|
450
440
|
const cols = this.#rows.get(number);
|
|
451
441
|
return cols ? [...cols].sort(([a], [b]) => a - b).map(([, cell]) => cell) : [];
|
|
@@ -460,6 +450,10 @@ export class Worksheet {
|
|
|
460
450
|
this.#extent.noteDeclaredColumn(index);
|
|
461
451
|
return properties;
|
|
462
452
|
},
|
|
453
|
+
dropColumnProperties: (index) => {
|
|
454
|
+
if (this.#columns.delete(index))
|
|
455
|
+
this.#extent.invalidate();
|
|
456
|
+
},
|
|
463
457
|
columnCells: (index) => {
|
|
464
458
|
const cells = [];
|
|
465
459
|
for (const number of [...this.#rows.keys()].sort((a, b) => a - b)) {
|
|
@@ -472,9 +466,7 @@ export class Worksheet {
|
|
|
472
466
|
};
|
|
473
467
|
}
|
|
474
468
|
function assertStartAndCount(verb, axis, start, count) {
|
|
475
|
-
|
|
476
|
-
throw new RangeError(`${verb} start ${start} is out of bounds: ${axis}s start at 1`);
|
|
477
|
-
}
|
|
469
|
+
assertAxisInBounds(axis, start);
|
|
478
470
|
if (!Number.isInteger(count) || count < 0) {
|
|
479
471
|
throw new RangeError(`${verb} count ${count} is invalid: it must be a non-negative integer`);
|
|
480
472
|
}
|
package/dist/customui/ribbon.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { strFromU8 } from 'fflate';
|
|
2
|
+
import { isRelType } from '../rel-type.js';
|
|
2
3
|
import { tokenSet } from '../token-set.js';
|
|
3
4
|
import { boolStrict, localName, xmlEvents } from '../xml/xml-scan.js';
|
|
4
5
|
import { CustomUiParseError } from './errors.js';
|
|
@@ -7,7 +8,7 @@ export const CUSTOMUI_2009_NAMESPACE = 'http://schemas.microsoft.com/office/2009
|
|
|
7
8
|
export const CUSTOMUI_2007_REL_TYPE = 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility';
|
|
8
9
|
export const CUSTOMUI_2010_REL_TYPE = 'http://schemas.microsoft.com/office/2007/relationships/ui/extensibility';
|
|
9
10
|
export function isCustomUiRelType(type) {
|
|
10
|
-
return type
|
|
11
|
+
return isRelType(type, 'ui/extensibility');
|
|
11
12
|
}
|
|
12
13
|
const MAX_DEPTH = 256;
|
|
13
14
|
const isKnownControlKind = tokenSet({
|
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;
|