@shbernal/ts-xlsx 2.0.0 → 2.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 +20 -10
- package/dist/bytes.d.ts +24 -0
- package/dist/bytes.js +34 -0
- package/dist/core/address.d.ts +26 -4
- package/dist/core/address.js +21 -9
- package/dist/core/autofilter.d.ts +11 -0
- package/dist/core/autofilter.js +35 -10
- package/dist/core/color-resolution.d.ts +1 -1
- package/dist/core/color-resolution.js +7 -8
- package/dist/core/conditional-formatting-overlay.d.ts +5 -0
- package/dist/core/conditional-formatting-overlay.js +11 -0
- package/dist/core/conditional-formatting.d.ts +45 -5
- package/dist/core/conditional-formatting.js +88 -0
- package/dist/core/data-validation-overlay.d.ts +11 -0
- package/dist/core/data-validation-overlay.js +21 -2
- package/dist/core/data-validation.d.ts +9 -2
- package/dist/core/data-validation.js +34 -0
- package/dist/core/grid-edits.d.ts +16 -0
- package/dist/core/grid-edits.js +26 -8
- package/dist/core/grid-shift.d.ts +19 -0
- package/dist/core/grid-shift.js +8 -0
- package/dist/core/image.d.ts +2 -0
- package/dist/core/image.js +4 -0
- package/dist/core/merge.d.ts +12 -1
- package/dist/core/merge.js +36 -2
- package/dist/core/page-setup.d.ts +16 -2
- package/dist/core/page-setup.js +8 -1
- package/dist/core/pivot-table.d.ts +2 -0
- package/dist/core/pivot-table.js +25 -16
- package/dist/core/protection.d.ts +3 -0
- package/dist/core/protection.js +20 -14
- package/dist/core/row-input.d.ts +7 -0
- package/dist/core/row-input.js +10 -8
- package/dist/core/style.d.ts +27 -0
- package/dist/core/style.js +82 -67
- package/dist/core/table.d.ts +25 -11
- package/dist/core/table.js +67 -31
- package/dist/core/theme.d.ts +3 -1
- package/dist/core/theme.js +4 -0
- package/dist/core/workbook.d.ts +2 -2
- package/dist/core/worksheet-comments.d.ts +8 -0
- package/dist/core/worksheet-comments.js +18 -0
- package/dist/core/worksheet.d.ts +15 -2
- package/dist/core/worksheet.js +28 -48
- package/dist/customui/ribbon.js +24 -23
- package/dist/entries/core.d.ts +3 -3
- package/dist/entries/csv.d.ts +1 -1
- package/dist/entries/node-unavailable.d.ts +15 -0
- package/dist/entries/node-unavailable.js +20 -0
- package/dist/entries/node.d.ts +1 -0
- package/dist/entries/node.js +1 -0
- package/dist/entries/xlsx.d.ts +0 -1
- package/dist/entries/xlsx.js +0 -1
- package/dist/io/csv/read.js +1 -1
- package/dist/io/csv/write.d.ts +12 -2
- package/dist/io/csv/write.js +17 -2
- package/dist/io/opc/inflate.js +2 -12
- package/dist/io/opc/rels.d.ts +11 -0
- package/dist/io/opc/rels.js +3 -2
- package/dist/io/style/xf-style.d.ts +7 -2
- package/dist/io/style/xf-style.js +6 -1
- package/dist/io/xlsx/cell-accumulator.d.ts +1 -3
- package/dist/io/xlsx/cell-accumulator.js +20 -58
- package/dist/io/xlsx/cell-value.d.ts +1 -1
- package/dist/io/xlsx/cell-value.js +7 -4
- package/dist/io/xlsx/color-xml.d.ts +1 -1
- package/dist/io/xlsx/color-xml.js +7 -6
- package/dist/io/xlsx/comments.js +4 -2
- package/dist/io/xlsx/conditional-formatting.d.ts +1 -1
- package/dist/io/xlsx/conditional-formatting.js +60 -45
- package/dist/io/xlsx/data-validation.d.ts +1 -1
- package/dist/io/xlsx/data-validation.js +35 -33
- package/dist/io/xlsx/hyperlinks.js +6 -14
- package/dist/io/xlsx/images.js +19 -22
- package/dist/io/xlsx/read-pivot.js +2 -8
- package/dist/io/xlsx/read-shared-strings.js +8 -47
- package/dist/io/xlsx/read-styles.js +2 -1
- package/dist/io/xlsx/read-worksheet.js +14 -16
- package/dist/io/xlsx/read.d.ts +1 -1
- package/dist/io/xlsx/read.js +44 -74
- package/dist/io/xlsx/rich-runs.d.ts +41 -7
- package/dist/io/xlsx/rich-runs.js +94 -30
- package/dist/io/xlsx/sheet-properties.d.ts +1 -1
- package/dist/io/xlsx/sheet-properties.js +13 -9
- package/dist/io/xlsx/styles.d.ts +3 -15
- package/dist/io/xlsx/styles.js +63 -88
- package/dist/io/xlsx/tables.js +13 -13
- package/dist/io/xlsx/theme-xml.js +7 -4
- package/dist/io/xlsx/threaded-comments.js +19 -19
- package/dist/io/xlsx/workbook-xml.js +14 -8
- package/dist/io/xlsx/worksheet-xml.js +34 -37
- package/dist/io/xlsx/write-stream.d.ts +8 -1
- package/dist/io/xlsx/write-stream.js +10 -11
- package/dist/sha512.d.ts +2 -0
- package/dist/sha512.js +146 -0
- package/dist/vba/bytes.d.ts +1 -2
- package/dist/vba/bytes.js +1 -12
- package/dist/vba/dir-records.d.ts +53 -0
- package/dist/vba/dir-records.js +28 -0
- package/dist/vba/project-editor.js +5 -34
- package/dist/vba/project.js +2 -18
- package/dist/xml/xml-read.d.ts +60 -0
- package/dist/xml/xml-read.js +47 -0
- package/dist/xml/xml.d.ts +43 -1
- package/dist/xml/xml.js +17 -5
- package/package.json +21 -4
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
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 { isPageOrder, isPageOrientation, } from '../../core/page-setup.js';
|
|
4
5
|
import { SHEET_PROTECTION_FLAGS, } from '../../core/protection.js';
|
|
5
6
|
import { assignStyleFacets } from '../../core/style.js';
|
|
6
|
-
import { boolPresent, boolStrict, boolTristate, decodeSpreadsheetText, localName, numFinite, numInteger, parseXml, } from '../../xml/xml-read.js';
|
|
7
|
+
import { boolPresent, boolStrict, boolTristate, decodeSpreadsheetText, enumToken, localName, numFinite, numInteger, parseXml, } from '../../xml/xml-read.js';
|
|
7
8
|
import { CellAccumulator } from './cell-accumulator.js';
|
|
8
9
|
import { parseColor } from './color-xml.js';
|
|
9
10
|
const MARGIN_SIDES = ['left', 'right', 'top', 'bottom', 'header', 'footer'];
|
|
@@ -90,13 +91,13 @@ class AutoFilterAccumulator {
|
|
|
90
91
|
commit(sheet) {
|
|
91
92
|
if (this.#ref === null)
|
|
92
93
|
return;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
const decoded = tryDecodeRange(this.#ref);
|
|
95
|
+
const left = decoded?.left;
|
|
96
|
+
const right = decoded?.right;
|
|
97
|
+
if (left !== undefined && right !== undefined) {
|
|
98
|
+
const width = right - left + 1;
|
|
96
99
|
sheet.autoFilter = { ref: this.#ref, columns: this.#columns.filter((c) => c.colId < width) };
|
|
97
100
|
}
|
|
98
|
-
catch {
|
|
99
|
-
}
|
|
100
101
|
this.#ref = null;
|
|
101
102
|
this.#columns = [];
|
|
102
103
|
}
|
|
@@ -214,9 +215,6 @@ export function parseWorksheet(xml, sheet, sharedStrings, xfStyles) {
|
|
|
214
215
|
case 'customFilter':
|
|
215
216
|
autoFilter.addCustom(attrs);
|
|
216
217
|
break;
|
|
217
|
-
default:
|
|
218
|
-
cell.runs.applyProperty(local, attrs);
|
|
219
|
-
break;
|
|
220
218
|
}
|
|
221
219
|
},
|
|
222
220
|
onText(chunk) {
|
|
@@ -384,10 +382,10 @@ function applyPageSetup(pageSetup, attrs) {
|
|
|
384
382
|
const fitToHeight = numInteger(attrs.fitToHeight, 0);
|
|
385
383
|
if (fitToHeight !== undefined)
|
|
386
384
|
pageSetup.fitToHeight = fitToHeight;
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
385
|
+
const pageOrder = enumToken(attrs.pageOrder, isPageOrder);
|
|
386
|
+
if (pageOrder !== undefined)
|
|
387
|
+
pageSetup.pageOrder = pageOrder;
|
|
388
|
+
const orientation = enumToken(attrs.orientation, isPageOrientation);
|
|
389
|
+
if (orientation !== undefined)
|
|
390
|
+
pageSetup.orientation = orientation;
|
|
393
391
|
}
|
package/dist/io/xlsx/read.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Workbook, type WorkbookView } from '../../core/workbook.ts';
|
|
2
|
-
import type
|
|
2
|
+
import { type WorksheetState } from '../../core/worksheet.ts';
|
|
3
3
|
import { type ReadXlsxOptions } from '../opc/read-options.ts';
|
|
4
4
|
export { parseRelationships, resolveWorkbookPart } from '../opc/read-opc.ts';
|
|
5
5
|
export { DEFAULT_MAX_UNCOMPRESSED, type ReadXlsxOptions } from '../opc/read-options.ts';
|
package/dist/io/xlsx/read.js
CHANGED
|
@@ -3,7 +3,8 @@ import { unmangleFunctions } from '../../core/formula.js';
|
|
|
3
3
|
import { INTERNAL } from '../../core/internal.js';
|
|
4
4
|
import { WORKBOOK_PROTECTION_CREDENTIAL_ATTRS, } from '../../core/workbook-protection.js';
|
|
5
5
|
import { Workbook } from '../../core/workbook.js';
|
|
6
|
-
import {
|
|
6
|
+
import { isVisibility } from '../../core/worksheet.js';
|
|
7
|
+
import { boolStrict, capturedText, enumToken, localName, numInteger, openElements, parseXml, } from '../../xml/xml-read.js';
|
|
7
8
|
import { UnsupportedFormatError } from '../opc/errors.js';
|
|
8
9
|
import { extensionOf } from '../opc/part-paths.js';
|
|
9
10
|
import { capturePartClosure, contentTypeResolver, packageAccessors, parseRelationshipRecords, parseRelationships, readPartRelationships, relationshipTargetByType, resolveRelativePart, resolveWorkbookPart, } from '../opc/read-opc.js';
|
|
@@ -143,8 +144,19 @@ function readSheetPrinterSettings(sheetRels, pkg) {
|
|
|
143
144
|
const path = sheetRels.targetPath('printerSettings');
|
|
144
145
|
return path === undefined ? undefined : pkg.partBytes(path);
|
|
145
146
|
}
|
|
147
|
+
function internImage(workbook, pkg, imageIdByMediaPath, mediaPath) {
|
|
148
|
+
const known = imageIdByMediaPath.get(mediaPath);
|
|
149
|
+
if (known !== undefined)
|
|
150
|
+
return known;
|
|
151
|
+
const bytes = pkg.partBytes(mediaPath);
|
|
152
|
+
if (bytes === undefined)
|
|
153
|
+
return undefined;
|
|
154
|
+
const id = workbook.addImage({ buffer: bytes, extension: extensionOf(mediaPath) });
|
|
155
|
+
imageIdByMediaPath.set(mediaPath, id);
|
|
156
|
+
return id;
|
|
157
|
+
}
|
|
146
158
|
function readSheetImages(sheetRels, pkg, workbook, sheet, imageIdByMediaPath) {
|
|
147
|
-
const { partText
|
|
159
|
+
const { partText } = pkg;
|
|
148
160
|
const drawingPath = sheetRels.targetPath('drawing');
|
|
149
161
|
if (drawingPath === undefined)
|
|
150
162
|
return;
|
|
@@ -159,14 +171,9 @@ function readSheetImages(sheetRels, pkg, workbook, sheet, imageIdByMediaPath) {
|
|
|
159
171
|
if (embedded === undefined)
|
|
160
172
|
continue;
|
|
161
173
|
const mediaPath = drawingRels.pathOf(embedded.target);
|
|
162
|
-
|
|
163
|
-
if (id === undefined)
|
|
164
|
-
|
|
165
|
-
if (bytes === undefined)
|
|
166
|
-
continue;
|
|
167
|
-
id = workbook.addImage({ buffer: bytes, extension: extensionOf(mediaPath) });
|
|
168
|
-
imageIdByMediaPath.set(mediaPath, id);
|
|
169
|
-
}
|
|
174
|
+
const id = internImage(workbook, pkg, imageIdByMediaPath, mediaPath);
|
|
175
|
+
if (id === undefined)
|
|
176
|
+
continue;
|
|
170
177
|
const rot = anchor.rotation !== undefined ? { rotation: anchor.rotation } : {};
|
|
171
178
|
if (anchor.to !== undefined) {
|
|
172
179
|
const mode = anchor.editAs !== undefined ? { editAs: anchor.editAs } : {};
|
|
@@ -181,15 +188,9 @@ function readSheetBackground(sheetRels, pkg, workbook, sheet, imageIdByMediaPath
|
|
|
181
188
|
const mediaPath = sheetRels.targetPath('image');
|
|
182
189
|
if (mediaPath === undefined)
|
|
183
190
|
return;
|
|
184
|
-
|
|
185
|
-
if (id
|
|
186
|
-
|
|
187
|
-
if (bytes === undefined)
|
|
188
|
-
return;
|
|
189
|
-
id = workbook.addImage({ buffer: bytes, extension: extensionOf(mediaPath) });
|
|
190
|
-
imageIdByMediaPath.set(mediaPath, id);
|
|
191
|
-
}
|
|
192
|
-
sheet.addBackgroundImage(id);
|
|
191
|
+
const id = internImage(workbook, pkg, imageIdByMediaPath, mediaPath);
|
|
192
|
+
if (id !== undefined)
|
|
193
|
+
sheet.addBackgroundImage(id);
|
|
193
194
|
}
|
|
194
195
|
function readSheetPreservedReferences(sheetRels, sheetXml, pkg, contentTypeOf, sheet) {
|
|
195
196
|
const { partText, partBytes } = pkg;
|
|
@@ -337,8 +338,9 @@ export function parseWorkbookSheets(xml) {
|
|
|
337
338
|
name: attrs.name ?? '',
|
|
338
339
|
relId: attrs['r:id'] ?? '',
|
|
339
340
|
};
|
|
340
|
-
|
|
341
|
-
|
|
341
|
+
const state = enumToken(attrs.state, isVisibility);
|
|
342
|
+
if (state !== undefined && state !== 'visible')
|
|
343
|
+
entry.state = state;
|
|
342
344
|
sheets.push(entry);
|
|
343
345
|
}
|
|
344
346
|
return sheets;
|
|
@@ -386,9 +388,9 @@ export function applyWorkbookView(view, xml) {
|
|
|
386
388
|
const activeTab = numInteger(attrs.activeTab, 0);
|
|
387
389
|
if (activeTab !== undefined)
|
|
388
390
|
view.activeTab = activeTab;
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
391
|
+
const visibility = enumToken(attrs.visibility, isVisibility);
|
|
392
|
+
if (visibility !== undefined && visibility !== 'visible')
|
|
393
|
+
view.visibility = visibility;
|
|
392
394
|
if (boolStrict(attrs.minimized))
|
|
393
395
|
view.minimized = true;
|
|
394
396
|
return;
|
|
@@ -439,57 +441,25 @@ const CORE_PROPERTY_LOCAL_NAMES = new Set([
|
|
|
439
441
|
'modified',
|
|
440
442
|
]);
|
|
441
443
|
function applyCoreProperties(workbook, xml) {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
if (
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
return;
|
|
457
|
-
if (capture === 'title')
|
|
458
|
-
workbook.properties.title = text;
|
|
459
|
-
else if (capture === 'creator')
|
|
460
|
-
workbook.properties.creator = text;
|
|
461
|
-
else if (capture === 'lastModifiedBy')
|
|
462
|
-
workbook.properties.lastModifiedBy = text;
|
|
463
|
-
else {
|
|
464
|
-
const date = new Date(text);
|
|
465
|
-
if (!Number.isNaN(date.getTime())) {
|
|
466
|
-
if (capture === 'created')
|
|
467
|
-
workbook.properties.created = date;
|
|
468
|
-
else
|
|
469
|
-
workbook.properties.modified = date;
|
|
470
|
-
}
|
|
444
|
+
for (const { local, text } of capturedText(xml, CORE_PROPERTY_LOCAL_NAMES)) {
|
|
445
|
+
if (local === 'title')
|
|
446
|
+
workbook.properties.title = text;
|
|
447
|
+
else if (local === 'creator')
|
|
448
|
+
workbook.properties.creator = text;
|
|
449
|
+
else if (local === 'lastModifiedBy')
|
|
450
|
+
workbook.properties.lastModifiedBy = text;
|
|
451
|
+
else {
|
|
452
|
+
const date = new Date(text);
|
|
453
|
+
if (!Number.isNaN(date.getTime())) {
|
|
454
|
+
if (local === 'created')
|
|
455
|
+
workbook.properties.created = date;
|
|
456
|
+
else
|
|
457
|
+
workbook.properties.modified = date;
|
|
471
458
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
475
461
|
}
|
|
476
462
|
function applyAppProperties(workbook, xml) {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
parseXml(xml, {
|
|
480
|
-
onOpen(name) {
|
|
481
|
-
capture = localName(name) === 'Company';
|
|
482
|
-
text = '';
|
|
483
|
-
},
|
|
484
|
-
onText(chunk) {
|
|
485
|
-
if (capture)
|
|
486
|
-
text += chunk;
|
|
487
|
-
},
|
|
488
|
-
onClose(name) {
|
|
489
|
-
if (!capture || localName(name) !== 'Company')
|
|
490
|
-
return;
|
|
491
|
-
workbook.properties.company = text;
|
|
492
|
-
capture = false;
|
|
493
|
-
},
|
|
494
|
-
});
|
|
463
|
+
for (const { text } of capturedText(xml, 'Company'))
|
|
464
|
+
workbook.properties.company = text;
|
|
495
465
|
}
|
|
@@ -1,13 +1,47 @@
|
|
|
1
1
|
import type { RichTextRun } from '../../core/value.ts';
|
|
2
|
-
import type
|
|
2
|
+
import { type XmlAttributes } from '../../xml/xml-read.ts';
|
|
3
|
+
/**
|
|
4
|
+
* What {@link RunAccumulator.close} did with an element: `'container'` means the `<si>`/`<is>` itself
|
|
5
|
+
* closed and the caller should commit whatever it makes of the gathered runs, the one step the two
|
|
6
|
+
* readers do differently; `'claimed'` means the machine handled it; `'other'` leaves it to the caller.
|
|
7
|
+
*
|
|
8
|
+
* Three values rather than a boolean because both callers need to tell "the machine dealt with it"
|
|
9
|
+
* from "your string is complete", and a boolean would mean something different to each of them.
|
|
10
|
+
*/
|
|
11
|
+
export type RunClose = 'claimed' | 'container' | 'other';
|
|
3
12
|
export declare class RunAccumulator {
|
|
4
13
|
#private;
|
|
5
|
-
|
|
14
|
+
/**
|
|
15
|
+
* @param options.container the element that opens one string: `'si'` for the shared-string pool,
|
|
16
|
+
* `'is'` for an inline string in a worksheet body.
|
|
17
|
+
* @param options.readRuns whether `<r>`/`<rPr>` open a rich-text run. The buffered readers read
|
|
18
|
+
* them; the row stream deliberately does not, and with runs off every `<t>` falls through to
|
|
19
|
+
* {@link plainText}, which is exactly the documented flattening.
|
|
20
|
+
*/
|
|
21
|
+
constructor(options: {
|
|
22
|
+
readonly container: 'si' | 'is';
|
|
23
|
+
readonly readRuns: boolean;
|
|
24
|
+
});
|
|
6
25
|
/** The runs gathered so far. */
|
|
7
26
|
get runs(): RichTextRun[];
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
27
|
+
/** Whether the container held at least one `<r>`: what decides rich text from a plain string. */
|
|
28
|
+
get isRich(): boolean;
|
|
29
|
+
/** The container's own text: every `<t>` no run claimed, concatenated and already unescaped. */
|
|
30
|
+
get plainText(): string;
|
|
31
|
+
/**
|
|
32
|
+
* Open a string container by discarding whatever the last one gathered. Called for the machine's
|
|
33
|
+
* own container automatically; a caller whose own element may *hold* one (a `<c>` around an
|
|
34
|
+
* `<is>`) calls it too, or that container inherits the previous one's runs, which is the one way
|
|
35
|
+
* this accumulator can be misused.
|
|
36
|
+
*
|
|
37
|
+
* A new array is installed rather than the existing one emptied, so a value already built from the
|
|
38
|
+
* last container's runs keeps its own array.
|
|
39
|
+
*/
|
|
40
|
+
beginContainer(): void;
|
|
41
|
+
/** Drive one element open, and return whether it was one of this machine's own. */
|
|
42
|
+
open(local: string, attrs: XmlAttributes, selfClosing: boolean): boolean;
|
|
43
|
+
/** Feed one run of character data. Ignored unless a `<t>` is open. */
|
|
44
|
+
text(chunk: string): void;
|
|
45
|
+
/** Drive one element close. See {@link RunClose}. */
|
|
46
|
+
close(local: string): RunClose;
|
|
13
47
|
}
|
|
@@ -1,43 +1,107 @@
|
|
|
1
|
+
import { decodeSpreadsheetText, TextCapture } from '../../xml/xml-read.js';
|
|
1
2
|
import { applyFontChild } from './read-styles.js';
|
|
2
3
|
export class RunAccumulator {
|
|
4
|
+
#container;
|
|
5
|
+
#readRuns;
|
|
6
|
+
#capture = new TextCapture('t');
|
|
3
7
|
#runs = [];
|
|
4
8
|
#font = null;
|
|
5
|
-
#
|
|
9
|
+
#inProperties = false;
|
|
10
|
+
#runText = '';
|
|
11
|
+
#plain = '';
|
|
6
12
|
#inRun = false;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this.#
|
|
13
|
+
#isRich = false;
|
|
14
|
+
#inContainer = false;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.#container = options.container;
|
|
17
|
+
this.#readRuns = options.readRuns;
|
|
11
18
|
}
|
|
12
19
|
get runs() {
|
|
13
20
|
return this.#runs;
|
|
14
21
|
}
|
|
15
|
-
|
|
16
|
-
this.#
|
|
22
|
+
get isRich() {
|
|
23
|
+
return this.#isRich;
|
|
24
|
+
}
|
|
25
|
+
get plainText() {
|
|
26
|
+
return this.#plain;
|
|
27
|
+
}
|
|
28
|
+
beginContainer() {
|
|
29
|
+
this.#runs = [];
|
|
17
30
|
this.#font = null;
|
|
18
|
-
this.#
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (this.#inRun)
|
|
22
|
-
this.#font = {};
|
|
23
|
-
}
|
|
24
|
-
applyProperty(local, attrs) {
|
|
25
|
-
if (this.#font !== null)
|
|
26
|
-
applyFontChild(this.#font, local, attrs);
|
|
27
|
-
}
|
|
28
|
-
appendText(text) {
|
|
29
|
-
if (!this.#inRun)
|
|
30
|
-
return false;
|
|
31
|
-
this.#text += text;
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
endRun() {
|
|
35
|
-
if (!this.#inRun)
|
|
36
|
-
return;
|
|
37
|
-
const run = { text: this.#text };
|
|
38
|
-
if (this.#font !== null && Object.keys(this.#font).length > 0)
|
|
39
|
-
run.font = this.#font;
|
|
40
|
-
this.#runs.push(run);
|
|
31
|
+
this.#inProperties = false;
|
|
32
|
+
this.#runText = '';
|
|
33
|
+
this.#plain = '';
|
|
41
34
|
this.#inRun = false;
|
|
35
|
+
this.#isRich = false;
|
|
36
|
+
}
|
|
37
|
+
open(local, attrs, selfClosing) {
|
|
38
|
+
switch (local) {
|
|
39
|
+
case this.#container:
|
|
40
|
+
this.#inContainer = true;
|
|
41
|
+
this.beginContainer();
|
|
42
|
+
return true;
|
|
43
|
+
case 'r':
|
|
44
|
+
if (!this.#readRuns || !this.#inContainer)
|
|
45
|
+
return false;
|
|
46
|
+
this.#isRich = true;
|
|
47
|
+
this.#inRun = true;
|
|
48
|
+
this.#font = null;
|
|
49
|
+
this.#inProperties = false;
|
|
50
|
+
this.#runText = '';
|
|
51
|
+
return true;
|
|
52
|
+
case 'rPr':
|
|
53
|
+
if (!this.#readRuns || !this.#inRun)
|
|
54
|
+
return false;
|
|
55
|
+
this.#font = {};
|
|
56
|
+
this.#inProperties = true;
|
|
57
|
+
return true;
|
|
58
|
+
case 't':
|
|
59
|
+
this.#capture.open(local, selfClosing);
|
|
60
|
+
return true;
|
|
61
|
+
default:
|
|
62
|
+
if (!this.#inProperties || this.#font === null)
|
|
63
|
+
return false;
|
|
64
|
+
applyFontChild(this.#font, local, attrs);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
text(chunk) {
|
|
69
|
+
this.#capture.text(chunk);
|
|
70
|
+
}
|
|
71
|
+
close(local) {
|
|
72
|
+
switch (local) {
|
|
73
|
+
case 't': {
|
|
74
|
+
const text = this.#capture.close(local);
|
|
75
|
+
if (text !== undefined) {
|
|
76
|
+
const decoded = decodeSpreadsheetText(text);
|
|
77
|
+
if (this.#inRun)
|
|
78
|
+
this.#runText += decoded;
|
|
79
|
+
else if (this.#inContainer)
|
|
80
|
+
this.#plain += decoded;
|
|
81
|
+
}
|
|
82
|
+
return 'claimed';
|
|
83
|
+
}
|
|
84
|
+
case 'rPr':
|
|
85
|
+
if (!this.#readRuns || !this.#inProperties)
|
|
86
|
+
return 'other';
|
|
87
|
+
this.#inProperties = false;
|
|
88
|
+
return 'claimed';
|
|
89
|
+
case 'r': {
|
|
90
|
+
if (!this.#readRuns || !this.#inRun)
|
|
91
|
+
return 'other';
|
|
92
|
+
this.#inProperties = false;
|
|
93
|
+
const run = { text: this.#runText };
|
|
94
|
+
if (this.#font !== null && Object.keys(this.#font).length > 0)
|
|
95
|
+
run.font = this.#font;
|
|
96
|
+
this.#runs.push(run);
|
|
97
|
+
this.#inRun = false;
|
|
98
|
+
return 'claimed';
|
|
99
|
+
}
|
|
100
|
+
case this.#container:
|
|
101
|
+
this.#inContainer = false;
|
|
102
|
+
return 'container';
|
|
103
|
+
default:
|
|
104
|
+
return 'other';
|
|
105
|
+
}
|
|
42
106
|
}
|
|
43
107
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AutoFilter } from '../../core/autofilter.ts';
|
|
2
|
-
import type
|
|
2
|
+
import { type HeaderFooter, type PageBreak, type PageMargins, type PageSetup, type PrintOptions } from '../../core/page-setup.ts';
|
|
3
3
|
import { type SheetProtection } from '../../core/protection.ts';
|
|
4
4
|
import type { SheetView, Worksheet } from '../../core/worksheet.ts';
|
|
5
5
|
export declare function sheetViewsXml(view: SheetView, active: boolean): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { encodeAddress } from '../../core/address.js';
|
|
2
|
+
import { isPageOrder, isPageOrientation, } from '../../core/page-setup.js';
|
|
2
3
|
import { SHEET_PROTECTION_FLAGS } from '../../core/protection.js';
|
|
3
|
-
import {
|
|
4
|
+
import { boolAttr, checkedToken, escapeAttr, escapeSpreadsheetText, numAttr, numberText, } from '../../xml/xml.js';
|
|
4
5
|
import { colorAttrs } from './color-xml.js';
|
|
5
6
|
export function sheetViewsXml(view, active) {
|
|
6
7
|
const selected = active ? ' tabSelected="1"' : '';
|
|
@@ -127,12 +128,16 @@ export function pageMarginsXml(margins) {
|
|
|
127
128
|
return `<pageMargins ${attrs}/>`;
|
|
128
129
|
}
|
|
129
130
|
export function pageSetupXml(pageSetup, printerSettingsRelId) {
|
|
130
|
-
const attrs =
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
(pageSetup.pageOrder
|
|
135
|
-
|
|
131
|
+
const attrs = numAttr('paperSize', pageSetup.paperSize) +
|
|
132
|
+
numAttr('scale', pageSetup.scale) +
|
|
133
|
+
numAttr('fitToWidth', pageSetup.fitToWidth) +
|
|
134
|
+
numAttr('fitToHeight', pageSetup.fitToHeight) +
|
|
135
|
+
(pageSetup.pageOrder === undefined
|
|
136
|
+
? ''
|
|
137
|
+
: ` pageOrder="${checkedToken(pageSetup.pageOrder, isPageOrder, 'page order')}"`) +
|
|
138
|
+
(pageSetup.orientation === undefined
|
|
139
|
+
? ''
|
|
140
|
+
: ` orientation="${checkedToken(pageSetup.orientation, isPageOrientation, 'page orientation')}"`) +
|
|
136
141
|
(printerSettingsRelId !== null ? ` r:id="${printerSettingsRelId}"` : '');
|
|
137
142
|
return attrs === '' ? '' : `<pageSetup${attrs}/>`;
|
|
138
143
|
}
|
|
@@ -141,8 +146,7 @@ export function pageBreaksXml(breaks, element) {
|
|
|
141
146
|
return '';
|
|
142
147
|
const brks = breaks
|
|
143
148
|
.map((brk) => {
|
|
144
|
-
|
|
145
|
-
return `<brk id="${brk.id}"${maxAttr} man="1"/>`;
|
|
149
|
+
return `<brk${numAttr('id', brk.id)}${numAttr('max', brk.max)} man="1"/>`;
|
|
146
150
|
})
|
|
147
151
|
.join('');
|
|
148
152
|
return `<${element} count="${breaks.length}" manualBreakCount="${breaks.length}">${brks}</${element}>`;
|
package/dist/io/xlsx/styles.d.ts
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type DifferentialStyle, type Font, type NamedCellStyle, type TableStyleTable } from '../../core/style.ts';
|
|
2
2
|
import { type TableStyle } from '../../core/table-style.ts';
|
|
3
|
-
|
|
4
|
-
export interface CellStyle {
|
|
5
|
-
readonly fill?: Fill | undefined;
|
|
6
|
-
readonly numFmt?: string | undefined;
|
|
7
|
-
readonly font?: Font | undefined;
|
|
8
|
-
readonly border?: Border | undefined;
|
|
9
|
-
readonly alignment?: Alignment | undefined;
|
|
10
|
-
readonly protection?: Protection | undefined;
|
|
11
|
-
/** The quote-prefix flag: an attribute on the xf, not a shared sub-table entry. */
|
|
12
|
-
readonly quotePrefix?: boolean | undefined;
|
|
13
|
-
/** The `xfId` link into `cellStyleXfs`: the named cell style this format inherits from (0 = Normal). */
|
|
14
|
-
readonly xfId?: number | undefined;
|
|
15
|
-
}
|
|
3
|
+
import type { XfStyle } from '../style/xf-style.ts';
|
|
16
4
|
/** What a {@link StyleRegistry} needs from its workbook before any style is interned. */
|
|
17
5
|
export interface StyleRegistryOptions {
|
|
18
6
|
/**
|
|
@@ -41,7 +29,7 @@ export declare class StyleRegistry {
|
|
|
41
29
|
* The `<cellXfs>` index for a composed cell/row/column style. A style with no facet needs
|
|
42
30
|
* no entry and resolves to the default xf 0, so its owner emits no `s` attribute at all.
|
|
43
31
|
*/
|
|
44
|
-
styleId(style:
|
|
32
|
+
styleId(style: XfStyle): number;
|
|
45
33
|
/**
|
|
46
34
|
* Seed the named cell styles (`<cellStyleXfs>`/`<cellStyles>`) read from a file, in place of the
|
|
47
35
|
* lone default, interning each style's facets into the shared sub-tables so its `fillId`/`fontId`/…
|