@shbernal/ts-xlsx 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/autofilter.d.ts +1 -1
- package/dist/core/autofilter.js +3 -5
- package/dist/core/axis-handle.d.ts +8 -0
- package/dist/core/axis-handle.js +14 -0
- package/dist/core/cell.d.ts +24 -0
- package/dist/core/cell.js +9 -1
- package/dist/core/column.d.ts +4 -1
- package/dist/core/column.js +31 -35
- package/dist/core/conditional-formatting.d.ts +5 -5
- package/dist/core/conditional-formatting.js +11 -25
- package/dist/core/data-validation.d.ts +3 -3
- package/dist/core/data-validation.js +7 -15
- package/dist/core/image.d.ts +1 -1
- package/dist/core/image.js +2 -4
- package/dist/core/merge-index.d.ts +31 -0
- package/dist/core/merge-index.js +60 -0
- package/dist/core/merge.d.ts +0 -10
- package/dist/core/merge.js +0 -8
- 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 +4 -8
- package/dist/core/row.d.ts +4 -1
- package/dist/core/row.js +19 -23
- package/dist/core/style.d.ts +51 -7
- package/dist/core/style.js +29 -34
- package/dist/core/table.d.ts +1 -1
- package/dist/core/table.js +3 -5
- package/dist/core/used-extent.d.ts +44 -0
- package/dist/core/used-extent.js +102 -0
- package/dist/core/worksheet.d.ts +17 -6
- package/dist/core/worksheet.js +48 -42
- package/dist/customui/ribbon.js +4 -6
- package/dist/io/opc/inflate.js +1 -1
- package/dist/io/opc/part-paths.d.ts +1 -0
- package/dist/io/opc/part-paths.js +15 -0
- package/dist/io/opc/read-opc.d.ts +22 -3
- package/dist/io/opc/read-opc.js +11 -39
- package/dist/io/opc/rels.d.ts +1 -6
- package/dist/io/opc/rels.js +1 -4
- package/dist/io/style/xf-style.d.ts +26 -2
- package/dist/io/style/xf-style.js +6 -0
- package/dist/io/xlsb/read-styles.js +6 -3
- package/dist/io/xlsb/read.d.ts +1 -1
- package/dist/io/xlsb/read.js +5 -8
- package/dist/io/xlsx/cell-accumulator.d.ts +1 -1
- package/dist/io/xlsx/cell-accumulator.js +1 -1
- package/dist/io/xlsx/cell-value.js +1 -1
- package/dist/io/xlsx/color-xml.js +1 -1
- package/dist/io/xlsx/comments.js +2 -1
- package/dist/io/xlsx/conditional-formatting.d.ts +3 -2
- package/dist/io/xlsx/conditional-formatting.js +22 -21
- package/dist/io/xlsx/data-validation.d.ts +9 -7
- package/dist/io/xlsx/data-validation.js +10 -9
- package/dist/io/xlsx/edit-vba.js +4 -11
- package/dist/io/xlsx/hyperlinks.d.ts +4 -2
- package/dist/io/xlsx/hyperlinks.js +20 -17
- package/dist/io/xlsx/images.js +15 -14
- package/dist/io/xlsx/package-plan.d.ts +9 -1
- package/dist/io/xlsx/package-plan.js +29 -16
- package/dist/io/xlsx/part-names.d.ts +41 -0
- package/dist/io/xlsx/part-names.js +46 -0
- package/dist/io/xlsx/read-pivot.js +2 -1
- package/dist/io/xlsx/read-rows.js +12 -13
- package/dist/io/xlsx/read-shared-strings.js +2 -1
- package/dist/io/xlsx/read-styles.d.ts +1 -1
- package/dist/io/xlsx/read-styles.js +63 -42
- package/dist/io/xlsx/read-worksheet.d.ts +10 -1
- package/dist/io/xlsx/read-worksheet.js +43 -56
- package/dist/io/xlsx/read.d.ts +2 -3
- package/dist/io/xlsx/read.js +81 -73
- package/dist/io/xlsx/rich-runs.d.ts +1 -1
- package/dist/io/xlsx/rich-runs.js +2 -1
- package/dist/io/xlsx/sheet-properties.js +21 -28
- package/dist/io/xlsx/styles.js +23 -20
- package/dist/io/xlsx/tables.js +2 -1
- package/dist/io/xlsx/theme-xml.js +1 -1
- package/dist/io/xlsx/threaded-comments.js +2 -1
- package/dist/io/xlsx/workbook-xml.js +29 -28
- package/dist/io/xlsx/worksheet-xml.d.ts +1 -1
- package/dist/io/xlsx/worksheet-xml.js +14 -16
- package/dist/io/xlsx/write-stream.d.ts +6 -0
- package/dist/io/xlsx/write-stream.js +30 -22
- package/dist/io/xlsx/write.d.ts +5 -0
- package/dist/io/xlsx/write.js +155 -131
- package/dist/token-set.d.ts +15 -0
- package/dist/token-set.js +4 -0
- package/dist/vba/cfb-format.d.ts +24 -0
- package/dist/vba/cfb-format.js +12 -0
- package/dist/vba/cfb-writer.js +17 -17
- package/dist/vba/cfb.js +1 -7
- package/dist/vba/ms-ovba.js +32 -11
- package/dist/vba/project.js +13 -13
- package/dist/vba/vba-encoding.js +1 -1
- package/dist/xml/xml-read.d.ts +59 -74
- package/dist/xml/xml-read.js +83 -176
- package/dist/xml/xml-scan.d.ts +100 -0
- package/dist/xml/xml-scan.js +208 -0
- package/dist/xml/xml.d.ts +1 -1
- package/package.json +2 -3
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { relativePartPath } from '../opc/part-paths.js';
|
|
2
|
+
export const WORKBOOK_PART = 'xl/workbook.xml';
|
|
3
|
+
export const STYLES_PART = 'xl/styles.xml';
|
|
4
|
+
export const SHARED_STRINGS_PART = 'xl/sharedStrings.xml';
|
|
5
|
+
export const PERSONS_PART = 'xl/persons/person.xml';
|
|
6
|
+
export const CORE_PROPS_PART = 'docProps/core.xml';
|
|
7
|
+
export const APP_PROPS_PART = 'docProps/app.xml';
|
|
8
|
+
export function worksheetPart(number) {
|
|
9
|
+
return `xl/worksheets/sheet${number}.xml`;
|
|
10
|
+
}
|
|
11
|
+
export function tablePart(number) {
|
|
12
|
+
return `xl/tables/table${number}.xml`;
|
|
13
|
+
}
|
|
14
|
+
export function mediaPart(number, extension) {
|
|
15
|
+
return `xl/media/image${number}.${extension}`;
|
|
16
|
+
}
|
|
17
|
+
export function drawingPart(number) {
|
|
18
|
+
return `xl/drawings/drawing${number}.xml`;
|
|
19
|
+
}
|
|
20
|
+
export function vmlDrawingPart(number) {
|
|
21
|
+
return `xl/drawings/vmlDrawing${number}.vml`;
|
|
22
|
+
}
|
|
23
|
+
export function commentsPart(number) {
|
|
24
|
+
return `xl/comments${number}.xml`;
|
|
25
|
+
}
|
|
26
|
+
export function threadedCommentsPart(number) {
|
|
27
|
+
return `xl/threadedComments/threadedComment${number}.xml`;
|
|
28
|
+
}
|
|
29
|
+
export function printerSettingsPart(number) {
|
|
30
|
+
return `xl/printerSettings/printerSettings${number}.bin`;
|
|
31
|
+
}
|
|
32
|
+
export function pivotTablePart(number) {
|
|
33
|
+
return `xl/pivotTables/pivotTable${number}.xml`;
|
|
34
|
+
}
|
|
35
|
+
export function pivotCacheDefinitionPart(number) {
|
|
36
|
+
return `xl/pivotCache/pivotCacheDefinition${number}.xml`;
|
|
37
|
+
}
|
|
38
|
+
export function pivotCacheRecordsPart(number) {
|
|
39
|
+
return `xl/pivotCache/pivotCacheRecords${number}.xml`;
|
|
40
|
+
}
|
|
41
|
+
export function targetFromWorksheet(partPath) {
|
|
42
|
+
return relativePartPath(worksheetPart(1), partPath);
|
|
43
|
+
}
|
|
44
|
+
export function targetFromWorkbook(partPath) {
|
|
45
|
+
return relativePartPath(WORKBOOK_PART, partPath);
|
|
46
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isDeclarablePivotSourceKind, pivotMetricFromSubtotal, } from '../../core/pivot-table.js';
|
|
2
|
-
import {
|
|
2
|
+
import { parseXml } from '../../xml/xml-read.js';
|
|
3
|
+
import { localName, numInteger } from '../../xml/xml-scan.js';
|
|
3
4
|
export function parsePivotTable(tableXml, cacheXml) {
|
|
4
5
|
const { fields, source } = parsePivotCacheDefinition(cacheXml);
|
|
5
6
|
const def = parsePivotTableDefinition(tableXml);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { MAX_COLUMN, MAX_ROW } from '../../core/address.js';
|
|
2
2
|
import { AuthoringError } from '../../errors.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { closeEmptyElements } from '../../xml/xml-read.js';
|
|
4
|
+
import { boolStrict, localName, numInteger, xmlEvents } from '../../xml/xml-scan.js';
|
|
5
|
+
import { openSpreadsheetPackage, readPartRelationships } from '../opc/read-opc.js';
|
|
6
|
+
import { unsupportedWorkbookPart } from '../opc/sniff-format.js';
|
|
6
7
|
import { CellAccumulator } from './cell-accumulator.js';
|
|
7
8
|
import { XlsxParseError } from './errors.js';
|
|
8
9
|
import { parseSharedStrings } from './read-shared-strings.js';
|
|
9
|
-
import {
|
|
10
|
+
import { parseStyleTable, parseWorkbookSheets, } from './read.js';
|
|
10
11
|
export function* readSheetRows(data, options = {}) {
|
|
11
12
|
const pkg = openPackage(data, options.maxUncompressedBytes);
|
|
12
13
|
const chosen = pickSheet(pkg.sheets, options.sheet);
|
|
@@ -23,14 +24,13 @@ export function* readWorkbookStream(data, options = {}) {
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
function openPackage(data, maxUncompressedBytes) {
|
|
26
|
-
const
|
|
27
|
-
const { partText: text } =
|
|
28
|
-
const workbookXml = text('xl/workbook.xml');
|
|
27
|
+
const { pkg, workbookXml } = openSpreadsheetPackage(data, maxUncompressedBytes);
|
|
28
|
+
const { partText: text } = pkg;
|
|
29
29
|
if (workbookXml === undefined) {
|
|
30
30
|
throw unsupportedWorkbookPart(text, 'the binary .xlsb format (BIFF12) cannot be row-streamed yet; read it with readXlsx or readXlsb');
|
|
31
31
|
}
|
|
32
32
|
const sheets = parseWorkbookSheets(workbookXml);
|
|
33
|
-
const rels =
|
|
33
|
+
const rels = readPartRelationships('xl/workbook.xml', text);
|
|
34
34
|
const sharedStrings = parseSharedStrings(text('xl/sharedStrings.xml') ?? '');
|
|
35
35
|
const { cellXfs: xfStyles } = parseStyleTable(text('xl/styles.xml') ?? '');
|
|
36
36
|
return {
|
|
@@ -38,9 +38,8 @@ function openPackage(data, maxUncompressedBytes) {
|
|
|
38
38
|
sharedStrings,
|
|
39
39
|
xfStyles,
|
|
40
40
|
sheetXml(relId) {
|
|
41
|
-
const target = rels.
|
|
42
|
-
|
|
43
|
-
return path === undefined ? undefined : text(path);
|
|
41
|
+
const target = rels.byId(relId)?.target;
|
|
42
|
+
return target === undefined ? undefined : text(rels.pathOf(target));
|
|
44
43
|
},
|
|
45
44
|
};
|
|
46
45
|
}
|
|
@@ -88,7 +87,7 @@ class StreamedSheetReader {
|
|
|
88
87
|
}
|
|
89
88
|
get merges() {
|
|
90
89
|
this.#ensureScanned();
|
|
91
|
-
return this.#merges;
|
|
90
|
+
return [...this.#merges];
|
|
92
91
|
}
|
|
93
92
|
#ensureScanned() {
|
|
94
93
|
if (this.#scanned)
|
|
@@ -156,7 +155,7 @@ function* scanSheet(xml, sharedStrings, xfStyles, hiddenColumns, merges) {
|
|
|
156
155
|
}
|
|
157
156
|
}
|
|
158
157
|
function collectHiddenColumn(attrs, hiddenColumns) {
|
|
159
|
-
if (attrs.hidden
|
|
158
|
+
if (!boolStrict(attrs.hidden))
|
|
160
159
|
return;
|
|
161
160
|
const min = numInteger(attrs.min, 1);
|
|
162
161
|
const max = numInteger(attrs.max, 1);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseXml } from '../../xml/xml-read.js';
|
|
2
|
+
import { localName } from '../../xml/xml-scan.js';
|
|
2
3
|
import { RunAccumulator } from './rich-runs.js';
|
|
3
4
|
export function parseSharedStrings(xml) {
|
|
4
5
|
if (xml === '')
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Font, type TableStyleTable } from '../../core/style.ts';
|
|
2
|
-
import { type XmlAttributes } from '../../xml/xml-
|
|
2
|
+
import { type XmlAttributes } from '../../xml/xml-scan.ts';
|
|
3
3
|
import { type StyleTable } from '../style/xf-style.ts';
|
|
4
4
|
export type FontDraft = {
|
|
5
5
|
-readonly [K in keyof Font]?: Font[K];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { isBorderStyle, isFillPatternType, isFontScheme, isFontVerticalAlignment,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { ALIGNMENT_FACETS, isBorderStyle, isFillPatternType, isFontScheme, isFontVerticalAlignment, isNamedUnderlineStyle, } from '../../core/style.js';
|
|
2
|
+
import { closeEmptyElements, elementSubtrees, openElements, } from '../../xml/xml-read.js';
|
|
3
|
+
import { boolPresent, boolStrict, boolTristate, localName, numFinite, numInteger, xmlEvents, } from '../../xml/xml-scan.js';
|
|
4
|
+
import { NO_PRESERVED_STYLE_TABLES, numFmtCodeFor, resolveStyleTable, } from '../style/xf-style.js';
|
|
4
5
|
import { parseColor } from './color-xml.js';
|
|
5
6
|
const BORDER_EDGE_NAMES = ['left', 'right', 'top', 'bottom', 'diagonal'];
|
|
6
7
|
const BORDER_EDGES = new Set(BORDER_EDGE_NAMES);
|
|
@@ -15,7 +16,7 @@ const STYLE_EMPTY_CLOSES = new Set([
|
|
|
15
16
|
]);
|
|
16
17
|
export function parseStyleTable(xml) {
|
|
17
18
|
if (xml === '')
|
|
18
|
-
return { cellXfs: [], namedStyles: [] };
|
|
19
|
+
return { cellXfs: [], namedStyles: [], preserved: NO_PRESERVED_STYLE_TABLES };
|
|
19
20
|
let fills = [];
|
|
20
21
|
let fonts = [];
|
|
21
22
|
let borders = [];
|
|
@@ -54,7 +55,17 @@ export function parseStyleTable(xml) {
|
|
|
54
55
|
}
|
|
55
56
|
next = events.next();
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
+
const { fragments, attributes } = elementSubtrees(xml, PRESERVED_SUBTREES);
|
|
59
|
+
const preserved = {
|
|
60
|
+
dxfs: fragments.get('dxfs') ?? [],
|
|
61
|
+
indexedColors: fragments.get('indexedColors') ?? [],
|
|
62
|
+
mruColors: fragments.get('mruColors') ?? [],
|
|
63
|
+
tableStyles: buildTableStyleTable(xml, fragments.get('tableStyles') ?? [], attributes.get('tableStyles')),
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
...resolveStyleTable({ directXfs: xfStyles, namedXfs, labels: cellStyleNames, fonts }),
|
|
67
|
+
preserved,
|
|
68
|
+
};
|
|
58
69
|
}
|
|
59
70
|
function* until(events, container) {
|
|
60
71
|
let next = events.next();
|
|
@@ -389,53 +400,58 @@ function borderToStyle(draft) {
|
|
|
389
400
|
}
|
|
390
401
|
function parseAlignment(attrs) {
|
|
391
402
|
const out = {};
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
403
|
+
for (const facet of ALIGNMENT_FACETS) {
|
|
404
|
+
const raw = attrs[facet.key];
|
|
405
|
+
switch (facet.kind) {
|
|
406
|
+
case 'token':
|
|
407
|
+
if (raw !== undefined && raw !== facet.omit && facet.isValid(raw)) {
|
|
408
|
+
assignAlignmentToken(out, facet.key, raw);
|
|
409
|
+
}
|
|
410
|
+
break;
|
|
411
|
+
case 'number': {
|
|
412
|
+
const value = numFinite(raw);
|
|
413
|
+
if (value !== undefined && value !== 0)
|
|
414
|
+
out[facet.key] = value;
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
case 'flag':
|
|
418
|
+
if (boolStrict(raw))
|
|
419
|
+
out[facet.key] = true;
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
396
422
|
}
|
|
397
|
-
if (attrs.vertical !== undefined && isVerticalAlignment(attrs.vertical))
|
|
398
|
-
out.vertical = attrs.vertical;
|
|
399
|
-
const rotation = numFinite(attrs.textRotation);
|
|
400
|
-
if (rotation !== undefined && rotation !== 0)
|
|
401
|
-
out.textRotation = rotation;
|
|
402
|
-
if (boolStrict(attrs.wrapText))
|
|
403
|
-
out.wrapText = true;
|
|
404
|
-
const indent = numInteger(attrs.indent);
|
|
405
|
-
if (indent !== undefined && indent !== 0)
|
|
406
|
-
out.indent = indent;
|
|
407
|
-
if (boolStrict(attrs.shrinkToFit))
|
|
408
|
-
out.shrinkToFit = true;
|
|
409
|
-
const order = numInteger(attrs.readingOrder);
|
|
410
|
-
if (order !== undefined && order !== 0)
|
|
411
|
-
out.readingOrder = order;
|
|
412
423
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
413
424
|
}
|
|
425
|
+
function assignAlignmentToken(out, key, raw) {
|
|
426
|
+
out[key] = raw;
|
|
427
|
+
}
|
|
414
428
|
function parseProtection(attrs) {
|
|
415
429
|
const out = {};
|
|
416
|
-
if (attrs.locked ===
|
|
430
|
+
if (boolTristate(attrs.locked) === false)
|
|
417
431
|
out.locked = false;
|
|
418
432
|
if (boolStrict(attrs.hidden))
|
|
419
433
|
out.hidden = true;
|
|
420
434
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
421
435
|
}
|
|
422
436
|
export function parseIndexedColors(stylesXml) {
|
|
423
|
-
return
|
|
437
|
+
return capturedFragments(stylesXml, 'indexedColors');
|
|
424
438
|
}
|
|
425
439
|
export function parseMruColors(stylesXml) {
|
|
426
|
-
return
|
|
440
|
+
return capturedFragments(stylesXml, 'mruColors');
|
|
427
441
|
}
|
|
428
442
|
export function parseTableStyles(stylesXml) {
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
break;
|
|
443
|
+
const { fragments, attributes } = elementSubtrees(stylesXml, new Map([['tableStyles', 'tableStyle']]));
|
|
444
|
+
return buildTableStyleTable(stylesXml, fragments.get('tableStyles') ?? [], attributes.get('tableStyles'));
|
|
445
|
+
}
|
|
446
|
+
function buildTableStyleTable(stylesXml, styles, containerAttrs) {
|
|
447
|
+
const table = { styles: [...styles] };
|
|
448
|
+
if (containerAttrs?.defaultTableStyle !== undefined) {
|
|
449
|
+
table.defaultTableStyle = containerAttrs.defaultTableStyle;
|
|
437
450
|
}
|
|
438
|
-
|
|
451
|
+
if (containerAttrs?.defaultPivotStyle !== undefined) {
|
|
452
|
+
table.defaultPivotStyle = containerAttrs.defaultPivotStyle;
|
|
453
|
+
}
|
|
454
|
+
const namespaces = fragmentNamespaces(stylesXml, table.styles);
|
|
439
455
|
if (namespaces.length > 0)
|
|
440
456
|
table.namespaces = namespaces;
|
|
441
457
|
return table;
|
|
@@ -470,11 +486,16 @@ function fragmentNamespaces(stylesXml, fragments) {
|
|
|
470
486
|
ignorable: ignorable.has(prefix),
|
|
471
487
|
}));
|
|
472
488
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
489
|
+
const PRESERVED_SUBTREES = new Map([
|
|
490
|
+
['dxfs', 'dxf'],
|
|
491
|
+
['indexedColors', 'rgbColor'],
|
|
492
|
+
['mruColors', 'color'],
|
|
493
|
+
['tableStyles', 'tableStyle'],
|
|
494
|
+
]);
|
|
495
|
+
function capturedFragments(xml, container) {
|
|
496
|
+
const child = PRESERVED_SUBTREES.get(container);
|
|
497
|
+
if (child === undefined)
|
|
476
498
|
return [];
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
return [...inner.matchAll(pattern)].map((m) => m[0] ?? '');
|
|
499
|
+
const { fragments } = elementSubtrees(xml, new Map([[container, child]]));
|
|
500
|
+
return [...(fragments.get(container) ?? [])];
|
|
480
501
|
}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type { Worksheet } from '../../core/worksheet.ts';
|
|
2
|
+
import { type SaxPass } from '../../xml/xml-read.ts';
|
|
2
3
|
import type { XfStyle } from '../style/xf-style.ts';
|
|
3
4
|
import type { SharedString } from './cell-value.ts';
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* A pass reading a worksheet part into `sheet`: cells and their styles, the column and row metadata,
|
|
7
|
+
* merges, the autofilter, page breaks, and the view and print layout. It commits as it goes rather
|
|
8
|
+
* than gathering, so it has nothing to hand back once the parse ends.
|
|
9
|
+
*
|
|
10
|
+
* Offered as a pass because the worksheet is the largest part in a package and four other readers
|
|
11
|
+
* want the same events, so the five share one parse of it rather than scanning it once each.
|
|
12
|
+
*/
|
|
13
|
+
export declare function worksheetPass(sheet: Worksheet, sharedStrings: readonly SharedString[], xfStyles: ReadonlyArray<XfStyle>): SaxPass;
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { MAX_COLUMN, MAX_ROW, tryDecodeRange } from '../../core/address.js';
|
|
2
2
|
import { isCustomFilterOperator, } from '../../core/autofilter.js';
|
|
3
3
|
import { INTERNAL } from '../../core/internal.js';
|
|
4
|
-
import {
|
|
4
|
+
import { HEADER_FOOTER_ELEMENTS, MARGIN_SIDES, PAGE_SETUP_FACETS, PRINT_OPTION_FLAGS, } from '../../core/page-setup.js';
|
|
5
5
|
import { SHEET_PROTECTION_FLAGS, } from '../../core/protection.js';
|
|
6
6
|
import { assignStyleFacets } from '../../core/style.js';
|
|
7
|
-
import {
|
|
7
|
+
import {} from '../../xml/xml-read.js';
|
|
8
|
+
import { boolPresent, boolStrict, boolTristate, decodeSpreadsheetText, localName, numFinite, numInteger, } from '../../xml/xml-scan.js';
|
|
8
9
|
import { CellAccumulator } from './cell-accumulator.js';
|
|
9
10
|
import { parseColor } from './color-xml.js';
|
|
10
|
-
const
|
|
11
|
+
const HEADER_FOOTER_CHILDREN = new Set(HEADER_FOOTER_ELEMENTS);
|
|
12
|
+
function isHeaderFooterElement(local) {
|
|
13
|
+
return HEADER_FOOTER_CHILDREN.has(local);
|
|
14
|
+
}
|
|
11
15
|
const WORKSHEET_EMPTY_CLOSES = new Set(['c', 'autoFilter']);
|
|
12
16
|
function pendingFilterCriteria(values, blank, predicates, and) {
|
|
13
17
|
if (values !== null && (values.length > 0 || blank)) {
|
|
@@ -19,7 +23,7 @@ function pendingFilterCriteria(values, blank, predicates, and) {
|
|
|
19
23
|
return null;
|
|
20
24
|
}
|
|
21
25
|
function parseSheetProtection(attrs) {
|
|
22
|
-
if (attrs.sheet ===
|
|
26
|
+
if (boolTristate(attrs.sheet) === false)
|
|
23
27
|
return undefined;
|
|
24
28
|
const flags = {};
|
|
25
29
|
for (const { key } of SHEET_PROTECTION_FLAGS) {
|
|
@@ -125,7 +129,7 @@ class PageBreakAccumulator {
|
|
|
125
129
|
this.#target.push(brk);
|
|
126
130
|
}
|
|
127
131
|
}
|
|
128
|
-
export function
|
|
132
|
+
export function worksheetPass(sheet, sharedStrings, xfStyles) {
|
|
129
133
|
const cell = new CellAccumulator({ richRuns: true });
|
|
130
134
|
let rowStyle = -1;
|
|
131
135
|
let rowCustomFormat = false;
|
|
@@ -141,11 +145,15 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
141
145
|
const style = styleIndex >= 0 ? xfStyles[styleIndex] : xfStyles[0];
|
|
142
146
|
cell.finalize(sheet, sharedStrings, style);
|
|
143
147
|
};
|
|
144
|
-
|
|
148
|
+
const handlers = {
|
|
145
149
|
onOpen(name, attrs, selfClosing) {
|
|
146
150
|
const local = localName(name);
|
|
147
151
|
if (cell.openElement(local, attrs, selfClosing))
|
|
148
152
|
return;
|
|
153
|
+
if (HEADER_FOOTER_CHILDREN.has(local)) {
|
|
154
|
+
cell.capture();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
149
157
|
switch (local) {
|
|
150
158
|
case 'col':
|
|
151
159
|
applyColumn(sheet, attrs, xfStyles, columnStyle);
|
|
@@ -155,14 +163,6 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
155
163
|
rowStyle = numInteger(attrs.s, 0) ?? -1;
|
|
156
164
|
rowCustomFormat = boolStrict(attrs.customFormat);
|
|
157
165
|
break;
|
|
158
|
-
case 'oddHeader':
|
|
159
|
-
case 'oddFooter':
|
|
160
|
-
case 'evenHeader':
|
|
161
|
-
case 'evenFooter':
|
|
162
|
-
case 'firstHeader':
|
|
163
|
-
case 'firstFooter':
|
|
164
|
-
cell.capture();
|
|
165
|
-
break;
|
|
166
166
|
case 'mergeCell':
|
|
167
167
|
if (attrs.ref !== undefined && attrs.ref !== '') {
|
|
168
168
|
try {
|
|
@@ -229,15 +229,11 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
229
229
|
}
|
|
230
230
|
if (claimed === 'claimed')
|
|
231
231
|
return;
|
|
232
|
+
if (isHeaderFooterElement(local)) {
|
|
233
|
+
sheet.headerFooter[local] = decodeSpreadsheetText(cell.capturedText);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
232
236
|
switch (local) {
|
|
233
|
-
case 'oddHeader':
|
|
234
|
-
case 'oddFooter':
|
|
235
|
-
case 'evenHeader':
|
|
236
|
-
case 'evenFooter':
|
|
237
|
-
case 'firstHeader':
|
|
238
|
-
case 'firstFooter':
|
|
239
|
-
sheet.headerFooter[local] = decodeSpreadsheetText(cell.capturedText);
|
|
240
|
-
break;
|
|
241
237
|
case 'row':
|
|
242
238
|
rowStyle = -1;
|
|
243
239
|
rowCustomFormat = false;
|
|
@@ -256,7 +252,8 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
256
252
|
break;
|
|
257
253
|
}
|
|
258
254
|
},
|
|
259
|
-
}
|
|
255
|
+
};
|
|
256
|
+
return { handlers, closeEmptyElements: WORKSHEET_EMPTY_CLOSES };
|
|
260
257
|
}
|
|
261
258
|
function applySheetProperties(local, attrs, sheet) {
|
|
262
259
|
switch (local) {
|
|
@@ -346,21 +343,11 @@ function applyRow(sheet, attrs) {
|
|
|
346
343
|
row.collapsed = true;
|
|
347
344
|
}
|
|
348
345
|
function applyPrintOptions(printOptions, attrs) {
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
printOptions.verticalCentered = verticalCentered;
|
|
355
|
-
const headings = boolTristate(attrs.headings);
|
|
356
|
-
if (headings !== undefined)
|
|
357
|
-
printOptions.headings = headings;
|
|
358
|
-
const gridLines = boolTristate(attrs.gridLines);
|
|
359
|
-
if (gridLines !== undefined)
|
|
360
|
-
printOptions.gridLines = gridLines;
|
|
361
|
-
const gridLinesSet = boolTristate(attrs.gridLinesSet);
|
|
362
|
-
if (gridLinesSet !== undefined)
|
|
363
|
-
printOptions.gridLinesSet = gridLinesSet;
|
|
346
|
+
for (const flag of PRINT_OPTION_FLAGS) {
|
|
347
|
+
const value = boolTristate(attrs[flag]);
|
|
348
|
+
if (value !== undefined)
|
|
349
|
+
printOptions[flag] = value;
|
|
350
|
+
}
|
|
364
351
|
}
|
|
365
352
|
function applyMargins(margins, attrs) {
|
|
366
353
|
for (const side of MARGIN_SIDES) {
|
|
@@ -370,22 +357,22 @@ function applyMargins(margins, attrs) {
|
|
|
370
357
|
}
|
|
371
358
|
}
|
|
372
359
|
function applyPageSetup(pageSetup, attrs) {
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
360
|
+
for (const facet of PAGE_SETUP_FACETS) {
|
|
361
|
+
const raw = attrs[facet.key];
|
|
362
|
+
switch (facet.kind) {
|
|
363
|
+
case 'count': {
|
|
364
|
+
const value = numInteger(raw, 0);
|
|
365
|
+
if (value !== undefined)
|
|
366
|
+
pageSetup[facet.key] = value;
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
case 'token':
|
|
370
|
+
if (raw !== undefined && facet.isValid(raw))
|
|
371
|
+
assignPageSetupToken(pageSetup, facet.key, raw);
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function assignPageSetupToken(pageSetup, key, raw) {
|
|
377
|
+
pageSetup[key] = raw;
|
|
391
378
|
}
|
package/dist/io/xlsx/read.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Workbook, type WorkbookView } from '../../core/workbook.ts';
|
|
2
2
|
import { type WorksheetState } from '../../core/worksheet.ts';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
export { DEFAULT_MAX_UNCOMPRESSED, type ReadXlsxOptions } from '../opc/read-options.ts';
|
|
3
|
+
import type { ReadXlsxOptions } from '../opc/read-options.ts';
|
|
4
|
+
export type { ReadXlsxOptions } from '../opc/read-options.ts';
|
|
6
5
|
export type { StyleTable, XfStyle } from '../style/xf-style.ts';
|
|
7
6
|
export { parseStyleTable } from './read-styles.ts';
|
|
8
7
|
/**
|