@shbernal/ts-xlsx 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -24
- package/dist/bytes.d.ts +10 -2
- package/dist/bytes.js +22 -0
- package/dist/core/address.d.ts +96 -2
- package/dist/core/address.js +87 -33
- package/dist/core/array-formula-ranges.d.ts +33 -0
- package/dist/core/array-formula-ranges.js +62 -0
- package/dist/core/autofilter.d.ts +4 -3
- package/dist/core/autofilter.js +31 -30
- package/dist/core/axis-handle.d.ts +2 -0
- package/dist/core/axis-handle.js +5 -2
- package/dist/core/cell.d.ts +4 -3
- package/dist/core/cell.js +4 -6
- package/dist/core/clone.d.ts +29 -0
- package/dist/core/clone.js +24 -0
- package/dist/core/color-resolution.js +4 -6
- package/dist/core/column.d.ts +1 -0
- package/dist/core/column.js +6 -2
- package/dist/core/comment-thread.d.ts +7 -3
- package/dist/core/comment-thread.js +2 -1
- package/dist/core/conditional-formatting-overlay.d.ts +11 -1
- package/dist/core/conditional-formatting-overlay.js +30 -3
- package/dist/core/conditional-formatting.d.ts +107 -11
- package/dist/core/conditional-formatting.js +76 -19
- package/dist/core/containers.d.ts +12 -0
- package/dist/core/containers.js +5 -0
- package/dist/core/data-validation-overlay.d.ts +7 -1
- package/dist/core/data-validation-overlay.js +19 -4
- package/dist/core/data-validation.d.ts +22 -0
- package/dist/core/data-validation.js +30 -4
- package/dist/core/date-format.d.ts +20 -0
- package/dist/core/date-format.js +170 -0
- package/dist/core/date.d.ts +43 -8
- package/dist/core/date.js +19 -3
- package/dist/core/formula-references.d.ts +26 -0
- package/dist/core/formula-references.js +173 -0
- package/dist/core/formula-scan.d.ts +2 -0
- package/dist/core/formula-scan.js +58 -0
- package/dist/core/formula.d.ts +76 -17
- package/dist/core/formula.js +87 -80
- package/dist/core/function-values.d.ts +4 -0
- package/dist/core/function-values.js +58 -0
- package/dist/core/future-functions.d.ts +3 -0
- package/dist/core/{modern-functions.js → future-functions.js} +119 -88
- package/dist/core/grid-edits.d.ts +30 -3
- package/dist/core/grid-edits.js +248 -81
- package/dist/core/grid-shift.d.ts +58 -9
- package/dist/core/grid-shift.js +26 -4
- package/dist/core/hyperlink.d.ts +39 -0
- package/dist/core/hyperlink.js +88 -0
- package/dist/core/image.d.ts +49 -14
- package/dist/core/image.js +16 -5
- package/dist/core/internal.d.ts +10 -2
- package/dist/core/limits.d.ts +25 -0
- package/dist/core/limits.js +4 -0
- package/dist/core/merge.d.ts +18 -4
- package/dist/core/merge.js +33 -20
- package/dist/core/page-setup.d.ts +26 -11
- package/dist/core/pivot-table.d.ts +49 -10
- package/dist/core/pivot-table.js +112 -60
- package/dist/core/protection.d.ts +66 -4
- package/dist/core/protection.js +6 -11
- package/dist/core/range.js +34 -30
- package/dist/core/row-input.js +2 -2
- package/dist/core/row.d.ts +1 -0
- package/dist/core/row.js +6 -2
- package/dist/core/structured-reference.d.ts +7 -0
- package/dist/core/structured-reference.js +7 -0
- package/dist/core/style.d.ts +85 -70
- package/dist/core/style.js +92 -28
- package/dist/core/table-style.d.ts +1 -1
- package/dist/core/table-style.js +4 -4
- package/dist/core/table.d.ts +64 -16
- package/dist/core/table.js +87 -40
- package/dist/core/theme.d.ts +2 -0
- package/dist/core/theme.js +9 -5
- package/dist/core/value.d.ts +60 -28
- package/dist/core/value.js +48 -43
- package/dist/core/workbook-media.d.ts +34 -0
- package/dist/core/workbook-media.js +44 -0
- package/dist/core/workbook-styles.d.ts +83 -1
- package/dist/core/workbook-styles.js +4 -0
- package/dist/core/workbook-theme.js +5 -3
- package/dist/core/workbook-vba.js +3 -2
- package/dist/core/workbook.d.ts +41 -3
- package/dist/core/workbook.js +46 -41
- package/dist/core/worksheet-comments.d.ts +2 -1
- package/dist/core/worksheet-comments.js +20 -13
- package/dist/core/worksheet-merges.d.ts +49 -0
- package/dist/core/worksheet-merges.js +65 -0
- package/dist/core/worksheet-model.d.ts +10 -2
- package/dist/core/worksheet-model.js +28 -9
- package/dist/core/worksheet-pictures.d.ts +3 -3
- package/dist/core/worksheet-pictures.js +7 -6
- package/dist/core/worksheet.d.ts +165 -27
- package/dist/core/worksheet.js +206 -89
- package/dist/customui/ribbon.js +2 -1
- package/dist/entries/core.d.ts +21 -14
- package/dist/entries/core.js +14 -7
- package/dist/entries/errors.d.ts +1 -0
- package/dist/entries/errors.js +1 -0
- package/dist/entries/xlsx.d.ts +1 -1
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +22 -0
- package/dist/hex.d.ts +8 -0
- package/dist/hex.js +3 -0
- package/dist/io/cell-metadata/metadata.d.ts +42 -0
- package/dist/io/cell-metadata/metadata.js +35 -0
- package/dist/io/cell-metadata/rich-values.d.ts +11 -0
- package/dist/io/cell-metadata/rich-values.js +80 -0
- package/dist/io/csv/delimiter.d.ts +21 -0
- package/dist/io/csv/delimiter.js +18 -0
- package/dist/io/csv/errors.d.ts +14 -0
- package/dist/io/csv/errors.js +5 -0
- package/dist/io/csv/read.d.ts +6 -1
- package/dist/io/csv/read.js +51 -22
- package/dist/io/csv/write.d.ts +19 -5
- package/dist/io/csv/write.js +24 -44
- package/dist/io/opc/inflate.js +14 -0
- package/dist/io/opc/namespaces.d.ts +16 -0
- package/dist/io/opc/namespaces.js +4 -0
- package/dist/io/opc/part-paths.d.ts +9 -0
- package/dist/io/opc/part-paths.js +5 -5
- package/dist/io/opc/read-opc.d.ts +58 -14
- package/dist/io/opc/read-opc.js +49 -21
- package/dist/io/opc/read-options.d.ts +5 -1
- package/dist/io/opc/sniff-format.d.ts +3 -3
- package/dist/io/opc/sniff-format.js +2 -2
- package/dist/io/opc/strict-relationships.d.ts +2 -0
- package/dist/io/opc/strict-relationships.js +12 -0
- package/dist/io/read-policy/column-budget.d.ts +26 -0
- package/dist/io/read-policy/column-budget.js +18 -0
- package/dist/io/read-policy/read-repair.d.ts +74 -0
- package/dist/io/read-policy/read-repair.js +119 -0
- package/dist/io/style/cell-style-resolution.d.ts +25 -0
- package/dist/io/style/cell-style-resolution.js +30 -0
- package/dist/io/style/xf-style.d.ts +23 -1
- package/dist/io/style/xf-style.js +8 -0
- package/dist/io/xlsb/formula.d.ts +2 -2
- package/dist/io/xlsb/formula.js +52 -35
- package/dist/io/xlsb/primitives.js +8 -14
- package/dist/io/xlsb/ptg-functions.d.ts +19 -10
- package/dist/io/xlsb/ptg-functions.js +495 -596
- package/dist/io/xlsb/read-metadata.d.ts +7 -0
- package/dist/io/xlsb/read-metadata.js +69 -0
- package/dist/io/xlsb/read-styles.js +45 -81
- package/dist/io/xlsb/read-worksheet.d.ts +26 -1
- package/dist/io/xlsb/read-worksheet.js +148 -106
- package/dist/io/xlsb/read.d.ts +6 -3
- package/dist/io/xlsb/read.js +70 -31
- package/dist/io/xlsb/record-stream.d.ts +30 -0
- package/dist/io/xlsb/record-stream.js +20 -0
- package/dist/io/xlsb/record-types.d.ts +14 -5
- package/dist/io/xlsb/record-types.js +14 -5
- package/dist/io/xlsb/sheet-protection.d.ts +20 -0
- package/dist/io/xlsb/sheet-protection.js +60 -0
- package/dist/io/xlsx/cell-accumulator.d.ts +24 -9
- package/dist/io/xlsx/cell-accumulator.js +74 -21
- package/dist/io/xlsx/cell-metadata.d.ts +39 -0
- package/dist/io/xlsx/cell-metadata.js +162 -0
- package/dist/io/xlsx/cell-value.d.ts +19 -5
- package/dist/io/xlsx/cell-value.js +45 -30
- package/dist/io/xlsx/color-xml.js +3 -2
- package/dist/io/xlsx/column-span.d.ts +11 -0
- package/dist/io/xlsx/column-span.js +9 -0
- package/dist/io/xlsx/comments.d.ts +9 -30
- package/dist/io/xlsx/comments.js +25 -83
- package/dist/io/xlsx/conditional-formatting.d.ts +43 -23
- package/dist/io/xlsx/conditional-formatting.js +437 -138
- package/dist/io/xlsx/data-validation.d.ts +12 -7
- package/dist/io/xlsx/data-validation.js +67 -53
- package/dist/io/xlsx/edit-vba.d.ts +7 -2
- package/dist/io/xlsx/edit-vba.js +52 -52
- package/dist/io/xlsx/font-xml.d.ts +7 -0
- package/dist/io/xlsx/font-xml.js +104 -0
- package/dist/io/xlsx/hyperlinks.d.ts +19 -21
- package/dist/io/xlsx/hyperlinks.js +12 -32
- package/dist/io/xlsx/images.d.ts +49 -16
- package/dist/io/xlsx/images.js +149 -50
- package/dist/io/xlsx/namespaces.d.ts +24 -0
- package/dist/io/xlsx/namespaces.js +11 -0
- package/dist/io/xlsx/package-plan.d.ts +60 -15
- package/dist/io/xlsx/package-plan.js +83 -18
- package/dist/io/xlsx/part-names.d.ts +6 -8
- package/dist/io/xlsx/part-names.js +3 -7
- package/dist/io/xlsx/pivot.d.ts +5 -5
- package/dist/io/xlsx/pivot.js +26 -24
- package/dist/io/xlsx/preserved-splices.d.ts +6 -0
- package/dist/io/xlsx/preserved-splices.js +74 -0
- package/dist/io/xlsx/read-comments.d.ts +29 -0
- package/dist/io/xlsx/read-comments.js +75 -0
- package/dist/io/xlsx/read-parts.d.ts +59 -0
- package/dist/io/xlsx/read-parts.js +259 -0
- package/dist/io/xlsx/read-pivot.js +11 -4
- package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +8 -5
- package/dist/io/xlsx/{rich-runs.js → read-rich-runs.js} +24 -4
- package/dist/io/xlsx/read-rows.d.ts +35 -11
- package/dist/io/xlsx/read-rows.js +73 -49
- package/dist/io/xlsx/read-shared-strings.js +3 -2
- package/dist/io/xlsx/read-styles.d.ts +0 -30
- package/dist/io/xlsx/read-styles.js +45 -105
- package/dist/io/xlsx/read-workbook-xml.d.ts +42 -0
- package/dist/io/xlsx/read-workbook-xml.js +175 -0
- package/dist/io/xlsx/read-worksheet.d.ts +9 -3
- package/dist/io/xlsx/read-worksheet.js +70 -177
- package/dist/io/xlsx/read.d.ts +3 -14
- package/dist/io/xlsx/read.js +74 -411
- package/dist/io/xlsx/relationships.d.ts +3 -0
- package/dist/io/xlsx/relationships.js +4 -0
- package/dist/io/xlsx/rich-text.js +1 -1
- package/dist/io/xlsx/row-position.d.ts +20 -0
- package/dist/io/xlsx/row-position.js +11 -0
- package/dist/io/xlsx/row-xml.d.ts +139 -0
- package/dist/io/xlsx/row-xml.js +222 -0
- package/dist/io/xlsx/shared-formulas.js +2 -2
- package/dist/io/xlsx/sheet-properties.d.ts +10 -1
- package/dist/io/xlsx/sheet-properties.js +182 -20
- package/dist/io/xlsx/strict-parts.d.ts +7 -0
- package/dist/io/xlsx/strict-parts.js +171 -0
- package/dist/io/xlsx/style-elements.d.ts +41 -0
- package/dist/io/xlsx/style-elements.js +136 -0
- package/dist/io/xlsx/styles.d.ts +17 -3
- package/dist/io/xlsx/styles.js +13 -209
- package/dist/io/xlsx/tables.d.ts +10 -2
- package/dist/io/xlsx/tables.js +55 -52
- package/dist/io/xlsx/theme-xml.d.ts +32 -4
- package/dist/io/xlsx/theme-xml.js +106 -71
- package/dist/io/xlsx/threaded-comments.d.ts +14 -11
- package/dist/io/xlsx/threaded-comments.js +16 -8
- package/dist/io/xlsx/workbook-xml.d.ts +45 -6
- package/dist/io/xlsx/workbook-xml.js +62 -54
- package/dist/io/xlsx/worksheet-xml.d.ts +26 -70
- package/dist/io/xlsx/worksheet-xml.js +69 -282
- package/dist/io/xlsx/write-stream.d.ts +90 -19
- package/dist/io/xlsx/write-stream.js +80 -25
- package/dist/io/xlsx/write.d.ts +12 -6
- package/dist/io/xlsx/write.js +226 -123
- package/dist/rel-type.d.ts +25 -0
- package/dist/rel-type.js +9 -0
- package/dist/token-set.d.ts +13 -0
- package/dist/token-set.js +4 -1
- package/dist/vba/bytes.d.ts +16 -5
- package/dist/vba/bytes.js +27 -6
- package/dist/vba/cfb-format.d.ts +55 -0
- package/dist/vba/cfb-format.js +35 -0
- package/dist/vba/cfb-writer.d.ts +8 -0
- package/dist/vba/cfb-writer.js +40 -40
- package/dist/vba/cfb.d.ts +21 -4
- package/dist/vba/cfb.js +124 -90
- package/dist/vba/codepage.js +2 -1
- package/dist/vba/dir-records.d.ts +6 -0
- package/dist/vba/dir-records.js +10 -2
- package/dist/vba/errors.d.ts +11 -4
- package/dist/vba/index.d.ts +0 -2
- package/dist/vba/index.js +0 -2
- package/dist/vba/ms-ovba.d.ts +6 -2
- package/dist/vba/ms-ovba.js +66 -22
- package/dist/vba/project-editor.js +129 -119
- package/dist/vba/project.d.ts +15 -1
- package/dist/vba/project.js +38 -13
- package/dist/vba/vba-encoding.d.ts +4 -10
- package/dist/vba/vba-encoding.js +3 -17
- package/dist/xml/xml-attrs.d.ts +37 -0
- package/dist/xml/xml-attrs.js +30 -0
- package/dist/xml/xml-chars.d.ts +40 -0
- package/dist/xml/xml-chars.js +12 -0
- package/dist/xml/xml-namespaces.d.ts +31 -0
- package/dist/xml/xml-namespaces.js +50 -0
- package/dist/xml/xml-read.d.ts +101 -11
- package/dist/xml/xml-read.js +150 -18
- package/dist/xml/xml-scan.d.ts +25 -34
- package/dist/xml/xml-scan.js +69 -46
- package/dist/xml/xml.d.ts +59 -26
- package/dist/xml/xml.js +45 -23
- package/package.json +15 -9
- package/skills/ts-xlsx-upstream/SKILL.md +21 -13
- package/dist/core/modern-functions.d.ts +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type WorkbookMetadata } from '../cell-metadata/metadata.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Read `xl/metadata.bin` as far as a cell's metadata indices reach into it.
|
|
4
|
+
*
|
|
5
|
+
* @throws {XlsbParseError} if a record the model reads is shorter than its fields.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseMetadataPart(part: Uint8Array | undefined): WorkbookMetadata;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { DYNAMIC_ARRAY_TYPE, NO_METADATA, RICH_VALUE_TYPE, } from '../cell-metadata/metadata.js';
|
|
2
|
+
import { RecordReader } from './primitives.js';
|
|
3
|
+
import { readRecords } from './record-stream.js';
|
|
4
|
+
import { BRT } from './record-types.js';
|
|
5
|
+
export function parseMetadataPart(part) {
|
|
6
|
+
if (part === undefined)
|
|
7
|
+
return NO_METADATA;
|
|
8
|
+
const typeNames = [];
|
|
9
|
+
const dynamicArrayBlocks = [];
|
|
10
|
+
const richValueBlocks = [];
|
|
11
|
+
const cellBlocks = [];
|
|
12
|
+
const valueBlocks = [];
|
|
13
|
+
let futureType;
|
|
14
|
+
let blocks;
|
|
15
|
+
for (const record of readRecords(part)) {
|
|
16
|
+
const reader = new RecordReader(record.data);
|
|
17
|
+
switch (record.type) {
|
|
18
|
+
case BRT.Mdtinfo:
|
|
19
|
+
reader.skip(8);
|
|
20
|
+
typeNames.push(reader.wideString());
|
|
21
|
+
break;
|
|
22
|
+
case BRT.BeginEsfmd:
|
|
23
|
+
reader.skip(4);
|
|
24
|
+
futureType = reader.wideString();
|
|
25
|
+
break;
|
|
26
|
+
case BRT.EndEsfmd:
|
|
27
|
+
futureType = undefined;
|
|
28
|
+
break;
|
|
29
|
+
case BRT.BeginFmd:
|
|
30
|
+
if (futureType === DYNAMIC_ARRAY_TYPE)
|
|
31
|
+
dynamicArrayBlocks.push(false);
|
|
32
|
+
else if (futureType === RICH_VALUE_TYPE)
|
|
33
|
+
richValueBlocks.push(-1);
|
|
34
|
+
break;
|
|
35
|
+
case BRT.DynamicArrayProperties:
|
|
36
|
+
if (futureType === DYNAMIC_ARRAY_TYPE && dynamicArrayBlocks.length > 0) {
|
|
37
|
+
dynamicArrayBlocks[dynamicArrayBlocks.length - 1] = (reader.u8() & 1) !== 0;
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
case BRT.RichValueBlock:
|
|
41
|
+
if (futureType === RICH_VALUE_TYPE && richValueBlocks.length > 0) {
|
|
42
|
+
reader.skip(4);
|
|
43
|
+
richValueBlocks[richValueBlocks.length - 1] = reader.u32();
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
case BRT.BeginEsmdb:
|
|
47
|
+
reader.skip(4);
|
|
48
|
+
blocks = (reader.u32() & 1) !== 0 ? cellBlocks : valueBlocks;
|
|
49
|
+
break;
|
|
50
|
+
case BRT.EndEsmdb:
|
|
51
|
+
blocks = undefined;
|
|
52
|
+
break;
|
|
53
|
+
case BRT.Mdb:
|
|
54
|
+
blocks?.push(metadataRecords(reader));
|
|
55
|
+
break;
|
|
56
|
+
default:
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { typeNames, dynamicArrayBlocks, richValueBlocks, cellBlocks, valueBlocks };
|
|
61
|
+
}
|
|
62
|
+
function metadataRecords(reader) {
|
|
63
|
+
const count = reader.u32();
|
|
64
|
+
const records = [];
|
|
65
|
+
while (records.length < count && reader.remaining >= 8) {
|
|
66
|
+
records.push({ type: reader.u32(), value: reader.u32() });
|
|
67
|
+
}
|
|
68
|
+
return records;
|
|
69
|
+
}
|
|
@@ -1,25 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ALIGNMENT_FACETS, FILL_PATTERNS_IN_SCHEMA_ORDER, } from '../../core/style.js';
|
|
2
|
+
import { numFmtCodeFor, NO_PRESERVED_STYLE_TABLES, protectionFrom, resolveStyleTable, } from '../style/xf-style.js';
|
|
2
3
|
import { RecordReader } from './primitives.js';
|
|
3
|
-
import { readRecords } from './record-stream.js';
|
|
4
|
+
import { blockTracker, readRecords } from './record-stream.js';
|
|
4
5
|
import { BRT } from './record-types.js';
|
|
5
|
-
const
|
|
6
|
-
[BRT.BeginFmts, 'fmts'],
|
|
7
|
-
[BRT.BeginFonts, 'fonts'],
|
|
8
|
-
[BRT.BeginFills, 'fills'],
|
|
9
|
-
[BRT.BeginBorders, 'borders'],
|
|
10
|
-
[BRT.BeginCellStyleXFs, 'cellStyleXfs'],
|
|
11
|
-
[BRT.BeginCellXFs, 'cellXfs'],
|
|
12
|
-
[BRT.BeginStyles, 'styles'],
|
|
13
|
-
]
|
|
14
|
-
const COLLECTION_ENDS = new Set([
|
|
15
|
-
BRT.EndFmts,
|
|
16
|
-
BRT.EndFonts,
|
|
17
|
-
BRT.EndFills,
|
|
18
|
-
BRT.EndBorders,
|
|
19
|
-
BRT.EndCellStyleXFs,
|
|
20
|
-
BRT.EndCellXFs,
|
|
21
|
-
BRT.EndStyles,
|
|
22
|
-
]);
|
|
6
|
+
const COLLECTIONS = [
|
|
7
|
+
[BRT.BeginFmts, BRT.EndFmts, 'fmts'],
|
|
8
|
+
[BRT.BeginFonts, BRT.EndFonts, 'fonts'],
|
|
9
|
+
[BRT.BeginFills, BRT.EndFills, 'fills'],
|
|
10
|
+
[BRT.BeginBorders, BRT.EndBorders, 'borders'],
|
|
11
|
+
[BRT.BeginCellStyleXFs, BRT.EndCellStyleXFs, 'cellStyleXfs'],
|
|
12
|
+
[BRT.BeginCellXFs, BRT.EndCellXFs, 'cellXfs'],
|
|
13
|
+
[BRT.BeginStyles, BRT.EndStyles, 'styles'],
|
|
14
|
+
];
|
|
23
15
|
export function parseStyleTable(part) {
|
|
24
16
|
if (part === undefined)
|
|
25
17
|
return { cellXfs: [], namedStyles: [], preserved: NO_PRESERVED_STYLE_TABLES };
|
|
@@ -30,43 +22,36 @@ export function parseStyleTable(part) {
|
|
|
30
22
|
const namedXfs = [];
|
|
31
23
|
const directXfs = [];
|
|
32
24
|
const labels = [];
|
|
33
|
-
|
|
25
|
+
const blocks = blockTracker(COLLECTIONS);
|
|
34
26
|
for (const record of readRecords(part)) {
|
|
35
|
-
if (
|
|
36
|
-
collection = undefined;
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
const started = COLLECTION_STARTS.get(record.type);
|
|
40
|
-
if (started !== undefined) {
|
|
41
|
-
collection = started;
|
|
27
|
+
if (blocks.boundary(record.type))
|
|
42
28
|
continue;
|
|
43
|
-
}
|
|
44
29
|
const reader = new RecordReader(record.data);
|
|
45
30
|
switch (record.type) {
|
|
46
31
|
case BRT.Fmt:
|
|
47
|
-
if (
|
|
32
|
+
if (blocks.isOpen('fmts'))
|
|
48
33
|
numFmtCodes.set(reader.u16(), reader.wideString());
|
|
49
34
|
break;
|
|
50
35
|
case BRT.Font:
|
|
51
|
-
if (
|
|
36
|
+
if (blocks.isOpen('fonts'))
|
|
52
37
|
fonts.push(readFont(reader));
|
|
53
38
|
break;
|
|
54
39
|
case BRT.Fill:
|
|
55
|
-
if (
|
|
40
|
+
if (blocks.isOpen('fills'))
|
|
56
41
|
fills.push(readFill(reader));
|
|
57
42
|
break;
|
|
58
43
|
case BRT.Border:
|
|
59
|
-
if (
|
|
44
|
+
if (blocks.isOpen('borders'))
|
|
60
45
|
borders.push(readBorder(reader));
|
|
61
46
|
break;
|
|
62
47
|
case BRT.XF:
|
|
63
|
-
if (
|
|
48
|
+
if (blocks.isOpen('cellXfs') || blocks.isOpen('cellStyleXfs')) {
|
|
64
49
|
const deps = { fonts, fills, borders, numFmtCodes };
|
|
65
|
-
(
|
|
50
|
+
(blocks.isOpen('cellXfs') ? directXfs : namedXfs).push(readXf(reader, deps, blocks.isOpen('cellXfs')));
|
|
66
51
|
}
|
|
67
52
|
break;
|
|
68
53
|
case BRT.Style:
|
|
69
|
-
if (
|
|
54
|
+
if (blocks.isOpen('styles'))
|
|
70
55
|
labels.push(readStyleLabel(reader));
|
|
71
56
|
break;
|
|
72
57
|
default:
|
|
@@ -110,34 +95,33 @@ function readXf(reader, deps, isDirect) {
|
|
|
110
95
|
return draft;
|
|
111
96
|
}
|
|
112
97
|
const NOT_A_CELL_XF = 0xffff;
|
|
98
|
+
const BIFF12_ALIGNMENT = {
|
|
99
|
+
horizontal: ({ flags }) => {
|
|
100
|
+
const value = HORIZONTAL_ALIGNMENTS[flags & 0b111];
|
|
101
|
+
return value === undefined ? {} : { horizontal: value };
|
|
102
|
+
},
|
|
103
|
+
vertical: ({ flags }) => {
|
|
104
|
+
const value = VERTICAL_ALIGNMENTS[(flags >> 3) & 0b111];
|
|
105
|
+
return value === undefined ? {} : { vertical: value };
|
|
106
|
+
},
|
|
107
|
+
textRotation: ({ rotation }) => (rotation === 0 ? {} : { textRotation: rotation }),
|
|
108
|
+
wrapText: ({ flags }) => ((flags & 0x0040) === 0 ? {} : { wrapText: true }),
|
|
109
|
+
indent: ({ indent }) => (indent === 0 ? {} : { indent }),
|
|
110
|
+
shrinkToFit: ({ flags }) => ((flags & 0x0100) === 0 ? {} : { shrinkToFit: true }),
|
|
111
|
+
readingOrder: ({ flags }) => {
|
|
112
|
+
const value = (flags >> 10) & 0b11;
|
|
113
|
+
return value === 0 ? {} : { readingOrder: value };
|
|
114
|
+
},
|
|
115
|
+
};
|
|
113
116
|
function readAlignment(flags, rotation, indent) {
|
|
117
|
+
const bits = { flags, rotation, indent };
|
|
114
118
|
const out = {};
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
out.horizontal = horizontal;
|
|
118
|
-
const vertical = VERTICAL_ALIGNMENTS[(flags >> 3) & 0b111];
|
|
119
|
-
if (vertical !== undefined)
|
|
120
|
-
out.vertical = vertical;
|
|
121
|
-
if (rotation !== 0)
|
|
122
|
-
out.textRotation = rotation;
|
|
123
|
-
if ((flags & 0x0040) !== 0)
|
|
124
|
-
out.wrapText = true;
|
|
125
|
-
if (indent !== 0)
|
|
126
|
-
out.indent = indent;
|
|
127
|
-
if ((flags & 0x0100) !== 0)
|
|
128
|
-
out.shrinkToFit = true;
|
|
129
|
-
const readingOrder = (flags >> 10) & 0b11;
|
|
130
|
-
if (readingOrder !== 0)
|
|
131
|
-
out.readingOrder = readingOrder;
|
|
119
|
+
for (const facet of ALIGNMENT_FACETS)
|
|
120
|
+
Object.assign(out, BIFF12_ALIGNMENT[facet.key](bits));
|
|
132
121
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
133
122
|
}
|
|
134
123
|
function readProtection(flags) {
|
|
135
|
-
|
|
136
|
-
if ((flags & 0x1000) === 0)
|
|
137
|
-
out.locked = false;
|
|
138
|
-
if ((flags & 0x2000) !== 0)
|
|
139
|
-
out.hidden = true;
|
|
140
|
-
return Object.keys(out).length > 0 ? out : undefined;
|
|
124
|
+
return protectionFrom({ locked: (flags & 0x1000) !== 0, hidden: (flags & 0x2000) !== 0 });
|
|
141
125
|
}
|
|
142
126
|
const HORIZONTAL_ALIGNMENTS = [
|
|
143
127
|
undefined,
|
|
@@ -208,7 +192,8 @@ const UNDERLINE_STYLES = new Map([
|
|
|
208
192
|
[0x22, 'doubleAccounting'],
|
|
209
193
|
]);
|
|
210
194
|
function readFill(reader) {
|
|
211
|
-
const
|
|
195
|
+
const raw = FILL_PATTERNS_IN_SCHEMA_ORDER[reader.u32()];
|
|
196
|
+
const pattern = raw === 'none' ? undefined : raw;
|
|
212
197
|
if (pattern === undefined)
|
|
213
198
|
return undefined;
|
|
214
199
|
const fgColor = notSentinel(reader.color(), AUTOMATIC_FOREGROUND);
|
|
@@ -225,27 +210,6 @@ const AUTOMATIC_BACKGROUND = 65;
|
|
|
225
210
|
function notSentinel(color, sentinel) {
|
|
226
211
|
return color?.indexed === sentinel ? undefined : color;
|
|
227
212
|
}
|
|
228
|
-
const FILL_PATTERNS = [
|
|
229
|
-
undefined,
|
|
230
|
-
'solid',
|
|
231
|
-
'mediumGray',
|
|
232
|
-
'darkGray',
|
|
233
|
-
'lightGray',
|
|
234
|
-
'darkHorizontal',
|
|
235
|
-
'darkVertical',
|
|
236
|
-
'darkDown',
|
|
237
|
-
'darkUp',
|
|
238
|
-
'darkGrid',
|
|
239
|
-
'darkTrellis',
|
|
240
|
-
'lightHorizontal',
|
|
241
|
-
'lightVertical',
|
|
242
|
-
'lightDown',
|
|
243
|
-
'lightUp',
|
|
244
|
-
'lightGrid',
|
|
245
|
-
'lightTrellis',
|
|
246
|
-
'gray125',
|
|
247
|
-
'gray0625',
|
|
248
|
-
];
|
|
249
213
|
function readBorder(reader) {
|
|
250
214
|
const flags = reader.u8();
|
|
251
215
|
const top = readEdge(reader);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { type DateEpoch } from '../../core/date.ts';
|
|
1
2
|
import type { Worksheet } from '../../core/worksheet.ts';
|
|
3
|
+
import type { CellMetadataIndex } from '../cell-metadata/metadata.ts';
|
|
2
4
|
import { type XfStyle } from '../style/xf-style.ts';
|
|
3
5
|
import { type FormulaScope } from './formula.ts';
|
|
4
6
|
/**
|
|
@@ -6,4 +8,27 @@ import { type FormulaScope } from './formula.ts';
|
|
|
6
8
|
* non-empty cell with the style its index resolves to in `xfStyles` and, for a formula cell, the text
|
|
7
9
|
* its token stream decodes to through `scope`.
|
|
8
10
|
*/
|
|
9
|
-
export declare function parseWorksheet(part: Uint8Array,
|
|
11
|
+
export declare function parseWorksheet(part: Uint8Array, context: WorksheetReadContext): void;
|
|
12
|
+
/**
|
|
13
|
+
* What reading a worksheet part needs around it: the sheet being filled and the three tables its
|
|
14
|
+
* records resolve through, plus the date system a serial under a date format counts from.
|
|
15
|
+
*
|
|
16
|
+
* One value rather than five positional arguments, two of them arrays and two of those `readonly
|
|
17
|
+
* string[]`/`ReadonlyArray<XfStyle>` -- a run whose order the call site cannot be read against, on a
|
|
18
|
+
* reader that decides what every cell in the sheet says. It is also exactly the half of
|
|
19
|
+
* {@link CellRecordContext} that does not change between records, which is why that one extends it
|
|
20
|
+
* and the record loop spreads this one into it.
|
|
21
|
+
*/
|
|
22
|
+
export interface WorksheetReadContext {
|
|
23
|
+
readonly sheet: Worksheet;
|
|
24
|
+
readonly sharedStrings: readonly string[];
|
|
25
|
+
readonly xfStyles: ReadonlyArray<XfStyle>;
|
|
26
|
+
readonly scope: FormulaScope;
|
|
27
|
+
/** The workbook's date system, from `BrtWbProp`: what a serial under a date format counts from. */
|
|
28
|
+
readonly dateEpoch: DateEpoch;
|
|
29
|
+
/** Every name the workbook defines, as `definedNameKeys` spells them: whether a function a formula
|
|
30
|
+
* passes as a value sheds its `_xleta.` depends on them, as it does in the XML reader. */
|
|
31
|
+
readonly definedNames: ReadonlySet<string>;
|
|
32
|
+
/** What the workbook's cell and value metadata indices resolve to, read from its metadata part. */
|
|
33
|
+
readonly cellMetadata: CellMetadataIndex;
|
|
34
|
+
}
|
|
@@ -1,157 +1,199 @@
|
|
|
1
|
-
import { encodeAddress,
|
|
2
|
-
import {
|
|
1
|
+
import { encodeAddress, encodeRange, encodeRect, MAX_COLUMN_INDEX, MAX_ROW_INDEX, } from '../../core/address.js';
|
|
2
|
+
import { coerceDateSerial } from '../../core/date.js';
|
|
3
3
|
import { unmangleFunctions } from '../../core/formula.js';
|
|
4
|
+
import { INTERNAL } from '../../core/internal.js';
|
|
4
5
|
import { assignStyleFacets } from '../../core/style.js';
|
|
6
|
+
import { ColumnRecordBudget, clampColumnSpan } from '../read-policy/column-budget.js';
|
|
7
|
+
import { admitArrayRanges, admitting } from '../read-policy/read-repair.js';
|
|
8
|
+
import { CellStyleResolver } from '../style/cell-style-resolution.js';
|
|
5
9
|
import { applyXfToCell } from '../style/xf-style.js';
|
|
6
10
|
import { decodeFormula, formulaAnchor } from './formula.js';
|
|
7
11
|
import { errorCodeFor, RecordReader } from './primitives.js';
|
|
8
12
|
import { readRecords } from './record-stream.js';
|
|
9
13
|
import { BRT } from './record-types.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
BRT.
|
|
18
|
-
BRT.
|
|
14
|
+
import { SheetProtectionRecords } from './sheet-protection.js';
|
|
15
|
+
const value = (read) => ({
|
|
16
|
+
kind: 'value',
|
|
17
|
+
read,
|
|
18
|
+
});
|
|
19
|
+
const formula = (read) => ({ kind: 'formula', read });
|
|
20
|
+
const CELL_RECORDS = new Map([
|
|
21
|
+
[BRT.CellBlank, value(() => null)],
|
|
22
|
+
[BRT.CellRk, value((r, c) => coerceDateSerial(r.rk(), c.numFmt, c.epoch))],
|
|
23
|
+
[BRT.CellReal, value((r, c) => coerceDateSerial(r.f64(), c.numFmt, c.epoch))],
|
|
24
|
+
[BRT.CellBool, value((r) => r.u8() !== 0)],
|
|
25
|
+
[BRT.CellError, value((r, c) => errorOf(r.u8(), c.valueError))],
|
|
26
|
+
[BRT.CellSt, value((r) => r.wideString())],
|
|
27
|
+
[BRT.CellRString, value((r) => r.richString())],
|
|
28
|
+
[BRT.CellIsst, value((r, c) => c.sharedStrings[r.u32()] ?? '')],
|
|
29
|
+
[BRT.FmlaNum, formula((r, c) => coerceDateSerial(r.f64(), c.numFmt, c.epoch))],
|
|
30
|
+
[BRT.FmlaBool, formula((r) => r.u8() !== 0)],
|
|
31
|
+
[BRT.FmlaError, formula((r, c) => errorOf(r.u8(), c.valueError) ?? undefined)],
|
|
32
|
+
[BRT.FmlaString, formula((r) => r.wideString())],
|
|
19
33
|
]);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export function parseWorksheet(part, sheet, sharedStrings, xfStyles, scope) {
|
|
34
|
+
function errorOf(code, valueError) {
|
|
35
|
+
const error = valueError ?? errorCodeFor(code);
|
|
36
|
+
return error === undefined ? null : { error };
|
|
37
|
+
}
|
|
38
|
+
export function parseWorksheet(part, context) {
|
|
39
|
+
const { sheet, xfStyles, scope, definedNames } = context;
|
|
27
40
|
let row = -1;
|
|
28
|
-
|
|
29
|
-
const columnStyle = new Map();
|
|
41
|
+
const styleResolution = new CellStyleResolver();
|
|
30
42
|
let defaultRowHeight = -1;
|
|
31
43
|
const groups = new Map();
|
|
32
44
|
const deferred = [];
|
|
45
|
+
const columnBudget = new ColumnRecordBudget();
|
|
46
|
+
const protection = new SheetProtectionRecords();
|
|
47
|
+
let cellMeta = 0;
|
|
48
|
+
let valueMeta = 0;
|
|
33
49
|
for (const record of readRecords(part)) {
|
|
50
|
+
const cellRecord = CELL_RECORDS.get(record.type);
|
|
34
51
|
const reader = new RecordReader(record.data);
|
|
35
52
|
if (record.type === BRT.WsFmtInfo) {
|
|
36
53
|
reader.skip(6);
|
|
37
54
|
defaultRowHeight = reader.u16();
|
|
38
55
|
}
|
|
39
56
|
else if (record.type === BRT.ColInfo) {
|
|
40
|
-
applyColumn(reader, sheet, xfStyles,
|
|
57
|
+
applyColumn(reader, sheet, xfStyles, styleResolution, columnBudget);
|
|
41
58
|
}
|
|
42
59
|
else if (record.type === BRT.RowHdr) {
|
|
43
60
|
const header = applyRow(reader, sheet, defaultRowHeight);
|
|
44
61
|
row = header.row;
|
|
45
|
-
|
|
62
|
+
styleResolution.openRow(header.styleIndex, header.customFormat);
|
|
46
63
|
}
|
|
47
64
|
else if (record.type === BRT.MergeCell) {
|
|
48
65
|
const { rowFirst, rowLast, colFirst, colLast } = reader.range();
|
|
49
66
|
if (inGrid(colFirst, rowFirst) && inGrid(colLast, rowLast)) {
|
|
50
|
-
|
|
67
|
+
const ref = encodeRect({
|
|
68
|
+
top: rowFirst + 1,
|
|
69
|
+
left: colFirst + 1,
|
|
70
|
+
bottom: rowLast + 1,
|
|
71
|
+
right: colLast + 1,
|
|
72
|
+
});
|
|
73
|
+
admitting(() => {
|
|
74
|
+
sheet.mergeCells(ref);
|
|
75
|
+
});
|
|
51
76
|
}
|
|
52
77
|
}
|
|
78
|
+
else if (record.type === BRT.SheetProtection) {
|
|
79
|
+
protection.legacy(reader);
|
|
80
|
+
}
|
|
81
|
+
else if (record.type === BRT.SheetProtectionIso) {
|
|
82
|
+
protection.iso(reader);
|
|
83
|
+
}
|
|
53
84
|
else if (record.type === BRT.ArrFmla) {
|
|
54
|
-
const { rowFirst, colFirst } = reader.range();
|
|
85
|
+
const { rowFirst, rowLast, colFirst, colLast } = reader.range();
|
|
55
86
|
reader.skip(1);
|
|
87
|
+
const inGridRange = inGrid(colFirst, rowFirst) && inGrid(colLast, rowLast);
|
|
56
88
|
groups.set(groupKey(rowFirst, colFirst), {
|
|
89
|
+
ref: inGridRange
|
|
90
|
+
? encodeRange({
|
|
91
|
+
top: rowFirst + 1,
|
|
92
|
+
left: colFirst + 1,
|
|
93
|
+
bottom: rowLast + 1,
|
|
94
|
+
right: colLast + 1,
|
|
95
|
+
})
|
|
96
|
+
: undefined,
|
|
57
97
|
rgce: reader.bytes(reader.u32()),
|
|
58
98
|
rgcb: reader.bytes(reader.u32()),
|
|
59
99
|
});
|
|
60
100
|
}
|
|
61
|
-
else if (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
cell.value = formulaValue(decodeFormula(rgce, rgcb, scope), result);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
deferred.push({
|
|
83
|
-
cell,
|
|
84
|
-
row: row - 1,
|
|
85
|
-
column,
|
|
86
|
-
anchorRow: anchor.row,
|
|
87
|
-
anchorColumn: anchor.column,
|
|
88
|
-
result,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
101
|
+
else if (record.type === BRT.CellMeta) {
|
|
102
|
+
cellMeta = reader.u32();
|
|
103
|
+
}
|
|
104
|
+
else if (record.type === BRT.ValueMeta) {
|
|
105
|
+
valueMeta = reader.u32();
|
|
106
|
+
}
|
|
107
|
+
else if (cellRecord !== undefined) {
|
|
108
|
+
const member = readCellRecord(cellRecord, reader, {
|
|
109
|
+
...context,
|
|
110
|
+
row,
|
|
111
|
+
styleResolution,
|
|
112
|
+
cellMeta,
|
|
113
|
+
valueMeta,
|
|
114
|
+
});
|
|
115
|
+
cellMeta = 0;
|
|
116
|
+
valueMeta = 0;
|
|
117
|
+
if (member !== undefined)
|
|
118
|
+
deferred.push(member);
|
|
91
119
|
}
|
|
92
120
|
}
|
|
121
|
+
const protectedAs = protection.result();
|
|
122
|
+
if (protectedAs !== undefined)
|
|
123
|
+
sheet[INTERNAL].restoreProtection(protectedAs);
|
|
93
124
|
for (const member of deferred) {
|
|
94
125
|
const group = groups.get(groupKey(member.anchorRow, member.anchorColumn));
|
|
95
126
|
const own = member.row === member.anchorRow && member.column === member.anchorColumn;
|
|
96
127
|
member.cell.value =
|
|
97
128
|
group === undefined || !own
|
|
98
129
|
? (member.result ?? null)
|
|
99
|
-
:
|
|
130
|
+
: arrayFormulaValue(decodeFormula(group.rgce, group.rgcb, scope), group.ref, member.result, definedNames, member.dynamic);
|
|
131
|
+
}
|
|
132
|
+
admitArrayRanges(sheet);
|
|
133
|
+
}
|
|
134
|
+
function readCellRecord(record, reader, context) {
|
|
135
|
+
const { sheet, sharedStrings, xfStyles, scope, dateEpoch, definedNames, row, styleResolution } = context;
|
|
136
|
+
const { cellMetadata, cellMeta, valueMeta } = context;
|
|
137
|
+
if (row <= 0)
|
|
138
|
+
return undefined;
|
|
139
|
+
const { column, styleIndex } = reader.cell();
|
|
140
|
+
if (!inGrid(column, row - 1))
|
|
141
|
+
return undefined;
|
|
142
|
+
const style = styleResolution.styleFor(column + 1, styleIndex > 0 ? styleIndex : -1, xfStyles);
|
|
143
|
+
const cell = sheet.getCell(encodeAddress(column + 1, row));
|
|
144
|
+
applyXfToCell(cell, style);
|
|
145
|
+
const ctx = {
|
|
146
|
+
sharedStrings,
|
|
147
|
+
numFmt: style?.numFmt,
|
|
148
|
+
epoch: dateEpoch,
|
|
149
|
+
valueError: cellMetadata.valueErrors.get(valueMeta),
|
|
150
|
+
};
|
|
151
|
+
if (record.kind === 'value') {
|
|
152
|
+
cell.value = record.read(reader, ctx);
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
const result = record.read(reader, ctx);
|
|
156
|
+
reader.skip(2);
|
|
157
|
+
const rgce = reader.bytes(reader.u32());
|
|
158
|
+
const rgcb = reader.bytes(reader.u32());
|
|
159
|
+
const anchor = formulaAnchor(rgce, rgcb);
|
|
160
|
+
if (anchor === undefined) {
|
|
161
|
+
cell.value = formulaValue(decodeFormula(rgce, rgcb, scope), result, definedNames);
|
|
162
|
+
return undefined;
|
|
100
163
|
}
|
|
164
|
+
return {
|
|
165
|
+
cell,
|
|
166
|
+
row: row - 1,
|
|
167
|
+
column,
|
|
168
|
+
anchorRow: anchor.row,
|
|
169
|
+
anchorColumn: anchor.column,
|
|
170
|
+
result,
|
|
171
|
+
dynamic: cellMetadata.dynamicArrayCells.has(cellMeta),
|
|
172
|
+
};
|
|
101
173
|
}
|
|
102
174
|
function groupKey(row, column) {
|
|
103
175
|
return `${row}:${column}`;
|
|
104
176
|
}
|
|
105
|
-
function formulaValue(formula, result) {
|
|
177
|
+
function formulaValue(formula, result, definedNames) {
|
|
106
178
|
if (formula === undefined)
|
|
107
179
|
return result ?? null;
|
|
108
|
-
const stored = unmangleFunctions(formula);
|
|
180
|
+
const stored = unmangleFunctions(formula, definedNames);
|
|
109
181
|
return result === undefined ? { formula: stored } : { formula: stored, result };
|
|
110
182
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
default:
|
|
122
|
-
return reader.wideString();
|
|
123
|
-
}
|
|
183
|
+
function arrayFormulaValue(formula, ref, result, definedNames, dynamic) {
|
|
184
|
+
if (formula === undefined || ref === undefined)
|
|
185
|
+
return formulaValue(formula, result, definedNames);
|
|
186
|
+
return {
|
|
187
|
+
shareType: 'array',
|
|
188
|
+
formula: unmangleFunctions(formula, definedNames),
|
|
189
|
+
ref,
|
|
190
|
+
...(dynamic ? { dynamic: true } : {}),
|
|
191
|
+
...(result === undefined ? {} : { result }),
|
|
192
|
+
};
|
|
124
193
|
}
|
|
125
|
-
const MAX_ROW_INDEX = 1048575;
|
|
126
|
-
const MAX_COLUMN_INDEX = MAX_COLUMN - 1;
|
|
127
194
|
function inGrid(column, row) {
|
|
128
195
|
return column >= 0 && column <= MAX_COLUMN_INDEX && row >= 0 && row <= MAX_ROW_INDEX;
|
|
129
196
|
}
|
|
130
|
-
function decodeCell(type, reader, sharedStrings, numFmt) {
|
|
131
|
-
switch (type) {
|
|
132
|
-
case BRT.CellRk:
|
|
133
|
-
return asNumberOrDate(reader.rk(), numFmt);
|
|
134
|
-
case BRT.CellReal:
|
|
135
|
-
return asNumberOrDate(reader.f64(), numFmt);
|
|
136
|
-
case BRT.CellBool:
|
|
137
|
-
return reader.u8() !== 0;
|
|
138
|
-
case BRT.CellError: {
|
|
139
|
-
const error = errorCodeFor(reader.u8());
|
|
140
|
-
return error === undefined ? null : { error };
|
|
141
|
-
}
|
|
142
|
-
case BRT.CellSt:
|
|
143
|
-
return reader.wideString();
|
|
144
|
-
case BRT.CellRString:
|
|
145
|
-
return reader.richString();
|
|
146
|
-
case BRT.CellIsst:
|
|
147
|
-
return sharedStrings[reader.u32()] ?? '';
|
|
148
|
-
default:
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
function asNumberOrDate(value, numFmt) {
|
|
153
|
-
return numFmt !== undefined && isDateFormat(numFmt) ? serialToDate(value) : value;
|
|
154
|
-
}
|
|
155
197
|
function applyRow(reader, sheet, defaultRowHeight) {
|
|
156
198
|
const index = reader.u32();
|
|
157
199
|
const styleIndex = reader.u32();
|
|
@@ -159,7 +201,7 @@ function applyRow(reader, sheet, defaultRowHeight) {
|
|
|
159
201
|
reader.skip(1);
|
|
160
202
|
const flags = reader.u8();
|
|
161
203
|
if (index > MAX_ROW_INDEX)
|
|
162
|
-
return { row: -1, styleIndex: -1 };
|
|
204
|
+
return { row: -1, styleIndex: -1, customFormat: false };
|
|
163
205
|
const row = index + 1;
|
|
164
206
|
const handle = sheet.getRow(row);
|
|
165
207
|
if ((flags & ROW_CUSTOM_HEIGHT) !== 0 || height !== defaultRowHeight) {
|
|
@@ -172,7 +214,7 @@ function applyRow(reader, sheet, defaultRowHeight) {
|
|
|
172
214
|
handle.outlineLevel = outlineLevel;
|
|
173
215
|
if ((flags & ROW_COLLAPSED) !== 0)
|
|
174
216
|
handle.collapsed = true;
|
|
175
|
-
return { row, styleIndex: (flags & ROW_CUSTOM_FORMAT) !== 0
|
|
217
|
+
return { row, styleIndex, customFormat: (flags & ROW_CUSTOM_FORMAT) !== 0 };
|
|
176
218
|
}
|
|
177
219
|
const TWIPS_PER_POINT = 20;
|
|
178
220
|
const ROW_OUTLINE_LEVEL = 0b0000_0111;
|
|
@@ -180,7 +222,7 @@ const ROW_COLLAPSED = 0b0000_1000;
|
|
|
180
222
|
const ROW_HIDDEN = 0b0001_0000;
|
|
181
223
|
const ROW_CUSTOM_HEIGHT = 0b0010_0000;
|
|
182
224
|
const ROW_CUSTOM_FORMAT = 0b0100_0000;
|
|
183
|
-
function applyColumn(reader, sheet, xfStyles,
|
|
225
|
+
function applyColumn(reader, sheet, xfStyles, styleResolution, budget) {
|
|
184
226
|
const first = reader.u32();
|
|
185
227
|
const last = reader.u32();
|
|
186
228
|
const width = reader.u32();
|
|
@@ -193,11 +235,11 @@ function applyColumn(reader, sheet, xfStyles, columnStyle) {
|
|
|
193
235
|
(flags & (COLUMN_HIDDEN | COLUMN_CUSTOM_WIDTH | COLUMN_COLLAPSED)) === 0) {
|
|
194
236
|
return;
|
|
195
237
|
}
|
|
196
|
-
const
|
|
197
|
-
if (
|
|
238
|
+
const span = clampColumnSpan(first + 1, last + 1, budget);
|
|
239
|
+
if (span === undefined)
|
|
198
240
|
return;
|
|
199
|
-
for (let index = first; index <=
|
|
200
|
-
const column = sheet.getColumn(index
|
|
241
|
+
for (let index = span.first; index <= span.last; index++) {
|
|
242
|
+
const column = sheet.getColumn(index);
|
|
201
243
|
column.width = width / COLUMN_WIDTH_UNITS;
|
|
202
244
|
if ((flags & COLUMN_HIDDEN) !== 0)
|
|
203
245
|
column.hidden = true;
|
|
@@ -207,9 +249,9 @@ function applyColumn(reader, sheet, xfStyles, columnStyle) {
|
|
|
207
249
|
column.collapsed = true;
|
|
208
250
|
if (style !== undefined)
|
|
209
251
|
assignStyleFacets(column, style);
|
|
210
|
-
if (styleIndex > 0)
|
|
211
|
-
columnStyle.set(index, styleIndex);
|
|
212
252
|
}
|
|
253
|
+
if (styleIndex > 0)
|
|
254
|
+
styleResolution.noteColumnSpan(span.first, span.last, styleIndex);
|
|
213
255
|
}
|
|
214
256
|
const COLUMN_WIDTH_UNITS = 256;
|
|
215
257
|
const COLUMN_HIDDEN = 0b0000_0001;
|
package/dist/io/xlsb/read.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Workbook } from '../../core/workbook.ts';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ReadPackageOptions } from '../opc/read-options.ts';
|
|
3
3
|
/** The office-document part every `.xlsb` package is entered through. */
|
|
4
4
|
export declare const XLSB_WORKBOOK_PART = "xl/workbook.bin";
|
|
5
5
|
/**
|
|
@@ -11,10 +11,13 @@ export declare const XLSB_WORKBOOK_PART = "xl/workbook.bin";
|
|
|
11
11
|
* @throws {PackageReadError} if the input is a ZIP that cannot be unpacked: a corrupt or
|
|
12
12
|
* truncated archive, or one exceeding the inflate bound (a probable zip bomb).
|
|
13
13
|
*/
|
|
14
|
-
export declare function readXlsb(data: Uint8Array, options?:
|
|
14
|
+
export declare function readXlsb(data: Uint8Array, options?: ReadPackageOptions): Workbook;
|
|
15
15
|
/**
|
|
16
16
|
* Build the model from an already-inflated `.xlsb` package. Separate from {@link readXlsb} so the
|
|
17
17
|
* `.xlsx` reader can hand over a package it has already inflated and classified, rather than
|
|
18
18
|
* inflating the same bytes twice.
|
|
19
|
+
*
|
|
20
|
+
* `documentPath` is where the package's own `_rels/.rels` says its workbook lives; it defaults to the
|
|
21
|
+
* conventional path for a caller holding nothing but the parts.
|
|
19
22
|
*/
|
|
20
|
-
export declare function readXlsbPackage(files: Record<string, Uint8Array
|
|
23
|
+
export declare function readXlsbPackage(files: Record<string, Uint8Array>, documentPath?: string): Workbook;
|