@shbernal/ts-xlsx 2.1.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/bytes.d.ts +7 -0
- package/dist/bytes.js +22 -0
- package/dist/core/address.d.ts +60 -2
- package/dist/core/address.js +40 -24
- package/dist/core/autofilter.d.ts +5 -4
- package/dist/core/autofilter.js +34 -35
- package/dist/core/axis-handle.d.ts +10 -0
- package/dist/core/axis-handle.js +17 -0
- package/dist/core/cell.d.ts +25 -0
- package/dist/core/cell.js +9 -3
- package/dist/core/clone.d.ts +29 -0
- package/dist/core/clone.js +24 -0
- package/dist/core/color-resolution.js +2 -4
- package/dist/core/column.d.ts +5 -1
- package/dist/core/column.js +34 -35
- package/dist/core/comment-thread.js +2 -1
- package/dist/core/conditional-formatting-overlay.d.ts +2 -1
- package/dist/core/conditional-formatting-overlay.js +2 -2
- package/dist/core/conditional-formatting.d.ts +14 -6
- package/dist/core/conditional-formatting.js +45 -43
- package/dist/core/containers.d.ts +12 -0
- package/dist/core/containers.js +5 -0
- package/dist/core/data-validation-overlay.d.ts +2 -1
- package/dist/core/data-validation-overlay.js +4 -4
- package/dist/core/data-validation.d.ts +9 -3
- package/dist/core/data-validation.js +21 -18
- package/dist/core/date-format.d.ts +20 -0
- package/dist/core/date-format.js +160 -0
- package/dist/core/date.d.ts +43 -8
- package/dist/core/date.js +18 -2
- package/dist/core/formula.d.ts +26 -0
- package/dist/core/formula.js +20 -4
- package/dist/core/grid-edits.d.ts +2 -3
- package/dist/core/grid-edits.js +69 -70
- package/dist/core/grid-shift.d.ts +58 -9
- package/dist/core/grid-shift.js +26 -4
- package/dist/core/image.d.ts +14 -10
- package/dist/core/image.js +9 -9
- package/dist/core/internal.d.ts +8 -2
- package/dist/core/limits.d.ts +23 -0
- package/dist/core/limits.js +4 -0
- package/dist/core/merge-index.d.ts +31 -0
- package/dist/core/merge-index.js +60 -0
- package/dist/core/merge.d.ts +5 -14
- package/dist/core/merge.js +18 -27
- package/dist/core/page-setup.d.ts +72 -2
- package/dist/core/page-setup.js +34 -8
- package/dist/core/pivot-table.d.ts +1 -1
- package/dist/core/pivot-table.js +67 -53
- package/dist/core/protection.js +2 -11
- package/dist/core/range.js +34 -30
- package/dist/core/row-input.js +2 -2
- package/dist/core/row.d.ts +5 -1
- package/dist/core/row.js +22 -23
- package/dist/core/style.d.ts +134 -75
- package/dist/core/style.js +112 -53
- package/dist/core/table-style.d.ts +1 -1
- package/dist/core/table-style.js +4 -4
- package/dist/core/table.d.ts +28 -10
- package/dist/core/table.js +54 -39
- package/dist/core/theme.js +6 -5
- package/dist/core/used-extent.d.ts +44 -0
- package/dist/core/used-extent.js +102 -0
- package/dist/core/value.d.ts +9 -0
- package/dist/core/value.js +36 -34
- package/dist/core/workbook-media.d.ts +34 -0
- package/dist/core/workbook-media.js +44 -0
- package/dist/core/workbook-styles.d.ts +67 -1
- package/dist/core/workbook-vba.js +3 -2
- package/dist/core/workbook.d.ts +23 -2
- package/dist/core/workbook.js +24 -40
- package/dist/core/worksheet-comments.d.ts +2 -1
- package/dist/core/worksheet-comments.js +20 -13
- package/dist/core/worksheet-merges.d.ts +44 -0
- package/dist/core/worksheet-merges.js +59 -0
- package/dist/core/worksheet-model.d.ts +9 -1
- package/dist/core/worksheet-model.js +24 -9
- package/dist/core/worksheet.d.ts +72 -12
- package/dist/core/worksheet.js +68 -70
- package/dist/customui/ribbon.js +6 -7
- package/dist/entries/core.d.ts +18 -13
- package/dist/entries/core.js +12 -6
- package/dist/entries/xlsx.d.ts +1 -1
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +22 -0
- package/dist/hex.d.ts +8 -0
- package/dist/hex.js +3 -0
- package/dist/io/csv/delimiter.d.ts +9 -0
- package/dist/io/csv/delimiter.js +6 -0
- package/dist/io/csv/read.js +11 -4
- package/dist/io/csv/write.d.ts +9 -2
- package/dist/io/csv/write.js +9 -38
- package/dist/io/opc/inflate.js +15 -1
- package/dist/io/opc/namespaces.d.ts +16 -0
- package/dist/io/opc/namespaces.js +4 -0
- package/dist/io/opc/part-paths.d.ts +10 -0
- package/dist/io/opc/part-paths.js +16 -1
- package/dist/io/opc/read-opc.d.ts +69 -10
- package/dist/io/opc/read-opc.js +49 -55
- package/dist/io/opc/read-options.d.ts +5 -1
- package/dist/io/opc/rels.d.ts +1 -6
- package/dist/io/opc/rels.js +1 -4
- package/dist/io/opc/sniff-format.d.ts +3 -3
- package/dist/io/opc/sniff-format.js +2 -2
- package/dist/io/style/xf-style.d.ts +48 -2
- package/dist/io/style/xf-style.js +14 -0
- package/dist/io/xlsb/formula.d.ts +2 -2
- package/dist/io/xlsb/formula.js +49 -34
- package/dist/io/xlsb/primitives.js +8 -14
- package/dist/io/xlsb/ptg-functions.d.ts +19 -10
- package/dist/io/xlsb/ptg-functions.js +385 -596
- package/dist/io/xlsb/read-styles.js +50 -83
- package/dist/io/xlsb/read-worksheet.d.ts +20 -1
- package/dist/io/xlsb/read-worksheet.js +73 -89
- package/dist/io/xlsb/read.d.ts +6 -3
- package/dist/io/xlsb/read.js +47 -29
- package/dist/io/xlsb/record-stream.d.ts +30 -0
- package/dist/io/xlsb/record-stream.js +20 -0
- package/dist/io/xlsb/record-types.d.ts +1 -5
- package/dist/io/xlsb/record-types.js +1 -5
- package/dist/io/xlsx/cell-accumulator.d.ts +9 -2
- package/dist/io/xlsx/cell-accumulator.js +32 -9
- package/dist/io/xlsx/cell-style-resolution.d.ts +25 -0
- package/dist/io/xlsx/cell-style-resolution.js +29 -0
- package/dist/io/xlsx/cell-value.d.ts +5 -3
- package/dist/io/xlsx/cell-value.js +13 -15
- package/dist/io/xlsx/color-xml.js +3 -2
- package/dist/io/xlsx/column-budget.d.ts +26 -0
- package/dist/io/xlsx/column-budget.js +22 -0
- package/dist/io/xlsx/comments.d.ts +6 -2
- package/dist/io/xlsx/comments.js +36 -31
- package/dist/io/xlsx/conditional-formatting.d.ts +9 -5
- package/dist/io/xlsx/conditional-formatting.js +51 -46
- package/dist/io/xlsx/data-validation.d.ts +9 -7
- package/dist/io/xlsx/data-validation.js +38 -35
- package/dist/io/xlsx/edit-vba.d.ts +7 -2
- package/dist/io/xlsx/edit-vba.js +15 -29
- package/dist/io/xlsx/font-xml.d.ts +7 -0
- package/dist/io/xlsx/font-xml.js +104 -0
- package/dist/io/xlsx/hyperlinks.d.ts +41 -7
- package/dist/io/xlsx/hyperlinks.js +40 -28
- package/dist/io/xlsx/images.js +24 -25
- package/dist/io/xlsx/namespaces.d.ts +16 -0
- package/dist/io/xlsx/namespaces.js +7 -0
- package/dist/io/xlsx/package-plan.d.ts +23 -3
- package/dist/io/xlsx/package-plan.js +66 -25
- package/dist/io/xlsx/part-names.d.ts +41 -0
- package/dist/io/xlsx/part-names.js +46 -0
- package/dist/io/xlsx/pivot.js +8 -7
- package/dist/io/xlsx/read-parts.d.ts +59 -0
- package/dist/io/xlsx/read-parts.js +252 -0
- package/dist/io/xlsx/read-pivot.js +3 -1
- package/dist/io/xlsx/read-repair.d.ts +26 -0
- package/dist/io/xlsx/read-repair.js +39 -0
- package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +1 -1
- package/dist/io/xlsx/{rich-runs.js → read-rich-runs.js} +7 -3
- package/dist/io/xlsx/read-rows.d.ts +18 -5
- package/dist/io/xlsx/read-rows.js +50 -37
- package/dist/io/xlsx/read-shared-strings.js +5 -3
- package/dist/io/xlsx/read-styles.d.ts +1 -6
- package/dist/io/xlsx/read-styles.js +65 -109
- package/dist/io/xlsx/read-workbook-xml.d.ts +36 -0
- package/dist/io/xlsx/read-workbook-xml.js +170 -0
- package/dist/io/xlsx/read-worksheet.d.ts +11 -1
- package/dist/io/xlsx/read-worksheet.js +51 -193
- package/dist/io/xlsx/read.d.ts +5 -13
- package/dist/io/xlsx/read.js +111 -436
- package/dist/io/xlsx/rich-text.js +1 -1
- package/dist/io/xlsx/row-position.d.ts +18 -0
- package/dist/io/xlsx/row-position.js +11 -0
- package/dist/io/xlsx/row-xml.d.ts +128 -0
- package/dist/io/xlsx/row-xml.js +203 -0
- package/dist/io/xlsx/shared-formulas.js +2 -2
- package/dist/io/xlsx/sheet-properties.d.ts +10 -1
- package/dist/io/xlsx/sheet-properties.js +166 -37
- package/dist/io/xlsx/style-elements.d.ts +43 -0
- package/dist/io/xlsx/style-elements.js +156 -0
- package/dist/io/xlsx/styles.d.ts +12 -3
- package/dist/io/xlsx/styles.js +5 -204
- package/dist/io/xlsx/tables.js +11 -14
- package/dist/io/xlsx/theme-xml.d.ts +26 -4
- package/dist/io/xlsx/theme-xml.js +107 -69
- package/dist/io/xlsx/threaded-comments.d.ts +8 -10
- package/dist/io/xlsx/threaded-comments.js +3 -1
- package/dist/io/xlsx/workbook-xml.d.ts +54 -4
- package/dist/io/xlsx/workbook-xml.js +84 -57
- package/dist/io/xlsx/worksheet-xml.d.ts +23 -70
- package/dist/io/xlsx/worksheet-xml.js +59 -242
- package/dist/io/xlsx/write-stream.d.ts +71 -16
- package/dist/io/xlsx/write-stream.js +79 -41
- package/dist/io/xlsx/write.d.ts +6 -2
- package/dist/io/xlsx/write.js +217 -153
- package/dist/rel-type.d.ts +16 -0
- package/dist/rel-type.js +6 -0
- package/dist/token-set.d.ts +28 -0
- package/dist/token-set.js +7 -0
- package/dist/vba/bytes.d.ts +14 -5
- package/dist/vba/bytes.js +16 -6
- package/dist/vba/cfb-format.d.ts +32 -0
- package/dist/vba/cfb-format.js +13 -0
- package/dist/vba/cfb-writer.d.ts +9 -0
- package/dist/vba/cfb-writer.js +28 -25
- package/dist/vba/cfb.d.ts +13 -1
- package/dist/vba/cfb.js +73 -57
- package/dist/vba/codepage.js +2 -1
- package/dist/vba/errors.d.ts +7 -0
- package/dist/vba/ms-ovba.js +79 -23
- package/dist/vba/project-editor.js +35 -40
- package/dist/vba/project.d.ts +11 -1
- package/dist/vba/project.js +40 -21
- package/dist/vba/vba-encoding.js +5 -6
- package/dist/xml/xml-attrs.d.ts +37 -0
- package/dist/xml/xml-attrs.js +30 -0
- package/dist/xml/xml-chars.d.ts +40 -0
- package/dist/xml/xml-chars.js +12 -0
- package/dist/xml/xml-namespaces.d.ts +31 -0
- package/dist/xml/xml-namespaces.js +50 -0
- package/dist/xml/xml-read.d.ts +128 -81
- package/dist/xml/xml-read.js +161 -178
- package/dist/xml/xml-scan.d.ts +78 -0
- package/dist/xml/xml-scan.js +180 -0
- package/dist/xml/xml.d.ts +29 -28
- package/dist/xml/xml.js +24 -24
- package/package.json +13 -9
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { isBorderStyle, isFillPatternType,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { ALIGNMENT_FACETS, isBorderStyle, isFillPatternType, } from '../../core/style.js';
|
|
2
|
+
import { numFinite, numInteger } from '../../xml/xml-attrs.js';
|
|
3
|
+
import { closeEmptyElements, elementSubtrees, openElements, } from '../../xml/xml-read.js';
|
|
4
|
+
import { boolStrict, boolTristate, localName, xmlEvents, } from '../../xml/xml-scan.js';
|
|
5
|
+
import { NO_PRESERVED_STYLE_TABLES, numFmtCodeFor, protectionFrom, resolveStyleTable, } from '../style/xf-style.js';
|
|
4
6
|
import { parseColor } from './color-xml.js';
|
|
7
|
+
import { applyFontChild } from './font-xml.js';
|
|
5
8
|
const BORDER_EDGE_NAMES = ['left', 'right', 'top', 'bottom', 'diagonal'];
|
|
6
9
|
const BORDER_EDGES = new Set(BORDER_EDGE_NAMES);
|
|
7
10
|
const isBorderEdgeName = (name) => BORDER_EDGES.has(name);
|
|
@@ -15,7 +18,7 @@ const STYLE_EMPTY_CLOSES = new Set([
|
|
|
15
18
|
]);
|
|
16
19
|
export function parseStyleTable(xml) {
|
|
17
20
|
if (xml === '')
|
|
18
|
-
return { cellXfs: [], namedStyles: [] };
|
|
21
|
+
return { cellXfs: [], namedStyles: [], preserved: NO_PRESERVED_STYLE_TABLES };
|
|
19
22
|
let fills = [];
|
|
20
23
|
let fonts = [];
|
|
21
24
|
let borders = [];
|
|
@@ -54,7 +57,17 @@ export function parseStyleTable(xml) {
|
|
|
54
57
|
}
|
|
55
58
|
next = events.next();
|
|
56
59
|
}
|
|
57
|
-
|
|
60
|
+
const { fragments, attributes } = elementSubtrees(xml, PRESERVED_SUBTREES);
|
|
61
|
+
const preserved = {
|
|
62
|
+
dxfs: fragments.get('dxfs') ?? [],
|
|
63
|
+
indexedColors: fragments.get('indexedColors') ?? [],
|
|
64
|
+
mruColors: fragments.get('mruColors') ?? [],
|
|
65
|
+
tableStyles: buildTableStyleTable(xml, fragments.get('tableStyles') ?? [], attributes.get('tableStyles')),
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
...resolveStyleTable({ directXfs: xfStyles, namedXfs, labels: cellStyleNames, fonts }),
|
|
69
|
+
preserved,
|
|
70
|
+
};
|
|
58
71
|
}
|
|
59
72
|
function* until(events, container) {
|
|
60
73
|
let next = events.next();
|
|
@@ -298,68 +311,6 @@ function parseCellStyles(events) {
|
|
|
298
311
|
}
|
|
299
312
|
return names;
|
|
300
313
|
}
|
|
301
|
-
export function applyFontChild(draft, local, attrs) {
|
|
302
|
-
switch (local) {
|
|
303
|
-
case 'b':
|
|
304
|
-
draft.bold = boolPresent(attrs.val);
|
|
305
|
-
break;
|
|
306
|
-
case 'i':
|
|
307
|
-
draft.italic = boolPresent(attrs.val);
|
|
308
|
-
break;
|
|
309
|
-
case 'strike':
|
|
310
|
-
draft.strike = boolPresent(attrs.val);
|
|
311
|
-
break;
|
|
312
|
-
case 'outline':
|
|
313
|
-
draft.outline = boolPresent(attrs.val);
|
|
314
|
-
break;
|
|
315
|
-
case 'u':
|
|
316
|
-
draft.underline =
|
|
317
|
-
attrs.val === undefined
|
|
318
|
-
? true
|
|
319
|
-
: attrs.val === 'none'
|
|
320
|
-
? false
|
|
321
|
-
: isNamedUnderlineStyle(attrs.val)
|
|
322
|
-
? attrs.val
|
|
323
|
-
: true;
|
|
324
|
-
break;
|
|
325
|
-
case 'vertAlign':
|
|
326
|
-
if (attrs.val !== undefined && isFontVerticalAlignment(attrs.val))
|
|
327
|
-
draft.vertAlign = attrs.val;
|
|
328
|
-
break;
|
|
329
|
-
case 'sz': {
|
|
330
|
-
const size = numFinite(attrs.val);
|
|
331
|
-
if (size !== undefined)
|
|
332
|
-
draft.size = size;
|
|
333
|
-
break;
|
|
334
|
-
}
|
|
335
|
-
case 'color':
|
|
336
|
-
draft.color = parseColor(attrs);
|
|
337
|
-
break;
|
|
338
|
-
case 'name':
|
|
339
|
-
case 'rFont':
|
|
340
|
-
if (attrs.val !== undefined)
|
|
341
|
-
draft.name = attrs.val;
|
|
342
|
-
break;
|
|
343
|
-
case 'family': {
|
|
344
|
-
const family = numInteger(attrs.val);
|
|
345
|
-
if (family !== undefined)
|
|
346
|
-
draft.family = family;
|
|
347
|
-
break;
|
|
348
|
-
}
|
|
349
|
-
case 'charset': {
|
|
350
|
-
const charset = numInteger(attrs.val);
|
|
351
|
-
if (charset !== undefined)
|
|
352
|
-
draft.charset = charset;
|
|
353
|
-
break;
|
|
354
|
-
}
|
|
355
|
-
case 'scheme':
|
|
356
|
-
if (attrs.val !== undefined && isFontScheme(attrs.val))
|
|
357
|
-
draft.scheme = attrs.val;
|
|
358
|
-
break;
|
|
359
|
-
default:
|
|
360
|
-
break;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
314
|
function resolveNumFmt(raw, custom) {
|
|
364
315
|
const id = numInteger(raw, 1);
|
|
365
316
|
return id === undefined ? undefined : numFmtCodeFor(id, custom);
|
|
@@ -389,53 +340,53 @@ function borderToStyle(draft) {
|
|
|
389
340
|
}
|
|
390
341
|
function parseAlignment(attrs) {
|
|
391
342
|
const out = {};
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
343
|
+
for (const facet of ALIGNMENT_FACETS) {
|
|
344
|
+
const raw = attrs[facet.key];
|
|
345
|
+
switch (facet.kind) {
|
|
346
|
+
case 'token':
|
|
347
|
+
if (raw !== undefined && raw !== facet.omit && facet.isValid(raw)) {
|
|
348
|
+
assignAlignmentToken(out, facet.key, raw);
|
|
349
|
+
}
|
|
350
|
+
break;
|
|
351
|
+
case 'number': {
|
|
352
|
+
const value = numFinite(raw);
|
|
353
|
+
if (value !== undefined && value !== 0)
|
|
354
|
+
out[facet.key] = value;
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
case 'flag':
|
|
358
|
+
if (boolStrict(raw))
|
|
359
|
+
out[facet.key] = true;
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
396
362
|
}
|
|
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
363
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
413
364
|
}
|
|
365
|
+
function assignAlignmentToken(out, key, raw) {
|
|
366
|
+
out[key] = raw;
|
|
367
|
+
}
|
|
414
368
|
function parseProtection(attrs) {
|
|
415
|
-
|
|
416
|
-
if (attrs.locked === '0' || attrs.locked === 'false')
|
|
417
|
-
out.locked = false;
|
|
418
|
-
if (boolStrict(attrs.hidden))
|
|
419
|
-
out.hidden = true;
|
|
420
|
-
return Object.keys(out).length > 0 ? out : undefined;
|
|
369
|
+
return protectionFrom({ locked: boolTristate(attrs.locked), hidden: boolStrict(attrs.hidden) });
|
|
421
370
|
}
|
|
422
371
|
export function parseIndexedColors(stylesXml) {
|
|
423
|
-
return
|
|
372
|
+
return capturedFragments(stylesXml, 'indexedColors');
|
|
424
373
|
}
|
|
425
374
|
export function parseMruColors(stylesXml) {
|
|
426
|
-
return
|
|
375
|
+
return capturedFragments(stylesXml, 'mruColors');
|
|
427
376
|
}
|
|
428
377
|
export function parseTableStyles(stylesXml) {
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
break;
|
|
378
|
+
const { fragments, attributes } = elementSubtrees(stylesXml, new Map([['tableStyles', 'tableStyle']]));
|
|
379
|
+
return buildTableStyleTable(stylesXml, fragments.get('tableStyles') ?? [], attributes.get('tableStyles'));
|
|
380
|
+
}
|
|
381
|
+
function buildTableStyleTable(stylesXml, styles, containerAttrs) {
|
|
382
|
+
const table = { styles: [...styles] };
|
|
383
|
+
if (containerAttrs?.defaultTableStyle !== undefined) {
|
|
384
|
+
table.defaultTableStyle = containerAttrs.defaultTableStyle;
|
|
437
385
|
}
|
|
438
|
-
|
|
386
|
+
if (containerAttrs?.defaultPivotStyle !== undefined) {
|
|
387
|
+
table.defaultPivotStyle = containerAttrs.defaultPivotStyle;
|
|
388
|
+
}
|
|
389
|
+
const namespaces = fragmentNamespaces(stylesXml, table.styles);
|
|
439
390
|
if (namespaces.length > 0)
|
|
440
391
|
table.namespaces = namespaces;
|
|
441
392
|
return table;
|
|
@@ -470,11 +421,16 @@ function fragmentNamespaces(stylesXml, fragments) {
|
|
|
470
421
|
ignorable: ignorable.has(prefix),
|
|
471
422
|
}));
|
|
472
423
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
424
|
+
const PRESERVED_SUBTREES = new Map([
|
|
425
|
+
['dxfs', 'dxf'],
|
|
426
|
+
['indexedColors', 'rgbColor'],
|
|
427
|
+
['mruColors', 'color'],
|
|
428
|
+
['tableStyles', 'tableStyle'],
|
|
429
|
+
]);
|
|
430
|
+
function capturedFragments(xml, container) {
|
|
431
|
+
const child = PRESERVED_SUBTREES.get(container);
|
|
432
|
+
if (child === undefined)
|
|
476
433
|
return [];
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
return [...inner.matchAll(pattern)].map((m) => m[0] ?? '');
|
|
434
|
+
const { fragments } = elementSubtrees(xml, new Map([[container, child]]));
|
|
435
|
+
return [...(fragments.get(container) ?? [])];
|
|
480
436
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type WorkbookProtection } from '../../core/workbook-protection.ts';
|
|
2
|
+
import type { DefinedName, Workbook, WorkbookView } from '../../core/workbook.ts';
|
|
3
|
+
import { type WorksheetState } from '../../core/worksheet.ts';
|
|
4
|
+
import { type CollectingPass, type SaxPass } from '../../xml/xml-read.ts';
|
|
5
|
+
export interface SheetEntry {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly relId: string;
|
|
8
|
+
readonly state?: WorksheetState['state'];
|
|
9
|
+
}
|
|
10
|
+
export declare function workbookSheetsPass(): CollectingPass<SheetEntry[]>;
|
|
11
|
+
export declare function workbookProtectionPass(): CollectingPass<WorkbookProtection | undefined>;
|
|
12
|
+
/**
|
|
13
|
+
* Apply `<workbookPr>`: the workbook's date system and its VBA code name.
|
|
14
|
+
*
|
|
15
|
+
* Both are read for the same reason and it is not that the model computes anything from them. The
|
|
16
|
+
* date system is what every serial in every sheet counts from, so a workbook read without it is read
|
|
17
|
+
* with every date four years and a day out; the code name is what the VBA project means by
|
|
18
|
+
* `ThisWorkbook`, so a `.xlsm` written back without it has had its macros unbound from its document.
|
|
19
|
+
* Neither has any signal in the file other than this element.
|
|
20
|
+
*/
|
|
21
|
+
export declare function workbookPropertiesPass(workbook: Workbook): SaxPass;
|
|
22
|
+
export declare function workbookViewPass(view: WorkbookView): SaxPass;
|
|
23
|
+
export interface DefinedNamesPass extends SaxPass {
|
|
24
|
+
/**
|
|
25
|
+
* The names, scoped against the sheet order.
|
|
26
|
+
*
|
|
27
|
+
* The order is supplied here rather than to the pass, and that is what lets the names ride the same
|
|
28
|
+
* scan as everything else this part carries. A scoped name's `localSheetId` indexes the sheets in
|
|
29
|
+
* declaration order, and the model's answer for index n is known only after the sheet loop has run
|
|
30
|
+
* and repaired the names it had to; resolving during the scan would have forced a second one.
|
|
31
|
+
*/
|
|
32
|
+
result(sheetOrder: readonly string[]): DefinedName[];
|
|
33
|
+
}
|
|
34
|
+
export declare function definedNamesPass(): DefinedNamesPass;
|
|
35
|
+
export declare function applyCoreProperties(workbook: Workbook, xml: string): void;
|
|
36
|
+
export declare function applyAppProperties(workbook: Workbook, xml: string): void;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { parseDateText } from '../../core/date.js';
|
|
2
|
+
import { unmangleFunctions } from '../../core/formula.js';
|
|
3
|
+
import { WORKBOOK_PROTECTION_CREDENTIAL_ATTRS, } from '../../core/workbook-protection.js';
|
|
4
|
+
import { isVisibility } from '../../core/worksheet.js';
|
|
5
|
+
import { enumToken, numInteger } from '../../xml/xml-attrs.js';
|
|
6
|
+
import { capturedText, TextCapture } from '../../xml/xml-read.js';
|
|
7
|
+
import { boolStrict, localName } from '../../xml/xml-scan.js';
|
|
8
|
+
import { relAttr } from '../opc/namespaces.js';
|
|
9
|
+
export function workbookSheetsPass() {
|
|
10
|
+
const sheets = [];
|
|
11
|
+
return {
|
|
12
|
+
handlers: {
|
|
13
|
+
onOpen(name, attrs, _selfClosing, scope) {
|
|
14
|
+
if (localName(name) !== 'sheet')
|
|
15
|
+
return;
|
|
16
|
+
const entry = {
|
|
17
|
+
name: attrs.name ?? '',
|
|
18
|
+
relId: relAttr(scope, attrs, 'id') ?? '',
|
|
19
|
+
};
|
|
20
|
+
const state = enumToken(attrs.state, isVisibility);
|
|
21
|
+
if (state !== undefined && state !== 'visible')
|
|
22
|
+
entry.state = state;
|
|
23
|
+
sheets.push(entry);
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
result: () => sheets,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function workbookProtectionPass() {
|
|
30
|
+
let found;
|
|
31
|
+
const handlers = {
|
|
32
|
+
onOpen(name, attrs) {
|
|
33
|
+
if (localName(name) !== 'workbookProtection')
|
|
34
|
+
return;
|
|
35
|
+
const protection = {};
|
|
36
|
+
if (boolStrict(attrs.lockStructure))
|
|
37
|
+
protection.lockStructure = true;
|
|
38
|
+
if (boolStrict(attrs.lockWindows))
|
|
39
|
+
protection.lockWindows = true;
|
|
40
|
+
if (boolStrict(attrs.lockRevision))
|
|
41
|
+
protection.lockRevision = true;
|
|
42
|
+
const credentials = {};
|
|
43
|
+
for (const key of WORKBOOK_PROTECTION_CREDENTIAL_ATTRS) {
|
|
44
|
+
const value = attrs[key];
|
|
45
|
+
if (value !== undefined)
|
|
46
|
+
credentials[key] = value;
|
|
47
|
+
}
|
|
48
|
+
if (Object.keys(credentials).length > 0)
|
|
49
|
+
protection.credentials = credentials;
|
|
50
|
+
found = protection;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
return { handlers, result: () => found };
|
|
54
|
+
}
|
|
55
|
+
export function workbookPropertiesPass(workbook) {
|
|
56
|
+
let seen = false;
|
|
57
|
+
return {
|
|
58
|
+
handlers: {
|
|
59
|
+
onOpen(name, attrs) {
|
|
60
|
+
if (seen || localName(name) !== 'workbookPr')
|
|
61
|
+
return;
|
|
62
|
+
seen = true;
|
|
63
|
+
if (boolStrict(attrs.date1904))
|
|
64
|
+
workbook.dateEpoch = 1904;
|
|
65
|
+
if (attrs.codeName !== undefined)
|
|
66
|
+
workbook.codeName = attrs.codeName;
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export function workbookViewPass(view) {
|
|
72
|
+
let seen = false;
|
|
73
|
+
return {
|
|
74
|
+
handlers: {
|
|
75
|
+
onOpen(name, attrs) {
|
|
76
|
+
if (seen || localName(name) !== 'workbookView')
|
|
77
|
+
return;
|
|
78
|
+
seen = true;
|
|
79
|
+
const x = numInteger(attrs.xWindow);
|
|
80
|
+
if (x !== undefined)
|
|
81
|
+
view.x = x;
|
|
82
|
+
const y = numInteger(attrs.yWindow);
|
|
83
|
+
if (y !== undefined)
|
|
84
|
+
view.y = y;
|
|
85
|
+
const width = numInteger(attrs.windowWidth, 0);
|
|
86
|
+
if (width !== undefined)
|
|
87
|
+
view.width = width;
|
|
88
|
+
const height = numInteger(attrs.windowHeight, 0);
|
|
89
|
+
if (height !== undefined)
|
|
90
|
+
view.height = height;
|
|
91
|
+
const activeTab = numInteger(attrs.activeTab, 0);
|
|
92
|
+
if (activeTab !== undefined)
|
|
93
|
+
view.activeTab = activeTab;
|
|
94
|
+
const visibility = enumToken(attrs.visibility, isVisibility);
|
|
95
|
+
if (visibility !== undefined && visibility !== 'visible')
|
|
96
|
+
view.visibility = visibility;
|
|
97
|
+
if (boolStrict(attrs.minimized))
|
|
98
|
+
view.minimized = true;
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export function definedNamesPass() {
|
|
104
|
+
const drafts = [];
|
|
105
|
+
const refersTo = new TextCapture('definedName');
|
|
106
|
+
let pending;
|
|
107
|
+
return {
|
|
108
|
+
handlers: {
|
|
109
|
+
onOpen(name, attrs, selfClosing) {
|
|
110
|
+
if (localName(name) !== 'definedName' || attrs.name === undefined)
|
|
111
|
+
return;
|
|
112
|
+
if (attrs.name === '_xlnm._FilterDatabase')
|
|
113
|
+
return;
|
|
114
|
+
refersTo.open(localName(name), selfClosing);
|
|
115
|
+
pending = { name: attrs.name, localSheetId: numInteger(attrs.localSheetId, 0) ?? -1 };
|
|
116
|
+
if (attrs.comment !== undefined)
|
|
117
|
+
pending.comment = attrs.comment;
|
|
118
|
+
if (boolStrict(attrs.hidden))
|
|
119
|
+
pending.hidden = true;
|
|
120
|
+
},
|
|
121
|
+
onText(chunk) {
|
|
122
|
+
refersTo.text(chunk);
|
|
123
|
+
},
|
|
124
|
+
onClose(name) {
|
|
125
|
+
const text = refersTo.close(localName(name));
|
|
126
|
+
if (text === undefined || pending === undefined)
|
|
127
|
+
return;
|
|
128
|
+
drafts.push({ ...pending, refersTo: unmangleFunctions(text) });
|
|
129
|
+
pending = undefined;
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
closeEmptyElements: new Set(['definedName']),
|
|
133
|
+
result(sheetOrder) {
|
|
134
|
+
return drafts.map(({ localSheetId, ...draft }) => {
|
|
135
|
+
const scope = sheetOrder[localSheetId];
|
|
136
|
+
return scope === undefined ? draft : { ...draft, scope };
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const CORE_PROPERTY_LOCAL_NAMES = new Set([
|
|
142
|
+
'title',
|
|
143
|
+
'creator',
|
|
144
|
+
'lastModifiedBy',
|
|
145
|
+
'created',
|
|
146
|
+
'modified',
|
|
147
|
+
]);
|
|
148
|
+
export function applyCoreProperties(workbook, xml) {
|
|
149
|
+
for (const { local, text } of capturedText(xml, CORE_PROPERTY_LOCAL_NAMES)) {
|
|
150
|
+
if (local === 'title')
|
|
151
|
+
workbook.properties.title = text;
|
|
152
|
+
else if (local === 'creator')
|
|
153
|
+
workbook.properties.creator = text;
|
|
154
|
+
else if (local === 'lastModifiedBy')
|
|
155
|
+
workbook.properties.lastModifiedBy = text;
|
|
156
|
+
else {
|
|
157
|
+
const date = parseDateText(text);
|
|
158
|
+
if (date !== null) {
|
|
159
|
+
if (local === 'created')
|
|
160
|
+
workbook.properties.created = date;
|
|
161
|
+
else
|
|
162
|
+
workbook.properties.modified = date;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
export function applyAppProperties(workbook, xml) {
|
|
168
|
+
for (const { text } of capturedText(xml, 'Company'))
|
|
169
|
+
workbook.properties.company = text;
|
|
170
|
+
}
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
+
import type { DateEpoch } from '../../core/date.ts';
|
|
1
2
|
import type { Worksheet } from '../../core/worksheet.ts';
|
|
3
|
+
import { type SaxPass } from '../../xml/xml-read.ts';
|
|
2
4
|
import type { XfStyle } from '../style/xf-style.ts';
|
|
3
5
|
import type { SharedString } from './cell-value.ts';
|
|
4
|
-
|
|
6
|
+
/**
|
|
7
|
+
* A pass reading a worksheet part into `sheet`: cells and their styles, the column and row metadata,
|
|
8
|
+
* merges, the autofilter, page breaks, and the view and print layout. It commits as it goes rather
|
|
9
|
+
* than gathering, so it has nothing to hand back once the parse ends.
|
|
10
|
+
*
|
|
11
|
+
* Offered as a pass because the worksheet is the largest part in a package and four other readers
|
|
12
|
+
* want the same events, so the five share one parse of it rather than scanning it once each.
|
|
13
|
+
*/
|
|
14
|
+
export declare function worksheetPass(sheet: Worksheet, sharedStrings: readonly SharedString[], xfStyles: ReadonlyArray<XfStyle>, dateEpoch: DateEpoch): SaxPass;
|