@shbernal/ts-xlsx 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/bytes.d.ts +7 -0
- package/dist/bytes.js +22 -0
- package/dist/core/address.d.ts +60 -2
- package/dist/core/address.js +40 -24
- package/dist/core/autofilter.d.ts +4 -3
- package/dist/core/autofilter.js +31 -30
- package/dist/core/axis-handle.d.ts +2 -0
- package/dist/core/axis-handle.js +5 -2
- package/dist/core/cell.d.ts +4 -3
- package/dist/core/cell.js +4 -6
- package/dist/core/clone.d.ts +29 -0
- package/dist/core/clone.js +24 -0
- package/dist/core/color-resolution.js +2 -4
- package/dist/core/column.d.ts +1 -0
- package/dist/core/column.js +3 -0
- package/dist/core/comment-thread.js +2 -1
- package/dist/core/conditional-formatting-overlay.d.ts +2 -1
- package/dist/core/conditional-formatting-overlay.js +2 -2
- package/dist/core/conditional-formatting.d.ts +9 -1
- package/dist/core/conditional-formatting.js +34 -18
- package/dist/core/containers.d.ts +12 -0
- package/dist/core/containers.js +5 -0
- package/dist/core/data-validation-overlay.d.ts +2 -1
- package/dist/core/data-validation-overlay.js +4 -4
- package/dist/core/data-validation.d.ts +6 -0
- package/dist/core/data-validation.js +15 -4
- package/dist/core/date-format.d.ts +20 -0
- package/dist/core/date-format.js +160 -0
- package/dist/core/date.d.ts +43 -8
- package/dist/core/date.js +18 -2
- package/dist/core/formula.d.ts +26 -0
- package/dist/core/formula.js +20 -4
- package/dist/core/grid-edits.d.ts +2 -3
- package/dist/core/grid-edits.js +69 -70
- package/dist/core/grid-shift.d.ts +58 -9
- package/dist/core/grid-shift.js +26 -4
- package/dist/core/image.d.ts +13 -9
- package/dist/core/image.js +7 -5
- package/dist/core/internal.d.ts +8 -2
- package/dist/core/limits.d.ts +23 -0
- package/dist/core/limits.js +4 -0
- package/dist/core/merge.d.ts +5 -4
- package/dist/core/merge.js +18 -19
- package/dist/core/pivot-table.js +63 -45
- package/dist/core/protection.js +2 -11
- package/dist/core/range.js +34 -30
- package/dist/core/row-input.js +2 -2
- package/dist/core/row.d.ts +1 -0
- package/dist/core/row.js +3 -0
- package/dist/core/style.d.ts +85 -70
- package/dist/core/style.js +92 -28
- package/dist/core/table-style.d.ts +1 -1
- package/dist/core/table-style.js +4 -4
- package/dist/core/table.d.ts +27 -9
- package/dist/core/table.js +51 -34
- package/dist/core/theme.js +6 -5
- package/dist/core/value.d.ts +9 -0
- package/dist/core/value.js +36 -34
- package/dist/core/workbook-media.d.ts +34 -0
- package/dist/core/workbook-media.js +44 -0
- package/dist/core/workbook-styles.d.ts +67 -1
- package/dist/core/workbook-vba.js +3 -2
- package/dist/core/workbook.d.ts +23 -2
- package/dist/core/workbook.js +24 -40
- package/dist/core/worksheet-comments.d.ts +2 -1
- package/dist/core/worksheet-comments.js +20 -13
- package/dist/core/worksheet-merges.d.ts +44 -0
- package/dist/core/worksheet-merges.js +59 -0
- package/dist/core/worksheet-model.d.ts +9 -1
- package/dist/core/worksheet-model.js +24 -9
- package/dist/core/worksheet.d.ts +55 -6
- package/dist/core/worksheet.js +36 -44
- package/dist/customui/ribbon.js +2 -1
- package/dist/entries/core.d.ts +18 -13
- package/dist/entries/core.js +12 -6
- package/dist/entries/xlsx.d.ts +1 -1
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +22 -0
- package/dist/hex.d.ts +8 -0
- package/dist/hex.js +3 -0
- package/dist/io/csv/delimiter.d.ts +9 -0
- package/dist/io/csv/delimiter.js +6 -0
- package/dist/io/csv/read.js +11 -4
- package/dist/io/csv/write.d.ts +9 -2
- package/dist/io/csv/write.js +9 -38
- package/dist/io/opc/inflate.js +14 -0
- package/dist/io/opc/namespaces.d.ts +16 -0
- package/dist/io/opc/namespaces.js +4 -0
- package/dist/io/opc/part-paths.d.ts +9 -0
- package/dist/io/opc/part-paths.js +1 -1
- package/dist/io/opc/read-opc.d.ts +54 -14
- package/dist/io/opc/read-opc.js +42 -20
- package/dist/io/opc/read-options.d.ts +5 -1
- package/dist/io/opc/sniff-format.d.ts +3 -3
- package/dist/io/opc/sniff-format.js +2 -2
- package/dist/io/style/xf-style.d.ts +23 -1
- package/dist/io/style/xf-style.js +8 -0
- package/dist/io/xlsb/formula.d.ts +2 -2
- package/dist/io/xlsb/formula.js +49 -34
- package/dist/io/xlsb/primitives.js +8 -14
- package/dist/io/xlsb/ptg-functions.d.ts +19 -10
- package/dist/io/xlsb/ptg-functions.js +385 -596
- package/dist/io/xlsb/read-styles.js +45 -81
- package/dist/io/xlsb/read-worksheet.d.ts +20 -1
- package/dist/io/xlsb/read-worksheet.js +73 -89
- package/dist/io/xlsb/read.d.ts +6 -3
- package/dist/io/xlsb/read.js +44 -23
- package/dist/io/xlsb/record-stream.d.ts +30 -0
- package/dist/io/xlsb/record-stream.js +20 -0
- package/dist/io/xlsb/record-types.d.ts +1 -5
- package/dist/io/xlsb/record-types.js +1 -5
- package/dist/io/xlsx/cell-accumulator.d.ts +8 -1
- package/dist/io/xlsx/cell-accumulator.js +32 -9
- package/dist/io/xlsx/cell-style-resolution.d.ts +25 -0
- package/dist/io/xlsx/cell-style-resolution.js +29 -0
- package/dist/io/xlsx/cell-value.d.ts +5 -3
- package/dist/io/xlsx/cell-value.js +13 -15
- package/dist/io/xlsx/color-xml.js +3 -2
- package/dist/io/xlsx/column-budget.d.ts +26 -0
- package/dist/io/xlsx/column-budget.js +22 -0
- package/dist/io/xlsx/comments.d.ts +6 -2
- package/dist/io/xlsx/comments.js +36 -32
- package/dist/io/xlsx/conditional-formatting.d.ts +6 -3
- package/dist/io/xlsx/conditional-formatting.js +30 -26
- package/dist/io/xlsx/data-validation.js +29 -27
- package/dist/io/xlsx/edit-vba.d.ts +7 -2
- package/dist/io/xlsx/edit-vba.js +14 -21
- package/dist/io/xlsx/font-xml.d.ts +7 -0
- package/dist/io/xlsx/font-xml.js +104 -0
- package/dist/io/xlsx/hyperlinks.d.ts +37 -5
- package/dist/io/xlsx/hyperlinks.js +22 -13
- package/dist/io/xlsx/images.js +11 -13
- package/dist/io/xlsx/namespaces.d.ts +16 -0
- package/dist/io/xlsx/namespaces.js +7 -0
- package/dist/io/xlsx/package-plan.d.ts +14 -2
- package/dist/io/xlsx/package-plan.js +39 -11
- package/dist/io/xlsx/pivot.js +8 -7
- package/dist/io/xlsx/read-parts.d.ts +59 -0
- package/dist/io/xlsx/read-parts.js +252 -0
- package/dist/io/xlsx/read-pivot.js +2 -1
- package/dist/io/xlsx/read-repair.d.ts +26 -0
- package/dist/io/xlsx/read-repair.js +39 -0
- package/dist/io/xlsx/{rich-runs.js → read-rich-runs.js} +6 -3
- package/dist/io/xlsx/read-rows.d.ts +18 -5
- package/dist/io/xlsx/read-rows.js +45 -31
- package/dist/io/xlsx/read-shared-strings.js +3 -2
- package/dist/io/xlsx/read-styles.d.ts +1 -6
- package/dist/io/xlsx/read-styles.js +6 -71
- package/dist/io/xlsx/read-workbook-xml.d.ts +36 -0
- package/dist/io/xlsx/read-workbook-xml.js +170 -0
- package/dist/io/xlsx/read-worksheet.d.ts +2 -1
- package/dist/io/xlsx/read-worksheet.js +35 -164
- package/dist/io/xlsx/read.d.ts +5 -12
- package/dist/io/xlsx/read.js +73 -406
- package/dist/io/xlsx/rich-text.js +1 -1
- package/dist/io/xlsx/row-position.d.ts +18 -0
- package/dist/io/xlsx/row-position.js +11 -0
- package/dist/io/xlsx/row-xml.d.ts +128 -0
- package/dist/io/xlsx/row-xml.js +203 -0
- package/dist/io/xlsx/shared-formulas.js +2 -2
- package/dist/io/xlsx/sheet-properties.d.ts +10 -1
- package/dist/io/xlsx/sheet-properties.js +145 -9
- package/dist/io/xlsx/style-elements.d.ts +43 -0
- package/dist/io/xlsx/style-elements.js +156 -0
- package/dist/io/xlsx/styles.d.ts +12 -3
- package/dist/io/xlsx/styles.js +5 -207
- package/dist/io/xlsx/tables.js +10 -14
- package/dist/io/xlsx/theme-xml.d.ts +26 -4
- package/dist/io/xlsx/theme-xml.js +107 -69
- package/dist/io/xlsx/threaded-comments.d.ts +8 -10
- package/dist/io/xlsx/threaded-comments.js +2 -1
- package/dist/io/xlsx/workbook-xml.d.ts +54 -4
- package/dist/io/xlsx/workbook-xml.js +60 -34
- package/dist/io/xlsx/worksheet-xml.d.ts +23 -70
- package/dist/io/xlsx/worksheet-xml.js +48 -229
- package/dist/io/xlsx/write-stream.d.ts +65 -16
- package/dist/io/xlsx/write-stream.js +50 -20
- package/dist/io/xlsx/write.d.ts +1 -2
- package/dist/io/xlsx/write.js +114 -74
- package/dist/rel-type.d.ts +16 -0
- package/dist/rel-type.js +6 -0
- package/dist/token-set.d.ts +13 -0
- package/dist/token-set.js +4 -1
- package/dist/vba/bytes.d.ts +14 -5
- package/dist/vba/bytes.js +16 -6
- package/dist/vba/cfb-format.d.ts +8 -0
- package/dist/vba/cfb-format.js +1 -0
- package/dist/vba/cfb-writer.d.ts +9 -0
- package/dist/vba/cfb-writer.js +12 -9
- package/dist/vba/cfb.d.ts +13 -1
- package/dist/vba/cfb.js +73 -51
- package/dist/vba/codepage.js +2 -1
- package/dist/vba/errors.d.ts +7 -0
- package/dist/vba/ms-ovba.js +51 -16
- package/dist/vba/project-editor.js +35 -40
- package/dist/vba/project.d.ts +11 -1
- package/dist/vba/project.js +27 -8
- package/dist/vba/vba-encoding.js +4 -5
- package/dist/xml/xml-attrs.d.ts +37 -0
- package/dist/xml/xml-attrs.js +30 -0
- package/dist/xml/xml-chars.d.ts +40 -0
- package/dist/xml/xml-chars.js +12 -0
- package/dist/xml/xml-namespaces.d.ts +31 -0
- package/dist/xml/xml-namespaces.js +50 -0
- package/dist/xml/xml-read.d.ts +72 -10
- package/dist/xml/xml-read.js +94 -18
- package/dist/xml/xml-scan.d.ts +15 -37
- package/dist/xml/xml-scan.js +12 -40
- package/dist/xml/xml.d.ts +28 -27
- package/dist/xml/xml.js +24 -24
- package/package.json +12 -7
- /package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +0 -0
|
@@ -1,41 +1,85 @@
|
|
|
1
1
|
import { DEFAULT_THEME_COLOR_SCHEME, isThemeColorSlot, normalizeThemeColor, } from '../../core/theme.js';
|
|
2
|
-
import {
|
|
2
|
+
import { elementRange, parseXml } from '../../xml/xml-read.js';
|
|
3
|
+
import { localName } from '../../xml/xml-scan.js';
|
|
3
4
|
import { escapeAttr } from '../../xml/xml.js';
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const COLOR_ELEMENTS = new Set(['srgbClr', 'sysClr']);
|
|
6
|
+
function readThemeScheme(themeXml) {
|
|
7
|
+
const colors = {};
|
|
8
|
+
const elements = {};
|
|
9
|
+
const fonts = {};
|
|
10
|
+
let prefix = '';
|
|
11
|
+
let container;
|
|
12
|
+
let slot;
|
|
13
|
+
let fontSlot;
|
|
14
|
+
parseXml(themeXml, {
|
|
15
|
+
onOpen(name, attrs, _selfClosing, scope) {
|
|
16
|
+
const local = localName(name);
|
|
17
|
+
if (local === 'theme') {
|
|
18
|
+
const colon = name.indexOf(':');
|
|
19
|
+
prefix = colon === -1 ? '' : name.slice(0, colon + 1);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (local === 'clrScheme' || local === 'fontScheme') {
|
|
23
|
+
container = local;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (container === 'clrScheme') {
|
|
27
|
+
if (isThemeColorSlot(local)) {
|
|
28
|
+
slot = local;
|
|
29
|
+
}
|
|
30
|
+
else if (slot !== undefined && COLOR_ELEMENTS.has(local)) {
|
|
31
|
+
const value = local === 'sysClr' ? attrs.lastClr : attrs.val;
|
|
32
|
+
if (value !== undefined && /^[0-9a-fA-F]{6}$/.test(value))
|
|
33
|
+
colors[slot] = value;
|
|
34
|
+
elements[slot] = emptyElement(name, attrs);
|
|
35
|
+
slot = undefined;
|
|
36
|
+
}
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (container === 'fontScheme') {
|
|
40
|
+
if (local === 'majorFont')
|
|
41
|
+
fontSlot = 'major';
|
|
42
|
+
else if (local === 'minorFont')
|
|
43
|
+
fontSlot = 'minor';
|
|
44
|
+
else if (local === 'latin' && fontSlot !== undefined && attrs.typeface !== undefined) {
|
|
45
|
+
fonts[fontSlot] ??= attrs.typeface;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
void scope;
|
|
49
|
+
},
|
|
50
|
+
onClose(name) {
|
|
51
|
+
const local = localName(name);
|
|
52
|
+
if (local === 'clrScheme' || local === 'fontScheme') {
|
|
53
|
+
container = undefined;
|
|
54
|
+
slot = undefined;
|
|
55
|
+
fontSlot = undefined;
|
|
56
|
+
}
|
|
57
|
+
else if (local === 'majorFont' || local === 'minorFont') {
|
|
58
|
+
fontSlot = undefined;
|
|
59
|
+
}
|
|
60
|
+
else if (slot !== undefined && local === slot) {
|
|
61
|
+
slot = undefined;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
});
|
|
9
65
|
const scheme = {};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return
|
|
66
|
+
if (fonts.major !== undefined)
|
|
67
|
+
scheme.major = fonts.major;
|
|
68
|
+
if (fonts.minor !== undefined)
|
|
69
|
+
scheme.minor = fonts.minor;
|
|
70
|
+
return { colors, elements, fonts: scheme, prefix };
|
|
71
|
+
}
|
|
72
|
+
function emptyElement(name, attrs) {
|
|
73
|
+
let out = `<${name}`;
|
|
74
|
+
for (const key in attrs)
|
|
75
|
+
out += ` ${key}="${escapeAttr(attrs[key] ?? '')}"`;
|
|
76
|
+
return `${out}/>`;
|
|
77
|
+
}
|
|
78
|
+
export function parseThemeColorScheme(themeXml) {
|
|
79
|
+
return readThemeScheme(themeXml).colors;
|
|
21
80
|
}
|
|
22
81
|
export function parseThemeFontScheme(themeXml) {
|
|
23
|
-
|
|
24
|
-
if (block === null)
|
|
25
|
-
return {};
|
|
26
|
-
const face = (which) => {
|
|
27
|
-
const font = new RegExp(`<a:${which}\\b[^>]*>([\\s\\S]*?)</a:${which}>`).exec(block[1] ?? '');
|
|
28
|
-
const typeface = /<a:latin\b[^>]*\btypeface="([^"]*)"/.exec(font?.[1] ?? '')?.[1];
|
|
29
|
-
return typeface === undefined ? undefined : decodeEntities(typeface);
|
|
30
|
-
};
|
|
31
|
-
const scheme = {};
|
|
32
|
-
const major = face('majorFont');
|
|
33
|
-
const minor = face('minorFont');
|
|
34
|
-
if (major !== undefined)
|
|
35
|
-
scheme.major = major;
|
|
36
|
-
if (minor !== undefined)
|
|
37
|
-
scheme.minor = minor;
|
|
38
|
-
return scheme;
|
|
82
|
+
return readThemeScheme(themeXml).fonts;
|
|
39
83
|
}
|
|
40
84
|
const SCHEME_ELEMENT_ORDER = [
|
|
41
85
|
'dk1',
|
|
@@ -52,49 +96,43 @@ const SCHEME_ELEMENT_ORDER = [
|
|
|
52
96
|
'folHlink',
|
|
53
97
|
];
|
|
54
98
|
export function applyThemeOverrides(baseXml, overrides) {
|
|
55
|
-
|
|
99
|
+
const { elements: sourceElements, prefix } = readThemeScheme(baseXml);
|
|
100
|
+
const edits = [];
|
|
56
101
|
const colors = overrides.colors ?? {};
|
|
57
102
|
if (Object.keys(colors).length > 0) {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
103
|
+
const scheme = elementRange(baseXml, ['clrScheme']);
|
|
104
|
+
if (scheme !== undefined) {
|
|
105
|
+
const body = SCHEME_ELEMENT_ORDER.map((slot) => {
|
|
106
|
+
const authored = colors[slot];
|
|
107
|
+
const inner = authored !== undefined
|
|
108
|
+
? `<${prefix}srgbClr val="${normalizeThemeColor(authored)}"/>`
|
|
109
|
+
: (sourceElements[slot] ??
|
|
110
|
+
`<${prefix}srgbClr val="${DEFAULT_THEME_COLOR_SCHEME[slot]}"/>`);
|
|
111
|
+
return `<${prefix}${slot}>${inner}</${prefix}${slot}>`;
|
|
112
|
+
}).join('');
|
|
113
|
+
edits.push({ start: scheme.contentStart, end: scheme.contentEnd, text: body });
|
|
114
|
+
}
|
|
67
115
|
}
|
|
68
116
|
const { major, minor } = overrides.fonts ?? {};
|
|
117
|
+
const latin = (which, typeface) => {
|
|
118
|
+
const found = elementRange(baseXml, [which, 'latin']);
|
|
119
|
+
if (found === undefined)
|
|
120
|
+
return;
|
|
121
|
+
const attrs = { ...found.attrs, typeface };
|
|
122
|
+
let rendered = `<${found.name}`;
|
|
123
|
+
for (const key in attrs)
|
|
124
|
+
rendered += ` ${key}="${escapeAttr(attrs[key] ?? '')}"`;
|
|
125
|
+
edits.push({ start: found.start, end: found.end, text: `${rendered}/>` });
|
|
126
|
+
};
|
|
69
127
|
if (major !== undefined)
|
|
70
|
-
|
|
128
|
+
latin('majorFont', major);
|
|
71
129
|
if (minor !== undefined)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const block = /<a:clrScheme\b[^>]*>([\s\S]*?)<\/a:clrScheme>/.exec(themeXml);
|
|
77
|
-
if (block === null)
|
|
78
|
-
return {};
|
|
79
|
-
const elements = {};
|
|
80
|
-
const pattern = /<a:(dk1|lt1|dk2|lt2|accent[1-6]|hlink|folHlink)>([\s\S]*?)<\/a:\1>|<a:(dk1|lt1|dk2|lt2|accent[1-6]|hlink|folHlink)\/>/g;
|
|
81
|
-
for (const match of (block[1] ?? '').matchAll(pattern)) {
|
|
82
|
-
const slot = match[1] ?? match[3];
|
|
83
|
-
if (slot === undefined || !isThemeColorSlot(slot))
|
|
84
|
-
continue;
|
|
85
|
-
const inner = match[2];
|
|
86
|
-
if (inner !== undefined && inner !== '')
|
|
87
|
-
elements[slot] = inner;
|
|
130
|
+
latin('minorFont', minor);
|
|
131
|
+
let xml = baseXml;
|
|
132
|
+
for (const edit of edits.sort((a, b) => b.start - a.start)) {
|
|
133
|
+
xml = xml.slice(0, edit.start) + edit.text + xml.slice(edit.end);
|
|
88
134
|
}
|
|
89
|
-
return
|
|
90
|
-
}
|
|
91
|
-
function replaceBlockBody(xml, name, body) {
|
|
92
|
-
const pattern = new RegExp(`(<a:${name}\\b[^>]*>)[\\s\\S]*?(</a:${name}>)`);
|
|
93
|
-
return xml.replace(pattern, (_all, open, close) => `${open}${body}${close}`);
|
|
94
|
-
}
|
|
95
|
-
function replaceLatinTypeface(xml, which, typeface) {
|
|
96
|
-
const pattern = new RegExp(`(<a:${which}\\b[^>]*>[\\s\\S]*?<a:latin\\b)[^>]*(/>)`);
|
|
97
|
-
return xml.replace(pattern, (_all, open, close) => `${open} typeface="${escapeAttr(typeface)}"${close}`);
|
|
135
|
+
return xml;
|
|
98
136
|
}
|
|
99
137
|
export const DEFAULT_THEME_XML = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
|
|
100
138
|
'<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">' +
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { type CommentThread, type MentionRef, type Person } from '../../core/comment-thread.ts';
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
readonly providerId?: string;
|
|
11
|
-
}
|
|
2
|
+
/**
|
|
3
|
+
* A registered author of threaded comments: one `<person>` of `xl/persons/person.xml`, which is the
|
|
4
|
+
* model's own {@link Person} with nothing added. Declared as an alias for the same reason
|
|
5
|
+
* {@link ParsedMention} is: this file's write half already emits `Person` directly, so re-declaring
|
|
6
|
+
* the four fields here made one feature module name one shape two ways, with nothing keeping the two
|
|
7
|
+
* in step.
|
|
8
|
+
*/
|
|
9
|
+
export type ParsedPerson = Person;
|
|
12
10
|
/**
|
|
13
11
|
* One `<mention>` of a message's `<mentions>` block: the model's own {@link MentionRef}, which is
|
|
14
12
|
* exactly the four wire attributes with nothing resolved yet. Declaring it a second time here would
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { encodeAddress, tryDecodeCellRef } from '../../core/address.js';
|
|
2
2
|
import { MENTION_OFFSET_MAX, } from '../../core/comment-thread.js';
|
|
3
|
+
import { decodeSpreadsheetText, numInteger } from '../../xml/xml-attrs.js';
|
|
3
4
|
import { parseXml, TextCapture } from '../../xml/xml-read.js';
|
|
4
|
-
import { boolStrict,
|
|
5
|
+
import { boolStrict, localName } from '../../xml/xml-scan.js';
|
|
5
6
|
import { escapeAttr, escapeSpreadsheetText, textAttr, XML_DECLARATION } from '../../xml/xml.js';
|
|
6
7
|
import { THREADED_COMMENTS_NS } from './namespaces.js';
|
|
7
8
|
export function parsePersons(xml) {
|
|
@@ -3,10 +3,60 @@ import type { PivotPlan, PreservedPartPlan, PreservedRootReferencePlan, Preserve
|
|
|
3
3
|
export type PreservedWorkbookRel = PreservedWorkbookReferencePlan & {
|
|
4
4
|
readonly relId: string;
|
|
5
5
|
};
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The workbook part's relationship ids, drawn once by the writer's `assignWorkbookRelIds` and handed
|
|
8
|
+
* to every consumer rather than re-derived by any of them.
|
|
9
|
+
*
|
|
10
|
+
* Declared here because both consumers are here: the rels part wires the ids, and the workbook body
|
|
11
|
+
* *references* them from `<sheet r:id>`. The body used to spell that reference `rId${i + 1}`, which
|
|
12
|
+
* agreed with the allocator only because sheets happen to be the first ids it hands out. Anything
|
|
13
|
+
* laid ahead of them would have re-pointed every sheet at the wrong part, and the package would have
|
|
14
|
+
* stayed schema-valid while doing it -- a class of corruption no validator catches and no round-trip
|
|
15
|
+
* through this library notices, because the reader resolves the same wrong ids consistently.
|
|
16
|
+
*/
|
|
17
|
+
export interface WorkbookRelPlan {
|
|
18
|
+
readonly sheetRelIds: readonly string[];
|
|
19
|
+
readonly stylesRelId: string;
|
|
20
|
+
readonly themeRelId: string;
|
|
21
|
+
readonly sharedStringsRelId: string | null;
|
|
22
|
+
readonly personsRelId: string | null;
|
|
23
|
+
readonly preservedWorkbookRels: readonly PreservedWorkbookRel[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* What `[Content_Types].xml` needs to know about a package: every part family it declares.
|
|
27
|
+
*
|
|
28
|
+
* One object rather than twelve positional parameters, eight of them arrays and four of those bare
|
|
29
|
+
* `readonly number[]`, which two adjacent ones could be silently transposed between. That is the same
|
|
30
|
+
* hazard `SheetReferences`, `SheetPlan` and `WorksheetXmlInputs` remove elsewhere in this writer, and
|
|
31
|
+
* it travels the whole way down: the two functions that render from this take it as it stands rather
|
|
32
|
+
* than re-scattering its fields across their own parameter lists.
|
|
33
|
+
*/
|
|
34
|
+
export interface ContentTypeInputs {
|
|
35
|
+
readonly sheetCount: number;
|
|
36
|
+
readonly tables: readonly TablePlan[];
|
|
37
|
+
readonly commentNumbers: readonly number[];
|
|
38
|
+
readonly drawingNumbers: readonly number[];
|
|
39
|
+
readonly printerSettingsNumbers: readonly number[];
|
|
40
|
+
readonly mediaExtensions: readonly string[];
|
|
41
|
+
readonly hasSharedStrings: boolean;
|
|
42
|
+
readonly preservedParts: readonly PreservedPartPlan[];
|
|
43
|
+
readonly pivots: readonly PivotPlan[];
|
|
44
|
+
readonly preservedWorkbookRefs: readonly PreservedWorkbookReferencePlan[];
|
|
45
|
+
readonly threadedCommentNumbers: readonly number[];
|
|
46
|
+
readonly hasPersons: boolean;
|
|
47
|
+
}
|
|
48
|
+
export declare function contentTypesXml(inputs: ContentTypeInputs): string;
|
|
7
49
|
export declare function rootRelsXml(rootRefs: readonly PreservedRootReferencePlan[]): string;
|
|
8
|
-
export declare function workbookXml(workbook: Workbook,
|
|
9
|
-
|
|
10
|
-
|
|
50
|
+
export declare function workbookXml(workbook: Workbook, plan: WorkbookRelPlan, pivots: readonly PivotPlan[]): string;
|
|
51
|
+
/**
|
|
52
|
+
* The workbook part's `.rels`, rendered from the ids the planner drew.
|
|
53
|
+
*
|
|
54
|
+
* Every id arrives in `plan`; none is computed here. It used to re-derive the styles, theme and
|
|
55
|
+
* shared-strings ids from the sheet count and a shared constant while `write.ts` independently summed
|
|
56
|
+
* the same inputs to place everything after them, so one sequence was spelled in two files and only
|
|
57
|
+
* its fixed part was shared. The relationship *order* is still stated here, because that is what this
|
|
58
|
+
* function is; the numbering is not, because two numberings of one sequence is how they drift apart.
|
|
59
|
+
*/
|
|
60
|
+
export declare function workbookRelsXml(plan: WorkbookRelPlan, pivots: readonly PivotPlan[]): string;
|
|
11
61
|
export declare function corePropsXml(properties: WorkbookProperties): string;
|
|
12
62
|
export declare function appPropsXml(properties: WorkbookProperties): string;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { mangleFormula, quoteSheetName } from '../../core/formula.js';
|
|
2
2
|
import { WORKBOOK_PROTECTION_CREDENTIAL_ATTRS } from '../../core/workbook-protection.js';
|
|
3
3
|
import { isVisibility } from '../../core/worksheet.js';
|
|
4
|
-
import {
|
|
4
|
+
import { AuthoringError, InternalError, quoted } from '../../errors.js';
|
|
5
|
+
import { isRelType } from '../../rel-type.js';
|
|
6
|
+
import { assertWritableDate, checkedToken, escapeAttr, escapeText, numAttr, textAttr, XML_DECLARATION, } from '../../xml/xml.js';
|
|
5
7
|
import { extensionOf, THEME_PART_PATH } from '../opc/part-paths.js';
|
|
6
8
|
import { relationship, relationshipsPart } from '../opc/rels.js';
|
|
7
9
|
import { imageContentType } from './images.js';
|
|
@@ -29,15 +31,16 @@ const CT = {
|
|
|
29
31
|
threadedComments: 'application/vnd.ms-excel.threadedcomments+xml',
|
|
30
32
|
person: 'application/vnd.ms-excel.person+xml',
|
|
31
33
|
};
|
|
32
|
-
export function contentTypesXml(
|
|
33
|
-
const extensionDefaults = buildExtensionDefaults(
|
|
34
|
+
export function contentTypesXml(inputs) {
|
|
35
|
+
const extensionDefaults = buildExtensionDefaults(inputs);
|
|
34
36
|
return (XML_DECLARATION +
|
|
35
37
|
`<Types xmlns="${NS.contentTypes}">` +
|
|
36
38
|
contentTypeDefaults(extensionDefaults) +
|
|
37
|
-
contentTypeOverrides(
|
|
39
|
+
contentTypeOverrides(inputs, extensionDefaults) +
|
|
38
40
|
'</Types>');
|
|
39
41
|
}
|
|
40
|
-
function buildExtensionDefaults(
|
|
42
|
+
function buildExtensionDefaults(inputs) {
|
|
43
|
+
const { commentNumbers, printerSettingsNumbers, mediaExtensions, preservedParts } = inputs;
|
|
41
44
|
const defaults = new Map();
|
|
42
45
|
const add = (extension, contentType) => {
|
|
43
46
|
const key = extension.toLowerCase();
|
|
@@ -54,25 +57,25 @@ function buildExtensionDefaults(commentNumbers, printerSettingsNumbers, mediaExt
|
|
|
54
57
|
add(ext, imageContentType(ext));
|
|
55
58
|
for (const part of preservedParts) {
|
|
56
59
|
const ext = extensionOf(part.path);
|
|
57
|
-
if (ext
|
|
60
|
+
if (ext === 'xml')
|
|
58
61
|
continue;
|
|
59
62
|
add(ext, part.contentType);
|
|
60
63
|
}
|
|
61
64
|
return defaults;
|
|
62
65
|
}
|
|
63
66
|
function isMacroEnabled(preservedWorkbookRefs) {
|
|
64
|
-
return preservedWorkbookRefs.some((ref) => ref.relType
|
|
67
|
+
return preservedWorkbookRefs.some((ref) => isRelType(ref.relType, 'vbaProject'));
|
|
65
68
|
}
|
|
66
69
|
function contentTypeDefaults(extensionDefaults) {
|
|
67
70
|
return [...extensionDefaults.values()]
|
|
68
71
|
.map(({ extension, contentType }) => defaultType(extension, contentType))
|
|
69
72
|
.join('');
|
|
70
73
|
}
|
|
71
|
-
function contentTypeOverrides(
|
|
74
|
+
function contentTypeOverrides(inputs, extensionDefaults) {
|
|
75
|
+
const { sheetCount, tables, drawingNumbers, commentNumbers, threadedCommentNumbers, pivots, hasSharedStrings, hasPersons, preservedParts, preservedWorkbookRefs, } = inputs;
|
|
72
76
|
const preservedOverrides = preservedParts
|
|
73
77
|
.filter((part) => part.path !== THEME_PART_PATH)
|
|
74
|
-
.filter((part) => extensionDefaults.get(extensionOf(part.path)
|
|
75
|
-
part.contentType)
|
|
78
|
+
.filter((part) => extensionDefaults.get(extensionOf(part.path))?.contentType !== part.contentType)
|
|
76
79
|
.map((part) => override(part.path, part.contentType));
|
|
77
80
|
return [
|
|
78
81
|
override(WORKBOOK_PART, isMacroEnabled(preservedWorkbookRefs) ? CT.macroEnabledWorkbook : CT.workbook),
|
|
@@ -94,10 +97,10 @@ function contentTypeOverrides(sheetCount, tables, drawingNumbers, commentNumbers
|
|
|
94
97
|
].join('');
|
|
95
98
|
}
|
|
96
99
|
function override(partPath, contentType) {
|
|
97
|
-
return `<Override PartName="/${partPath}" ContentType="${contentType}"/>`;
|
|
100
|
+
return `<Override PartName="/${escapeAttr(partPath)}" ContentType="${escapeAttr(contentType)}"/>`;
|
|
98
101
|
}
|
|
99
102
|
function defaultType(extension, contentType) {
|
|
100
|
-
return `<Default Extension="${extension}" ContentType="${contentType}"/>`;
|
|
103
|
+
return `<Default Extension="${escapeAttr(extension)}" ContentType="${escapeAttr(contentType)}"/>`;
|
|
101
104
|
}
|
|
102
105
|
export function rootRelsXml(rootRefs) {
|
|
103
106
|
return relationshipsPart([
|
|
@@ -107,18 +110,25 @@ export function rootRelsXml(rootRefs) {
|
|
|
107
110
|
...rootRefs.map((ref, i) => relationship(`rId${4 + i}`, ref.relType, ref.entryPath)),
|
|
108
111
|
]);
|
|
109
112
|
}
|
|
110
|
-
export function workbookXml(workbook,
|
|
113
|
+
export function workbookXml(workbook, plan, pivots) {
|
|
114
|
+
const preservedRels = plan.preservedWorkbookRels;
|
|
111
115
|
const sheets = workbook.worksheets;
|
|
112
116
|
const entries = sheets
|
|
113
117
|
.map((sheet, i) => {
|
|
118
|
+
const relId = plan.sheetRelIds[i];
|
|
119
|
+
if (relId === undefined) {
|
|
120
|
+
throw new InternalError(`worksheet ${i + 1} of ${sheets.length} has no relationship id: the plan was drawn for ` +
|
|
121
|
+
`${plan.sheetRelIds.length} sheet(s)`);
|
|
122
|
+
}
|
|
114
123
|
const state = sheet.state === 'visible'
|
|
115
124
|
? ''
|
|
116
125
|
: ` state="${checkedToken(sheet.state, isVisibility, 'sheet visibility')}"`;
|
|
117
|
-
return `<sheet name="${escapeAttr(sheet.name)}" sheetId="${sheet.id}"${state} r:id="
|
|
126
|
+
return `<sheet name="${escapeAttr(sheet.name)}" sheetId="${sheet.id}"${state} r:id="${relId}"/>`;
|
|
118
127
|
})
|
|
119
128
|
.join('');
|
|
120
129
|
return (XML_DECLARATION +
|
|
121
130
|
`<workbook xmlns="${NS.main}" xmlns:r="${NS.docRels}">` +
|
|
131
|
+
workbookPrXml(workbook) +
|
|
122
132
|
workbookProtectionXml(workbook) +
|
|
123
133
|
bookViewsXml(workbook) +
|
|
124
134
|
`<sheets>${entries}</sheets>` +
|
|
@@ -129,6 +139,11 @@ export function workbookXml(workbook, preservedRels, pivots) {
|
|
|
129
139
|
workbookExtLstXml(preservedRels) +
|
|
130
140
|
'</workbook>');
|
|
131
141
|
}
|
|
142
|
+
function workbookPrXml(workbook) {
|
|
143
|
+
const attrs = (workbook.dateEpoch === 1904 ? ' date1904="1"' : '') +
|
|
144
|
+
(workbook.codeName === undefined ? '' : ` codeName="${escapeAttr(workbook.codeName)}"`);
|
|
145
|
+
return attrs === '' ? '' : `<workbookPr${attrs}/>`;
|
|
146
|
+
}
|
|
132
147
|
function bookViewsXml(workbook) {
|
|
133
148
|
const view = workbook.view;
|
|
134
149
|
const activeTab = workbook.activeTabIndex;
|
|
@@ -146,23 +161,23 @@ function bookViewsXml(workbook) {
|
|
|
146
161
|
function externalReferencesXml(preservedRels) {
|
|
147
162
|
const links = preservedRels
|
|
148
163
|
.filter((ref) => ref.externalReferenceIndex !== undefined)
|
|
149
|
-
.sort((a, b) => a.externalReferenceIndex - b.externalReferenceIndex);
|
|
164
|
+
.sort((a, b) => (a.externalReferenceIndex ?? 0) - (b.externalReferenceIndex ?? 0));
|
|
150
165
|
if (links.length === 0)
|
|
151
166
|
return '';
|
|
152
167
|
const entries = links.map((ref) => `<externalReference r:id="${ref.relId}"/>`).join('');
|
|
153
168
|
return `<externalReferences>${entries}</externalReferences>`;
|
|
154
169
|
}
|
|
155
170
|
function workbookExtLstXml(preservedRels) {
|
|
156
|
-
const caches = preservedRels.filter((ref) => ref.relType
|
|
171
|
+
const caches = preservedRels.filter((ref) => isRelType(ref.relType, 'slicerCache'));
|
|
157
172
|
if (caches.length === 0)
|
|
158
173
|
return '';
|
|
159
174
|
const entries = caches.map((ref) => `<x14:slicerCache r:id="${ref.relId}"/>`).join('');
|
|
160
175
|
return `<extLst>${x14Ext(SLICER_CACHES_EXT_URI, `<x14:slicerCaches>${entries}</x14:slicerCaches>`)}</extLst>`;
|
|
161
176
|
}
|
|
162
177
|
function pivotCachesXml(preservedRels, pivots) {
|
|
163
|
-
const preserved = preservedRels
|
|
164
|
-
|
|
165
|
-
|
|
178
|
+
const preserved = preservedRels.flatMap((ref) => ref.pivotCacheId === undefined
|
|
179
|
+
? []
|
|
180
|
+
: [`<pivotCache cacheId="${escapeAttr(ref.pivotCacheId)}" r:id="${ref.relId}"/>`]);
|
|
166
181
|
const generated = pivots.map((pivot) => `<pivotCache cacheId="${escapeAttr(pivot.cacheId)}" r:id="${pivot.workbookRelId}"/>`);
|
|
167
182
|
const entries = [...preserved, ...generated];
|
|
168
183
|
if (entries.length === 0)
|
|
@@ -193,12 +208,20 @@ const EXCEL_CALC_ID = '171027';
|
|
|
193
208
|
function calcPrXml(workbook) {
|
|
194
209
|
return workbook.fullCalcOnLoad ? `<calcPr calcId="${EXCEL_CALC_ID}" fullCalcOnLoad="1"/>` : '';
|
|
195
210
|
}
|
|
211
|
+
function localSheetId(sheets, name, scope) {
|
|
212
|
+
const wanted = scope.toLowerCase();
|
|
213
|
+
const index = sheets.findIndex((sheet) => sheet.name.toLowerCase() === wanted);
|
|
214
|
+
if (index === -1) {
|
|
215
|
+
throw new AuthoringError(`defined name ${quoted(name)} is scoped to worksheet ${quoted(scope)}, which this workbook does not contain`);
|
|
216
|
+
}
|
|
217
|
+
return index;
|
|
218
|
+
}
|
|
196
219
|
function definedNamesXml(workbook) {
|
|
197
220
|
const sheets = workbook.worksheets;
|
|
198
221
|
const userEntries = workbook.definedNames.map((name) => {
|
|
199
222
|
const scopeAttr = name.scope === undefined
|
|
200
223
|
? ''
|
|
201
|
-
: ` localSheetId="${sheets
|
|
224
|
+
: ` localSheetId="${localSheetId(sheets, name.name, name.scope)}"`;
|
|
202
225
|
const commentAttr = textAttr('comment', name.comment);
|
|
203
226
|
const hiddenAttr = name.hidden ? ' hidden="1"' : '';
|
|
204
227
|
return (`<definedName name="${escapeAttr(name.name)}"${scopeAttr}${commentAttr}${hiddenAttr}>` +
|
|
@@ -219,21 +242,22 @@ function filterDatabaseRefersTo(sheetName, range) {
|
|
|
219
242
|
const absolute = range.replace(/([A-Z]+)(\d+)/g, '$$$1$$$2');
|
|
220
243
|
return `${quoteSheetName(sheetName)}!${absolute}`;
|
|
221
244
|
}
|
|
222
|
-
export
|
|
223
|
-
|
|
245
|
+
export function workbookRelsXml(plan, pivots) {
|
|
246
|
+
const { personsRelId } = plan;
|
|
247
|
+
const preservedRels = plan.preservedWorkbookRels;
|
|
224
248
|
return relationshipsPart([
|
|
225
|
-
...
|
|
226
|
-
relationship(
|
|
227
|
-
relationship(
|
|
228
|
-
...(
|
|
229
|
-
? [
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
249
|
+
...plan.sheetRelIds.map((relId, i) => relationship(relId, REL.worksheet, targetFromWorkbook(worksheetPart(i + 1)))),
|
|
250
|
+
relationship(plan.stylesRelId, REL.styles, targetFromWorkbook(STYLES_PART)),
|
|
251
|
+
relationship(plan.themeRelId, REL.theme, targetFromWorkbook(THEME_PART_PATH)),
|
|
252
|
+
...(plan.sharedStringsRelId === null
|
|
253
|
+
? []
|
|
254
|
+
: [
|
|
255
|
+
relationship(plan.sharedStringsRelId, REL.sharedStrings, targetFromWorkbook(SHARED_STRINGS_PART)),
|
|
256
|
+
]),
|
|
233
257
|
...(personsRelId === null
|
|
234
258
|
? []
|
|
235
259
|
: [relationship(personsRelId, REL.person, targetFromWorkbook(PERSONS_PART))]),
|
|
236
|
-
...preservedRels.map((ref) => relationship(ref.relId, ref.relType,
|
|
260
|
+
...preservedRels.map((ref) => relationship(ref.relId, ref.relType, targetFromWorkbook(ref.entryPath))),
|
|
237
261
|
...pivots.map((pivot) => relationship(pivot.workbookRelId, REL.pivotCacheDefinition, targetFromWorkbook(pivotCacheDefinitionPart(pivot.number)))),
|
|
238
262
|
]);
|
|
239
263
|
}
|
|
@@ -248,10 +272,10 @@ export function corePropsXml(properties) {
|
|
|
248
272
|
if (properties.lastModifiedBy !== undefined) {
|
|
249
273
|
parts.push(`<cp:lastModifiedBy>${escapeText(properties.lastModifiedBy)}</cp:lastModifiedBy>`);
|
|
250
274
|
}
|
|
251
|
-
if (properties.created) {
|
|
275
|
+
if (properties.created !== undefined) {
|
|
252
276
|
parts.push(w3cdtf('created', properties.created));
|
|
253
277
|
}
|
|
254
|
-
if (properties.modified) {
|
|
278
|
+
if (properties.modified !== undefined) {
|
|
255
279
|
parts.push(w3cdtf('modified', properties.modified));
|
|
256
280
|
}
|
|
257
281
|
return (XML_DECLARATION +
|
|
@@ -261,7 +285,9 @@ export function corePropsXml(properties) {
|
|
|
261
285
|
'</cp:coreProperties>');
|
|
262
286
|
}
|
|
263
287
|
function w3cdtf(element, date) {
|
|
264
|
-
|
|
288
|
+
assertWritableDate(date, `the document property ${quoted(element)}`);
|
|
289
|
+
const stamp = date.toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
290
|
+
return `<dcterms:${element} xsi:type="dcterms:W3CDTF">${stamp}</dcterms:${element}>`;
|
|
265
291
|
}
|
|
266
292
|
export function appPropsXml(properties) {
|
|
267
293
|
const company = properties.company === undefined ? '' : `<Company>${escapeText(properties.company)}</Company>`;
|
|
@@ -1,46 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
1
|
+
import type { DateEpoch } from '../../core/date.ts';
|
|
2
|
+
import type { Worksheet } from '../../core/worksheet.ts';
|
|
3
3
|
import { type HyperlinkPlan } from './hyperlinks.ts';
|
|
4
|
-
import type {
|
|
5
|
-
import { type
|
|
4
|
+
import type { SheetPlan, TablePlan } from './package-plan.ts';
|
|
5
|
+
import { type FlushedSheet } from './row-xml.ts';
|
|
6
6
|
import type { SharedStringTable } from './shared-strings.ts';
|
|
7
7
|
import type { StyleRegistry } from './styles.ts';
|
|
8
|
-
/**
|
|
9
|
-
* The used-cell extent of a sheet: the top-left/bottom-right grid bounds that fold into the
|
|
10
|
-
* `<dimension>`. Rows carrying only formatting (a row height, an outline level) do not extend the
|
|
11
|
-
* used range, matching how Excel records `<dimension>`, so {@link add} ignores them. A fresh extent
|
|
12
|
-
* holds the `Infinity`/`-Infinity` sentinels; {@link isEmpty} reports that no used cell has been seen.
|
|
13
|
-
*/
|
|
14
|
-
export declare class Extent {
|
|
15
|
-
top: number;
|
|
16
|
-
left: number;
|
|
17
|
-
bottom: number;
|
|
18
|
-
right: number;
|
|
19
|
-
constructor(seed?: Extent);
|
|
20
|
-
/** Whether no used cell has been folded in yet, in which case the dimension is the lone cell `A1`. */
|
|
21
|
-
get isEmpty(): boolean;
|
|
22
|
-
/** Fold a rendered row's used-column span into the extent. `minCol` is `Infinity` when the row
|
|
23
|
-
* carried no cells (only formatting), which extends nothing. */
|
|
24
|
-
add(row: number, minCol: number, maxCol: number): void;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* A worksheet's eagerly-serialised rows: each row's `<row>` XML tagged with its number (so it merges
|
|
28
|
-
* into ascending order with the sheet's remaining live rows, whatever order it was committed in), plus
|
|
29
|
-
* the used-cell {@link Extent} they span. The buffered pass folds that extent into the sheet's dimension.
|
|
30
|
-
*/
|
|
31
|
-
export interface FlushedSheet {
|
|
32
|
-
readonly rows: ReadonlyArray<{
|
|
33
|
-
readonly number: number;
|
|
34
|
-
readonly xml: string;
|
|
35
|
-
}>;
|
|
36
|
-
readonly extent: Extent;
|
|
37
|
-
/**
|
|
38
|
-
* The deepest row outline level among the flushed rows. Carried across the eviction because
|
|
39
|
-
* `<sheetFormatPr outlineLevelRow>` is derived from every row on the sheet, and a flushed row's
|
|
40
|
-
* properties are gone from the model by the time the header is serialised.
|
|
41
|
-
*/
|
|
42
|
-
readonly maxRowOutlineLevel: number;
|
|
43
|
-
}
|
|
44
8
|
export interface SheetReferences {
|
|
45
9
|
readonly drawingRelId: string | null;
|
|
46
10
|
readonly legacyDrawingRelId: string | null;
|
|
@@ -49,38 +13,27 @@ export interface SheetReferences {
|
|
|
49
13
|
readonly legacyDrawingHFRelId: string | null;
|
|
50
14
|
readonly slicerRelIds: readonly string[];
|
|
51
15
|
}
|
|
52
|
-
export declare function worksheetXml(sheet: Worksheet, tables: readonly TablePlan[], styles: StyleRegistry, references: SheetReferences, hyperlinks: readonly HyperlinkPlan[], sharedStrings: SharedStringTable | null, active: boolean, flushed?: FlushedSheet): string;
|
|
53
16
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
17
|
+
* Everything one worksheet part is rendered from: the sheet itself, the parts of the package plan
|
|
18
|
+
* that belong to it, and the two registries a sheet pass interns into.
|
|
19
|
+
*
|
|
20
|
+
* One object for the reason {@link SheetReferences} is one object, applied to the layer above it: a
|
|
21
|
+
* run of positional arguments carrying two `readonly …[]`s, two nullable references and a bare
|
|
22
|
+
* boolean is a run whose order the call site cannot be read against. `active:` is the clearest of
|
|
23
|
+
* them -- as a positional it needed a comment at the call site to say which boolean it was.
|
|
58
24
|
*/
|
|
59
|
-
export
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
* outline summaries whose toggle it must stamp. The streaming writer supplies empty shared-formula
|
|
63
|
-
* and collapsed-summary sets, since those are whole-sheet derivations a flushed row cannot join. */
|
|
64
|
-
export interface RowRenderContext {
|
|
65
|
-
readonly columnDefaults: ReadonlyMap<number, ColumnProperties>;
|
|
25
|
+
export interface WorksheetXmlInputs {
|
|
26
|
+
readonly sheet: Worksheet;
|
|
27
|
+
readonly tables: readonly TablePlan[];
|
|
66
28
|
readonly styles: StyleRegistry;
|
|
29
|
+
readonly references: SheetReferences;
|
|
30
|
+
readonly hyperlinks: readonly HyperlinkPlan[];
|
|
67
31
|
readonly sharedStrings: SharedStringTable | null;
|
|
68
|
-
readonly
|
|
69
|
-
|
|
32
|
+
readonly dateEpoch: DateEpoch;
|
|
33
|
+
/** Whether this is the workbook's one selected sheet. */
|
|
34
|
+
readonly active: boolean;
|
|
35
|
+
/** The rows the streaming writer already serialised and evicted, absent on the buffered path. */
|
|
36
|
+
readonly flushed?: FlushedSheet | undefined;
|
|
70
37
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
* formatting. Returns the used-column bounds (`Infinity`/`-Infinity` when nothing was rendered) so a
|
|
74
|
-
* caller can fold them into the sheet dimension. Shared by the buffered sheet pass and the streaming
|
|
75
|
-
* writer's eager flush, so both emit byte-identical rows.
|
|
76
|
-
*/
|
|
77
|
-
export declare function renderRow(entry: {
|
|
78
|
-
readonly number: number;
|
|
79
|
-
readonly cells: readonly Cell[];
|
|
80
|
-
readonly properties: RowProperties | undefined;
|
|
81
|
-
}, ctx: RowRenderContext): {
|
|
82
|
-
xml: string;
|
|
83
|
-
minCol: number;
|
|
84
|
-
maxCol: number;
|
|
85
|
-
};
|
|
86
|
-
export declare function worksheetRelsXml(tables: readonly TablePlan[], drawing: DrawingPlan | null, comments: CommentPlan | null, threadedComments: ThreadedCommentPlan | null, printerSettings: PrinterSettingsPlan | null, background: BackgroundPlan | null, hyperlinks: readonly HyperlinkPlan[], preservedReferences: readonly PreservedReferencePlan[], pivots: readonly PivotPlan[]): string;
|
|
38
|
+
export declare function worksheetXml(inputs: WorksheetXmlInputs): string;
|
|
39
|
+
export declare function worksheetRelsXml(plan: SheetPlan): string;
|