@shbernal/ts-xlsx 1.3.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/address.d.ts +49 -2
- package/dist/core/address.js +31 -3
- package/dist/core/autofilter.d.ts +2 -2
- package/dist/core/cell.d.ts +17 -16
- package/dist/core/cell.js +3 -7
- package/dist/core/color-resolution.d.ts +7 -7
- package/dist/core/column.d.ts +8 -9
- package/dist/core/column.js +2 -4
- package/dist/core/comment-thread.d.ts +32 -23
- package/dist/core/comment-thread.js +4 -4
- package/dist/core/conditional-formatting-overlay.d.ts +1 -1
- package/dist/core/conditional-formatting.d.ts +3 -3
- package/dist/core/data-validation-overlay.d.ts +1 -1
- package/dist/core/data-validation.d.ts +3 -3
- package/dist/core/date.d.ts +3 -3
- package/dist/core/formula.d.ts +6 -6
- package/dist/core/grid-edits.js +3 -3
- package/dist/core/image.d.ts +37 -2
- package/dist/core/image.js +6 -0
- package/dist/core/internal.d.ts +9 -1
- package/dist/core/limits.d.ts +4 -4
- package/dist/core/merge.d.ts +6 -12
- package/dist/core/merge.js +0 -3
- package/dist/core/page-setup.d.ts +4 -4
- package/dist/core/pivot-table.d.ts +2 -4
- package/dist/core/pivot-table.js +5 -5
- package/dist/core/preserved.d.ts +3 -3
- package/dist/core/protection.d.ts +4 -4
- package/dist/core/range.d.ts +16 -14
- package/dist/core/range.js +5 -5
- package/dist/core/row-input.d.ts +2 -8
- package/dist/core/row-input.js +2 -2
- package/dist/core/row.d.ts +7 -8
- package/dist/core/row.js +2 -4
- package/dist/core/style.d.ts +14 -14
- package/dist/core/table-style.d.ts +9 -9
- package/dist/core/table-style.js +1 -1
- package/dist/core/table.d.ts +30 -42
- package/dist/core/table.js +16 -10
- package/dist/core/theme.d.ts +13 -43
- package/dist/core/theme.js +2 -148
- package/dist/core/value.d.ts +7 -7
- package/dist/core/workbook-protection.d.ts +2 -2
- package/dist/core/workbook-styles.d.ts +26 -0
- package/dist/core/workbook-styles.js +48 -0
- package/dist/core/workbook-theme.d.ts +25 -0
- package/dist/core/workbook-theme.js +49 -0
- package/dist/core/workbook-vba.d.ts +17 -0
- package/dist/core/workbook-vba.js +79 -0
- package/dist/core/workbook.d.ts +131 -85
- package/dist/core/workbook.js +74 -133
- package/dist/core/worksheet-comments.d.ts +9 -0
- package/dist/core/worksheet-comments.js +52 -0
- package/dist/core/worksheet-model.d.ts +4 -4
- package/dist/core/worksheet-model.js +1 -0
- package/dist/core/worksheet-pictures.d.ts +29 -0
- package/dist/core/worksheet-pictures.js +42 -0
- package/dist/core/worksheet.d.ts +85 -77
- package/dist/core/worksheet.js +36 -95
- package/dist/customui/errors.d.ts +1 -1
- package/dist/customui/ribbon.d.ts +3 -3
- package/dist/entries/core.d.ts +4 -4
- package/dist/entries/core.js +1 -1
- package/dist/entries/vba.d.ts +1 -1
- package/dist/entries/vba.js +1 -1
- package/dist/entries/xlsx.d.ts +1 -0
- package/dist/entries/xlsx.js +1 -0
- package/dist/errors.d.ts +12 -12
- package/dist/io/csv/read.js +1 -2
- package/dist/io/csv/write.d.ts +8 -3
- package/dist/io/csv/write.js +17 -2
- package/dist/io/opc/errors.d.ts +6 -6
- package/dist/io/opc/inflate.d.ts +1 -1
- package/dist/io/opc/namespaces.d.ts +1 -1
- package/dist/io/opc/read-opc.d.ts +19 -3
- package/dist/io/opc/read-opc.js +14 -8
- package/dist/io/opc/read-options.d.ts +2 -2
- package/dist/io/opc/sniff-format.d.ts +2 -2
- package/dist/io/style/xf-style.d.ts +38 -6
- package/dist/io/style/xf-style.js +22 -0
- package/dist/io/xlsb/errors.d.ts +1 -1
- package/dist/io/xlsb/formula.d.ts +4 -4
- package/dist/io/xlsb/primitives.d.ts +8 -8
- package/dist/io/xlsb/ptg-functions.d.ts +1 -1
- package/dist/io/xlsb/read-styles.js +2 -20
- package/dist/io/xlsb/read.d.ts +2 -2
- package/dist/io/xlsx/cell-accumulator.d.ts +25 -6
- package/dist/io/xlsx/cell-accumulator.js +111 -30
- package/dist/io/xlsx/cell-value.d.ts +2 -2
- package/dist/io/xlsx/cell-value.js +3 -3
- package/dist/io/xlsx/color-xml.js +11 -17
- package/dist/io/xlsx/comments.d.ts +5 -5
- package/dist/io/xlsx/comments.js +13 -6
- package/dist/io/xlsx/conditional-formatting.d.ts +3 -3
- package/dist/io/xlsx/conditional-formatting.js +7 -16
- package/dist/io/xlsx/data-validation.d.ts +2 -2
- package/dist/io/xlsx/data-validation.js +1 -1
- package/dist/io/xlsx/errors.d.ts +3 -3
- package/dist/io/xlsx/hyperlinks.d.ts +4 -2
- package/dist/io/xlsx/hyperlinks.js +5 -5
- package/dist/io/xlsx/images.d.ts +1 -1
- package/dist/io/xlsx/images.js +8 -8
- package/dist/io/xlsx/namespaces.d.ts +2 -2
- package/dist/io/xlsx/package-plan.js +5 -2
- package/dist/io/xlsx/read-pivot.js +2 -5
- package/dist/io/xlsx/read-rows.d.ts +13 -13
- package/dist/io/xlsx/read-rows.js +19 -55
- package/dist/io/xlsx/read-shared-strings.js +7 -5
- package/dist/io/xlsx/read-styles.d.ts +3 -3
- package/dist/io/xlsx/read-styles.js +40 -65
- package/dist/io/xlsx/read-worksheet.js +61 -115
- package/dist/io/xlsx/read.d.ts +3 -5
- package/dist/io/xlsx/read.js +61 -69
- package/dist/io/xlsx/rich-runs.d.ts +1 -1
- package/dist/io/xlsx/rich-runs.js +1 -1
- package/dist/io/xlsx/rich-text.d.ts +1 -1
- package/dist/io/xlsx/shared-strings.d.ts +2 -2
- package/dist/io/xlsx/sheet-properties.js +2 -2
- package/dist/io/xlsx/styles.d.ts +8 -9
- package/dist/io/xlsx/styles.js +4 -3
- package/dist/io/xlsx/tables.d.ts +2 -2
- package/dist/io/xlsx/tables.js +8 -13
- package/dist/io/xlsx/theme-xml.d.ts +37 -0
- package/dist/io/xlsx/theme-xml.js +142 -0
- package/dist/io/xlsx/threaded-comments.d.ts +18 -27
- package/dist/io/xlsx/threaded-comments.js +9 -21
- package/dist/io/xlsx/worksheet-xml.d.ts +2 -2
- package/dist/io/xlsx/worksheet-xml.js +7 -12
- package/dist/io/xlsx/write-stream.d.ts +15 -15
- package/dist/io/xlsx/write-stream.js +3 -3
- package/dist/io/xlsx/write.d.ts +8 -7
- package/dist/io/xlsx/write.js +6 -3
- package/dist/io/xlsx/x14-ext.d.ts +1 -1
- package/dist/vba/bytes.d.ts +12 -0
- package/dist/vba/bytes.js +40 -0
- package/dist/vba/cfb-writer.d.ts +1 -1
- package/dist/vba/cfb.d.ts +1 -1
- package/dist/vba/cfb.js +15 -51
- package/dist/vba/codepage.d.ts +2 -2
- package/dist/vba/errors.d.ts +2 -2
- package/dist/vba/index.d.ts +2 -2
- package/dist/vba/index.js +2 -2
- package/dist/vba/ms-ovba.d.ts +1 -1
- package/dist/vba/ms-ovba.js +1 -3
- package/dist/vba/project-editor.d.ts +9 -9
- package/dist/vba/project-editor.js +2 -11
- package/dist/vba/project.d.ts +5 -5
- package/dist/vba/project.js +1 -10
- package/dist/vba/vba-encoding.d.ts +1 -1
- package/dist/xml/errors.d.ts +1 -1
- package/dist/xml/xml-read.d.ts +38 -9
- package/dist/xml/xml-read.js +23 -0
- package/dist/xml/xml.d.ts +31 -9
- package/dist/xml/xml.js +23 -3
- package/package.json +41 -35
package/dist/core/workbook.d.ts
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import { type CustomUiDocument } from '../customui/index.ts';
|
|
2
2
|
import { type VbaLibraryReference, type VbaProject, type VbaProjectSignature } from '../vba/index.ts';
|
|
3
3
|
import { type Person } from './comment-thread.ts';
|
|
4
|
-
import { type WorkbookImage } from './image.ts';
|
|
4
|
+
import { type WorkbookImage, type WorksheetImages } from './image.ts';
|
|
5
5
|
import { INTERNAL } from './internal.ts';
|
|
6
6
|
import type { PreservedPart, PreservedRootReference } from './preserved.ts';
|
|
7
7
|
import type { Color, Font, NamedCellStyle, TableStyleTable } from './style.ts';
|
|
8
8
|
import { type TableStyle } from './table-style.ts';
|
|
9
9
|
import { type ThemeColorScheme, type ThemeFontScheme, type ThemeOverrides } from './theme.ts';
|
|
10
10
|
import type { WorkbookProtection } from './workbook-protection.ts';
|
|
11
|
+
import { type DeclaredThemeSchemes } from './workbook-theme.ts';
|
|
11
12
|
import { Worksheet, type WorksheetState } from './worksheet.ts';
|
|
12
13
|
/**
|
|
13
|
-
* A workbook-level reference to package content the model does not model
|
|
14
|
-
* (`pivotCacheDefinition`) or a slicer cache (`slicerCache`)
|
|
14
|
+
* A workbook-level reference to package content the model does not model: a pivot cache
|
|
15
|
+
* (`pivotCacheDefinition`) or a slicer cache (`slicerCache`), preserved verbatim across a round-trip
|
|
15
16
|
* instead of being dropped. `relType` is the workbook relationship Type URI to re-emit; `entryPath`
|
|
16
17
|
* is the part it points at; `parts` is the transitive closure that reference reaches (the entry
|
|
17
18
|
* included). `pivotCacheId` carries the `<pivotCache cacheId>` a pivot cache is registered under in
|
|
18
19
|
* the workbook's `<pivotCaches>`, so the wiring a pivot table resolves its cache through is re-emitted
|
|
19
20
|
* too; it is absent for a slicer cache, which the workbook lists in an extension block instead.
|
|
20
21
|
* `externalReferenceIndex` is the 0-based position of an `externalLink` within the workbook's
|
|
21
|
-
* `<externalReferences
|
|
22
|
+
* `<externalReferences>`, the `[n]` a formula or defined name resolves an external cell through, so
|
|
22
23
|
* the block is re-emitted in the original order and every `[n]` still points at the same linked
|
|
23
24
|
* workbook; it is absent for a pivot/slicer cache.
|
|
24
25
|
*/
|
|
@@ -30,14 +31,14 @@ export interface PreservedWorkbookReference {
|
|
|
30
31
|
readonly externalReferenceIndex?: number;
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
|
-
* The workbook's theme part, captured verbatim from a source package
|
|
34
|
+
* The workbook's theme part, captured verbatim from a source package: the `<clrScheme>`,
|
|
34
35
|
* `<fontScheme>`, and `<fmtScheme>` every `theme="n"` colour reference and every `scheme="major|minor"`
|
|
35
36
|
* font in the file resolves against.
|
|
36
37
|
*
|
|
37
38
|
* Held opaquely, like {@link Workbook.restoreDifferentialStyles}'s `<dxf>` fragments: the model does
|
|
38
39
|
* not interpret the theme, it only refuses to destroy it. `entryPath` is where the source package held
|
|
39
40
|
* the part (reached through the workbook's `.../theme` relationship, so not necessarily
|
|
40
|
-
* `xl/theme/theme1.xml`), and `parts` is the transitive closure it reaches
|
|
41
|
+
* `xl/theme/theme1.xml`), and `parts` is the transitive closure it reaches, the entry included. The
|
|
41
42
|
* closure matters because a theme can carry its own relationships: a picture used as a themed fill is
|
|
42
43
|
* wired by an `r:embed` into the theme's rels part, and re-emitting the theme without it would leave
|
|
43
44
|
* that reference dangling.
|
|
@@ -47,14 +48,14 @@ export interface PreservedTheme {
|
|
|
47
48
|
readonly parts: readonly PreservedPart[];
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
|
-
* The workbook's saved window state
|
|
51
|
+
* The workbook's saved window state: OOXML's `<workbookView>`, the single entry of `<bookViews>`.
|
|
51
52
|
*
|
|
52
53
|
* This is the rect a consumer restores the document window to, and the layout every pane geometry is
|
|
53
54
|
* computed against: a frozen split is positioned within it. `activeTab` names the sheet whose tab is
|
|
54
55
|
* selected on open.
|
|
55
56
|
*
|
|
56
57
|
* The position and size are in twips (1/20 of a point), Excel's window unit. A slightly negative
|
|
57
|
-
* `x`/`y` is normal and is what Excel itself writes
|
|
58
|
+
* `x`/`y` is normal and is what Excel itself writes: a maximised window's frame sits just outside the
|
|
58
59
|
* work area.
|
|
59
60
|
*/
|
|
60
61
|
export interface WorkbookView {
|
|
@@ -74,7 +75,7 @@ export interface WorkbookView {
|
|
|
74
75
|
minimized?: boolean;
|
|
75
76
|
}
|
|
76
77
|
/**
|
|
77
|
-
* The window geometry a workbook starts from
|
|
78
|
+
* The window geometry a workbook starts from: the values desktop Excel writes for its own default
|
|
78
79
|
* window.
|
|
79
80
|
*
|
|
80
81
|
* A default is emitted rather than the element left out because Excel writes `<bookViews>` into every
|
|
@@ -90,27 +91,27 @@ export declare const DEFAULT_WORKBOOK_VIEW: {
|
|
|
90
91
|
readonly activeTab: 0;
|
|
91
92
|
};
|
|
92
93
|
/**
|
|
93
|
-
* Document-level metadata
|
|
94
|
+
* Document-level metadata: what Excel's File ▸ Info panel shows. Mostly the package's core
|
|
94
95
|
* properties (`docProps/core.xml`); `company` is the exception and lives in the extended part,
|
|
95
96
|
* because that is where OOXML puts it. One interface either way: which part a field lands in is
|
|
96
97
|
* the format's business, not the caller's.
|
|
97
98
|
*/
|
|
98
99
|
export interface WorkbookProperties {
|
|
99
|
-
/**
|
|
100
|
+
/** The document's title (`dc:title`), as Excel's File ▸ Info shows it. */
|
|
100
101
|
title?: string;
|
|
101
102
|
creator?: string;
|
|
102
103
|
lastModifiedBy?: string;
|
|
103
104
|
created?: Date;
|
|
104
105
|
modified?: Date;
|
|
105
106
|
/**
|
|
106
|
-
* `Company` in the extended properties (`docProps/app.xml`), not the core ones
|
|
107
|
+
* `Company` in the extended properties (`docProps/app.xml`), not the core ones. It is the only
|
|
107
108
|
* field here that does not live beside the others, because OOXML puts it in the other part.
|
|
108
109
|
*/
|
|
109
110
|
company?: string;
|
|
110
111
|
}
|
|
111
112
|
/**
|
|
112
|
-
* A named reference in the workbook
|
|
113
|
-
* an identifier to a formula (`refersTo`), most often a cell range like `Sheet1!$A$1:$B$2` but
|
|
113
|
+
* A named reference in the workbook, one of the entries Excel surfaces in its Name Manager. A name
|
|
114
|
+
* maps an identifier to a formula (`refersTo`), most often a cell range like `Sheet1!$A$1:$B$2` but
|
|
114
115
|
* possibly any formula. A name is global to the workbook unless it names a sheet in {@link scope},
|
|
115
116
|
* which restricts it to that sheet and lets another sheet reuse the same name independently.
|
|
116
117
|
*/
|
|
@@ -133,7 +134,7 @@ export interface AddWorksheetOptions {
|
|
|
133
134
|
export interface AddImageOptions {
|
|
134
135
|
/** The image bytes. */
|
|
135
136
|
readonly buffer: Uint8Array;
|
|
136
|
-
/** The file kind
|
|
137
|
+
/** The file kind: `"png"`, `"jpeg"`/`"jpg"`, `"gif"`, … A leading dot or a URL query string is
|
|
137
138
|
* tolerated and stripped; omit it entirely to infer the kind from the bytes' magic number. */
|
|
138
139
|
readonly extension?: string;
|
|
139
140
|
}
|
|
@@ -141,7 +142,7 @@ export declare class Workbook {
|
|
|
141
142
|
#private;
|
|
142
143
|
readonly properties: WorkbookProperties;
|
|
143
144
|
/**
|
|
144
|
-
* The workbook's window state
|
|
145
|
+
* The workbook's window state: position, size, and the selected sheet. Always present (see
|
|
145
146
|
* {@link DEFAULT_WORKBOOK_VIEW} for why it is defaulted rather than left unset) and always written.
|
|
146
147
|
* Reading a file replaces it with that file's saved geometry, so a round-trip restores the window
|
|
147
148
|
* the author left rather than stamping ours over it.
|
|
@@ -150,12 +151,12 @@ export declare class Workbook {
|
|
|
150
151
|
/**
|
|
151
152
|
* Ask consuming spreadsheet apps to recalculate every formula when the file is opened, rather than
|
|
152
153
|
* trusting the cached results stored with each formula cell. Set this when the producer cannot
|
|
153
|
-
* compute formula results itself
|
|
154
|
-
* whose cached results are authoritative stays unmarked.
|
|
154
|
+
* compute formula results itself. This is the OOXML `fullCalcOnLoad` flag, off by default, so a
|
|
155
|
+
* workbook whose cached results are authoritative stays unmarked.
|
|
155
156
|
*/
|
|
156
157
|
fullCalcOnLoad: boolean;
|
|
157
158
|
/**
|
|
158
|
-
* Workbook-level structure/window protection
|
|
159
|
+
* Workbook-level structure/window protection: the OOXML `<workbookProtection>` element. Absent by
|
|
159
160
|
* default (an unprotected workbook). Set it to lock the workbook shell, or leave it as read from a
|
|
160
161
|
* file so a protected workbook stays locked across a passthrough save rather than being silently
|
|
161
162
|
* unlocked. Distinct from a worksheet's own `protect()`, which guards a single sheet's cells.
|
|
@@ -165,7 +166,7 @@ export declare class Workbook {
|
|
|
165
166
|
get worksheets(): readonly Worksheet[];
|
|
166
167
|
/**
|
|
167
168
|
* The 0-based index of the active sheet: {@link WorkbookView.activeTab} resolved against the sheets
|
|
168
|
-
* that actually exist. Exactly one sheet is always active
|
|
169
|
+
* that actually exist. Exactly one sheet is always active: an out-of-range tab (a caller's stale
|
|
169
170
|
* index, or a file whose sheet was removed after the view was saved) falls back to the first sheet
|
|
170
171
|
* rather than to none, because a package where no sheet is selected gives the consumer no view to
|
|
171
172
|
* initialise on open.
|
|
@@ -176,12 +177,12 @@ export declare class Workbook {
|
|
|
176
177
|
/** The package-root preserved references, in the order they were read. */
|
|
177
178
|
get preservedRootReferences(): readonly PreservedRootReference[];
|
|
178
179
|
/**
|
|
179
|
-
* The ribbon customisations decoded from this workbook's `customUI` parts
|
|
180
|
+
* The ribbon customisations decoded from this workbook's `customUI` parts: `customUI.xml` (Office
|
|
180
181
|
* 2007) and/or `customUI14.xml` (Office 2010+), in the order their root relationships were read. Each
|
|
181
182
|
* {@link CustomUiDocument} is tagged with its dialect and exposes the parsed `<ribbon>` tree. Empty
|
|
182
183
|
* for a workbook that customises no ribbon.
|
|
183
184
|
*
|
|
184
|
-
* This is a **read-only view** over parts the writer already round-trips verbatim
|
|
185
|
+
* This is a **read-only view** over parts the writer already round-trips verbatim. Mutating the
|
|
185
186
|
* returned objects changes nothing on write; the original `customUI` XML is re-emitted byte-for-byte
|
|
186
187
|
* regardless. Parsed lazily on first access and memoised.
|
|
187
188
|
*
|
|
@@ -191,15 +192,15 @@ export declare class Workbook {
|
|
|
191
192
|
/**
|
|
192
193
|
* The VBA project decoded from this workbook's preserved `vbaProject.bin`, or `undefined` for a
|
|
193
194
|
* workbook with no macros. This is a **read-only view** over the bytes the writer already round-trips
|
|
194
|
-
* verbatim
|
|
195
|
+
* verbatim. Mutating the returned object changes nothing on write; the original macro blob is
|
|
195
196
|
* re-emitted byte-for-byte regardless. Parsed lazily on first access and memoised.
|
|
196
197
|
*
|
|
197
198
|
* @throws {VbaParseError} if a macro project is present but its `vbaProject.bin` is malformed.
|
|
198
199
|
*/
|
|
199
200
|
get vbaProject(): VbaProject | undefined;
|
|
200
201
|
/**
|
|
201
|
-
* The raw `vbaProject.bin` bytes attached to this workbook
|
|
202
|
-
* embed
|
|
202
|
+
* The raw `vbaProject.bin` bytes attached to this workbook (the exact macro blob the writer will
|
|
203
|
+
* embed), or `undefined` for a workbook with no macros. The getter returns a defensive copy, so
|
|
203
204
|
* mutating it changes nothing on write.
|
|
204
205
|
*
|
|
205
206
|
* Assigning bytes attaches (or replaces) the macro project: the written package becomes
|
|
@@ -210,14 +211,14 @@ export declare class Workbook {
|
|
|
210
211
|
* `.bin` produced by another tool. Assigning `undefined` removes the project, reverting the workbook
|
|
211
212
|
* to a plain (non-macro) package.
|
|
212
213
|
*
|
|
213
|
-
* Replacing or removing the project also drops any digital signature the previous blob carried
|
|
214
|
-
* signature over the old bytes cannot validate new ones
|
|
215
|
-
* signature.
|
|
214
|
+
* Replacing or removing the project also drops any digital signature the previous blob carried,
|
|
215
|
+
* because a signature over the old bytes cannot validate new ones, so the result never advertises
|
|
216
|
+
* a broken signature.
|
|
216
217
|
*/
|
|
217
218
|
get vbaProjectBytes(): Uint8Array | undefined;
|
|
218
219
|
set vbaProjectBytes(bytes: Uint8Array | undefined);
|
|
219
220
|
/**
|
|
220
|
-
* Whether this workbook's VBA project carries a digital signature
|
|
221
|
+
* Whether this workbook's VBA project carries a digital signature: `true` if any signature part is
|
|
221
222
|
* attached, `false` for an unsigned project or a workbook with no macros.
|
|
222
223
|
*
|
|
223
224
|
* This reflects the **presence** of a signature blob, not its cryptographic validity: the library
|
|
@@ -231,20 +232,20 @@ export declare class Workbook {
|
|
|
231
232
|
get vbaProjectSigned(): boolean;
|
|
232
233
|
/**
|
|
233
234
|
* The digital signatures attached to this workbook's VBA project, in the order their relationships
|
|
234
|
-
* are wired off `vbaProject.bin
|
|
235
|
+
* are wired off `vbaProject.bin`. Up to three generations (legacy, agile, V3) can coexist over the
|
|
235
236
|
* same project bytes. Empty for an unsigned project or a workbook with no macros.
|
|
236
237
|
*
|
|
237
238
|
* Each entry's `bytes` are the raw signature blob passed through verbatim; the library does not parse
|
|
238
239
|
* or verify them (see {@link vbaProjectSigned} on presence-vs-validity). Hand a blob to an external
|
|
239
|
-
* verifier if you need cryptographic validation
|
|
240
|
+
* verifier if you need cryptographic validation; that is deliberately out of this library's scope.
|
|
240
241
|
*/
|
|
241
242
|
get vbaProjectSignatures(): readonly VbaProjectSignature[];
|
|
242
243
|
/**
|
|
243
|
-
* Remove a standard module from this workbook's existing macro project, in place
|
|
244
|
+
* Remove a standard module from this workbook's existing macro project, in place: a structural splice
|
|
244
245
|
* that leaves every remaining module's compiled p-code untouched (see {@link removeVbaModule}).
|
|
245
246
|
* Replacing the project also drops a stale signature, as {@link vbaProjectBytes} does.
|
|
246
247
|
*
|
|
247
|
-
* Only `procedural` and `class` modules can be removed this way
|
|
248
|
+
* Only `procedural` and `class` modules can be removed this way. See {@link removeVbaModule} for why.
|
|
248
249
|
* To author or edit module *source* (which needs real compiled p-code), use the offline
|
|
249
250
|
* `tools/vba-compiler`, then attach its output via {@link vbaProjectBytes}.
|
|
250
251
|
*
|
|
@@ -273,7 +274,7 @@ export declare class Workbook {
|
|
|
273
274
|
/** The preserved `<tableStyles>` block; `styles` is empty when the file declared no custom style. */
|
|
274
275
|
get tableStyles(): TableStyleTable;
|
|
275
276
|
/**
|
|
276
|
-
* Register a custom table style
|
|
277
|
+
* Register a custom table style: a named look a table applies to itself by putting that name in
|
|
277
278
|
* {@link TableStyleInfo.name}, exactly as it would name one of Excel's built-in gallery styles.
|
|
278
279
|
*
|
|
279
280
|
* ```ts
|
|
@@ -290,14 +291,15 @@ export declare class Workbook {
|
|
|
290
291
|
* ```
|
|
291
292
|
*
|
|
292
293
|
* Each element's formatting is interned into the workbook's shared differential-style table, so two
|
|
293
|
-
* elements
|
|
294
|
+
* elements, or a conditional-formatting rule, that paint the same way share one entry.
|
|
294
295
|
*
|
|
295
296
|
* Registering a name a source file already defined **overrides** that definition rather than adding
|
|
296
297
|
* a second one beside it.
|
|
297
298
|
*
|
|
298
|
-
* @throws {AuthoringError} if the name is empty, or an element carries a `size` outside the four
|
|
299
|
-
* types
|
|
300
|
-
*
|
|
299
|
+
* @throws {AuthoringError} if the name is empty, or an element carries a `size` outside the four
|
|
300
|
+
* stripe types. See {@link checkTableStyle} for why those are refused here rather than silently
|
|
301
|
+
* dropped.
|
|
302
|
+
* @throws {RangeError} if a `size` is not a positive integer.
|
|
301
303
|
*/
|
|
302
304
|
addTableStyle(style: TableStyle): void;
|
|
303
305
|
/** The table styles authored on this workbook, in registration order. */
|
|
@@ -309,24 +311,24 @@ export declare class Workbook {
|
|
|
309
311
|
* typefaces. Merges into what the workbook already has, so branding one accent leaves the other
|
|
310
312
|
* eleven slots alone, and calling it twice accumulates.
|
|
311
313
|
*
|
|
312
|
-
* This is the workbook-wide palette. A cell that names a colour as `theme="4"
|
|
313
|
-
* writes whenever a user picks from the theme row of the colour picker
|
|
314
|
+
* This is the workbook-wide palette. A cell that names a colour as `theme="4"`, which is what Excel
|
|
315
|
+
* writes whenever a user picks from the theme row of the colour picker, follows `accent1` here, so
|
|
314
316
|
* one call restyles every such cell, chart and table style at once. Colours are `RRGGBB`; a leading
|
|
315
317
|
* `#` and an 8-hex ARGB are both accepted and reduced, and anything else throws rather than writing
|
|
316
318
|
* a value Excel silently renders as flat black.
|
|
317
319
|
*
|
|
318
|
-
* What it does **not** touch: the theme's format scheme
|
|
319
|
-
* give a theme its texture. Those ride through from the source theme (or the library's
|
|
320
|
-
* untouched, because nobody hand-authors gradient stops from a spreadsheet API and
|
|
321
|
-
* would replace a designer's work with the Office default. For the same reason a
|
|
322
|
-
* unauthored keeps the source's own encoding, including the `<a:sysClr>` form Excel uses
|
|
323
|
-
* `dk1`/`lt1` so they follow the viewer's window colours.
|
|
320
|
+
* What it does **not** touch: the theme's format scheme, meaning the gradient, line and effect
|
|
321
|
+
* styles that give a theme its texture. Those ride through from the source theme (or the library's
|
|
322
|
+
* default) untouched, because nobody hand-authors gradient stops from a spreadsheet API and
|
|
323
|
+
* regenerating them would replace a designer's work with the Office default. For the same reason a
|
|
324
|
+
* slot left unauthored keeps the source's own encoding, including the `<a:sysClr>` form Excel uses
|
|
325
|
+
* for `dk1`/`lt1` so they follow the viewer's window colours.
|
|
324
326
|
*
|
|
325
327
|
* @throws {AuthoringError} if a colour is not 6 or 8 hexadecimal digits.
|
|
326
328
|
*/
|
|
327
329
|
setTheme(overrides: ThemeOverrides): void;
|
|
328
330
|
/**
|
|
329
|
-
* The colour scheme every `theme="n"` reference in this workbook resolves against
|
|
331
|
+
* The colour scheme every `theme="n"` reference in this workbook resolves against: anything
|
|
330
332
|
* {@link setTheme} authored, over the preserved theme's `<a:clrScheme>`, over the Office default.
|
|
331
333
|
*
|
|
332
334
|
* Note the slot *order*: `theme="0"` is `lt1` and `theme="1"` is `dk1`, which is not the order the
|
|
@@ -336,7 +338,7 @@ export declare class Workbook {
|
|
|
336
338
|
/** The theme's major (heading) and minor (body) typefaces, authored values over the source's. */
|
|
337
339
|
get themeFonts(): ThemeFontScheme;
|
|
338
340
|
/**
|
|
339
|
-
* The default font as the source package declared it
|
|
341
|
+
* The default font as the source package declared it: font id 0 of its styles part, the face every
|
|
340
342
|
* cell that names no font of its own renders in. `undefined` for a workbook authored from scratch or
|
|
341
343
|
* read from a package carrying no styles part: nothing was declared, and the library does not
|
|
342
344
|
* fabricate a declaration on the file's behalf.
|
|
@@ -346,23 +348,24 @@ export declare class Workbook {
|
|
|
346
348
|
*/
|
|
347
349
|
get declaredDefaultFont(): Font | undefined;
|
|
348
350
|
/**
|
|
349
|
-
* Author the workbook's default font
|
|
351
|
+
* Author the workbook's default font: the face, size and colour every cell with no font of its own
|
|
350
352
|
* renders in, **empty cells included**. Merges into whatever the workbook already had, so
|
|
351
353
|
* `setDefaultFont({size: 14})` keeps the resolved face and changes only the size, and calling it
|
|
352
354
|
* twice accumulates. This is the one knob that reaches a cell no row or column default can: an
|
|
353
355
|
* untouched cell in an unformatted column.
|
|
354
356
|
*
|
|
355
|
-
* It writes the styles part's font 0 and **nothing else
|
|
357
|
+
* It writes the styles part's font 0 and **nothing else**. In particular it does not rewrite the
|
|
356
358
|
* theme's body typeface. The dependency runs the other way: with no default font authored, font 0
|
|
357
359
|
* follows {@link themeFonts}'s minor face, so `setTheme({fonts: {minor}})` already reaches every
|
|
358
360
|
* unstyled cell and needs no second call here. See {@link defaultFont} for the full chain.
|
|
359
361
|
*
|
|
360
|
-
* @throws {
|
|
361
|
-
* produce a styles part Excel renders from some other font without ever reporting why.
|
|
362
|
+
* @throws {RangeError} if `size` is not a positive finite number, or `name` is empty. Both
|
|
363
|
+
* produce a styles part Excel renders from some other font without ever reporting why. Native
|
|
364
|
+
* rather than {@link AuthoringError}: one argument out of range is what `RangeError` is for.
|
|
362
365
|
*/
|
|
363
366
|
setDefaultFont(font: Font): void;
|
|
364
367
|
/**
|
|
365
|
-
* The font every cell that names none of its own renders in, resolved and complete
|
|
368
|
+
* The font every cell that names none of its own renders in, resolved and complete: what the writer
|
|
366
369
|
* emits as font id 0. Never `undefined`: a workbook always renders in *some* face, and the chain
|
|
367
370
|
* below always reaches one.
|
|
368
371
|
*
|
|
@@ -373,28 +376,28 @@ export declare class Workbook {
|
|
|
373
376
|
* The two authored levels outrank the file because authoring is an explicit act; between them
|
|
374
377
|
* {@link setDefaultFont} wins on the face because it names font 0 outright while
|
|
375
378
|
* {@link setTheme} names it only by implication. With **nothing** authored the file's own font 0
|
|
376
|
-
* passes through verbatim
|
|
377
|
-
* not: Excel writes `等线` as font 0 under a theme whose latin body face is `Calibri`, and
|
|
379
|
+
* passes through verbatim. That is deliberate, because a producer resolves that face by script and
|
|
380
|
+
* we do not: Excel writes `等线` as font 0 under a theme whose latin body face is `Calibri`, and
|
|
378
381
|
* re-deriving would silently rewrite it.
|
|
379
382
|
*
|
|
380
383
|
* `family` and `scheme` describe the *theme's* body face, so they are carried exactly while the
|
|
381
|
-
* resolved face still is that face and dropped when a caller names another
|
|
384
|
+
* resolved face still is that face and dropped when a caller names another, which is also what
|
|
382
385
|
* Excel writes: a font 0 naming a non-theme face carries no `<scheme>` at all. Either may be stated
|
|
383
386
|
* outright, in which case the caller's word stands.
|
|
384
387
|
*/
|
|
385
388
|
get defaultFont(): Font;
|
|
386
389
|
/**
|
|
387
|
-
* The
|
|
388
|
-
* source theme (or the writer's default)
|
|
390
|
+
* The colour slots and typefaces {@link setTheme} authored on this workbook, or `undefined` when
|
|
391
|
+
* none were, in which case the source theme (or the writer's default) rides through untouched.
|
|
389
392
|
*
|
|
390
|
-
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
+
* A serializer composes these *over* the existing part rather than generating one from scratch, so
|
|
394
|
+
* a preserved theme keeps its format scheme, its unauthored slots' exact encoding, and the
|
|
395
|
+
* relationships it carries.
|
|
393
396
|
*/
|
|
394
|
-
|
|
397
|
+
get themeOverrides(): ThemeOverrides | undefined;
|
|
395
398
|
/**
|
|
396
399
|
* Resolve a colour reference to a concrete 8-hex ARGB string, or `undefined` when it does not
|
|
397
|
-
* resolve to a fixed colour
|
|
400
|
+
* resolve to a fixed colour: an `auto` colour, one of the two system indexed colours, or a theme
|
|
398
401
|
* slot this workbook's scheme does not declare.
|
|
399
402
|
*
|
|
400
403
|
* This is a *derived* view, not a rewrite: the {@link Color} stays exactly as its file encoded it,
|
|
@@ -410,12 +413,12 @@ export declare class Workbook {
|
|
|
410
413
|
/** The named cell styles, in index order (index 0 is Normal); empty when only the default exists. */
|
|
411
414
|
get namedStyles(): readonly NamedCellStyle[];
|
|
412
415
|
/**
|
|
413
|
-
* Register an identity a threaded comment can name
|
|
416
|
+
* Register an identity a threaded comment can name: an author, or someone `@mentioned` in a message.
|
|
414
417
|
* A message reaches it by {@link Comment.personId}, a mention by {@link Mention.personId}.
|
|
415
418
|
*
|
|
416
419
|
* Keyed by {@link Person.id} alone, so registering the same id twice replaces the entry rather than
|
|
417
420
|
* adding a second: the id is the identity. Registering the same human twice under *different* ids is
|
|
418
|
-
* legitimate and is what Excel itself does
|
|
421
|
+
* legitimate and is what Excel itself does. See {@link restorePersons}. The id is normalised to the
|
|
419
422
|
* brace-wrapped upper-case GUID form the format requires, so a `crypto.randomUUID()` is accepted as-is.
|
|
420
423
|
*
|
|
421
424
|
* @throws {SyntaxError} if the id is not a GUID.
|
|
@@ -423,7 +426,8 @@ export declare class Workbook {
|
|
|
423
426
|
addPerson(person: Person): void;
|
|
424
427
|
/**
|
|
425
428
|
* The registered threaded-comment identities, in the order they were read. That order carries no
|
|
426
|
-
* meaning
|
|
429
|
+
* meaning, because Excel re-sorts the registry by person id when it saves, so nothing may depend
|
|
430
|
+
* on it.
|
|
427
431
|
*/
|
|
428
432
|
get persons(): readonly Person[];
|
|
429
433
|
/** Look up a registered identity by its {@link Person.id}, or `undefined` if the registry has none. */
|
|
@@ -438,13 +442,54 @@ export declare class Workbook {
|
|
|
438
442
|
get media(): readonly WorkbookImage[];
|
|
439
443
|
/** Look up a registered image by its id, or `undefined` if no image carries that id. */
|
|
440
444
|
getImage(id: number): WorkbookImage | undefined;
|
|
445
|
+
/**
|
|
446
|
+
* Every picture `sheet` shows, resolved out of this workbook's media registry into the
|
|
447
|
+
* workbook-independent form {@link importImages} consumes. `sheet` must belong to this workbook:
|
|
448
|
+
* that is whose registry its image ids index.
|
|
449
|
+
*
|
|
450
|
+
* This is the attached-part half of a sheet copy, and it is deliberately a separate call from
|
|
451
|
+
* {@link Worksheet.model}: a model is a serialisable value, an image is bytes on the workbook, and
|
|
452
|
+
* ADR-0005 keeps them apart. Carrying a sheet whole is therefore the two of them together:
|
|
453
|
+
*
|
|
454
|
+
* ```ts
|
|
455
|
+
* destination.model = source.model;
|
|
456
|
+
* destinationWorkbook.importImages(destination, sourceWorkbook.exportImages(source));
|
|
457
|
+
* ```
|
|
458
|
+
*
|
|
459
|
+
* The exported pictures share the registry's byte arrays rather than copying them: the library
|
|
460
|
+
* never mutates image bytes, and copying every picture would double the memory of an image-heavy
|
|
461
|
+
* workbook to defend against a mutation nothing performs.
|
|
462
|
+
*
|
|
463
|
+
* @throws {AuthoringError} if the sheet anchors an image id this workbook has not registered,
|
|
464
|
+
* which is what a sheet from *another* workbook looks like from here. Emitting a package with a
|
|
465
|
+
* drawing pointing at media that was never registered is the silently-broken-image failure this
|
|
466
|
+
* refuses to start.
|
|
467
|
+
*/
|
|
468
|
+
exportImages(sheet: Worksheet): WorksheetImages;
|
|
469
|
+
/**
|
|
470
|
+
* Show `images` on `sheet`, a worksheet of this workbook, registering each picture's bytes here
|
|
471
|
+
* and re-anchoring it against the id they land on. The counterpart to {@link exportImages}, and
|
|
472
|
+
* the affordance that lets a picture cross workbooks at all: an {@link AnchoredImage}'s `imageId`
|
|
473
|
+
* indexes one workbook's registry and means nothing in the next, so a raw anchor moved between
|
|
474
|
+
* workbooks points at media that does not exist there.
|
|
475
|
+
*
|
|
476
|
+
* The sheet's existing pictures are replaced, not appended to, so `importImages` is a transfer
|
|
477
|
+
* rather than an accumulation: the same direction {@link Worksheet.model} assignment goes, and
|
|
478
|
+
* what makes re-importing a sheet's own export leave it unchanged. An import whose `background` is
|
|
479
|
+
* absent clears the destination's background for the same reason.
|
|
480
|
+
*
|
|
481
|
+
* Registration is content-addressed: a picture whose bytes are already here is re-used at its
|
|
482
|
+
* existing id rather than stored twice, so importing the same sheet repeatedly, or twenty sheets
|
|
483
|
+
* sharing one logo, costs one media part.
|
|
484
|
+
*/
|
|
485
|
+
importImages(sheet: Worksheet, images: WorksheetImages): void;
|
|
441
486
|
/** The workbook's defined names, in the order they were registered. */
|
|
442
487
|
get definedNames(): readonly DefinedName[];
|
|
443
488
|
/**
|
|
444
489
|
* Register a defined name on the workbook.
|
|
445
490
|
*
|
|
446
491
|
* @throws {AuthoringError} if the name is empty, or if a {@link DefinedName.scope} is given that names no
|
|
447
|
-
* existing worksheet
|
|
492
|
+
* existing worksheet. A scoped name must target a sheet that is already part of the workbook.
|
|
448
493
|
*/
|
|
449
494
|
defineName(definedName: DefinedName): void;
|
|
450
495
|
/**
|
|
@@ -457,20 +502,20 @@ export declare class Workbook {
|
|
|
457
502
|
/** Look up a worksheet by name (case-insensitive) or by numeric id. */
|
|
458
503
|
getWorksheet(nameOrId: string | number): Worksheet | undefined;
|
|
459
504
|
/**
|
|
460
|
-
* {@link getWorksheet}, for a caller who knows the sheet is there
|
|
505
|
+
* {@link getWorksheet}, for a caller who knows the sheet is there: the miss throws instead of
|
|
461
506
|
* returning `undefined`, and the message names every sheet the workbook does have.
|
|
462
507
|
*
|
|
463
508
|
* The partial lookup is the right primitive for asking *whether* a sheet exists, and the wrong
|
|
464
509
|
* one for reaching a sheet a template is expected to carry: `undefined` flows on into a `?.`
|
|
465
510
|
* chain and fails several steps later with nothing left to say about which name was missing.
|
|
466
|
-
* That listing is the whole point
|
|
511
|
+
* That listing is the whole point: a lookup miss is a typo, a stale template or a renamed tab,
|
|
467
512
|
* and all three are answered by seeing the real names.
|
|
468
513
|
*
|
|
469
514
|
* @throws {AuthoringError} if no worksheet has that name (case-insensitive) or numeric id.
|
|
470
515
|
*/
|
|
471
516
|
requireWorksheet(nameOrId: string | number): Worksheet;
|
|
472
517
|
/**
|
|
473
|
-
* The codec's channel into this workbook
|
|
518
|
+
* The codec's channel into this workbook. See `core/internal.ts` for why these are not public
|
|
474
519
|
* methods. Declared last so every private field it closes over is already in scope.
|
|
475
520
|
*/
|
|
476
521
|
readonly [INTERNAL]: WorkbookInternals;
|
|
@@ -480,7 +525,7 @@ export declare class Workbook {
|
|
|
480
525
|
* the finished form the file stated it. Reached as `workbook[INTERNAL]`; see `core/internal.ts`.
|
|
481
526
|
*
|
|
482
527
|
* Every operation replaces what it restores rather than merging, because a reader states a table
|
|
483
|
-
* whole
|
|
528
|
+
* whole: a half-restored `<dxfs>` would leave existing `dxfId` references pointing into a mix of
|
|
484
529
|
* two files.
|
|
485
530
|
*/
|
|
486
531
|
export interface WorkbookInternals {
|
|
@@ -489,39 +534,40 @@ export interface WorkbookInternals {
|
|
|
489
534
|
/** Record a package-root preserved reference (a customUI ribbon part, custom props) read from a file. */
|
|
490
535
|
addPreservedRootReference(reference: PreservedRootReference): void;
|
|
491
536
|
/**
|
|
492
|
-
* Reinstate the differential-style (`<dxfs>`) table read from a file
|
|
537
|
+
* Reinstate the differential-style (`<dxfs>`) table read from a file: the deserialization
|
|
493
538
|
* counterpart the writer re-emits verbatim. Each entry is one `<dxf>…</dxf>` fragment, preserved as
|
|
494
539
|
* opaque XML so a conditional-formatting rule's `dxfId` (an index into this table) stays valid on
|
|
495
540
|
* re-write.
|
|
496
541
|
*/
|
|
497
542
|
restoreDifferentialStyles(fragments: readonly string[]): void;
|
|
498
543
|
/**
|
|
499
|
-
* Reinstate the custom indexed-color palette (`<colors><indexedColors>`) read from a file
|
|
500
|
-
* entry a verbatim `<rgbColor rgb="…"/>` fragment
|
|
544
|
+
* Reinstate the custom indexed-color palette (`<colors><indexedColors>`) read from a file, each
|
|
545
|
+
* entry a verbatim `<rgbColor rgb="…"/>` fragment, so a colour referenced by `indexed="…"` keeps
|
|
501
546
|
* its intended RGB on re-write instead of the palette being dropped and the colour shifting to a
|
|
502
547
|
* default-palette entry.
|
|
503
548
|
*/
|
|
504
549
|
restoreIndexedColors(fragments: readonly string[]): void;
|
|
505
550
|
/**
|
|
506
551
|
* Reinstate the most-recently-used colour swatches (`<colors><mruColors>`) read from a file, each
|
|
507
|
-
* entry a verbatim `<color rgb="…"/>` fragment
|
|
508
|
-
* offers, which is the author's own working set rather than anything the model
|
|
552
|
+
* entry a verbatim `<color rgb="…"/>` fragment. This is the "Recent Colors" row a spreadsheet
|
|
553
|
+
* application offers, which is the author's own working set rather than anything the model
|
|
554
|
+
* interprets.
|
|
509
555
|
*/
|
|
510
556
|
restoreMruColors(fragments: readonly string[]): void;
|
|
511
557
|
/**
|
|
512
|
-
* Reinstate the custom table-style definitions (`<tableStyles>`) read from a file
|
|
513
|
-
* {@link TableStyleTable}
|
|
558
|
+
* Reinstate the custom table-style definitions (`<tableStyles>`) read from a file (see
|
|
559
|
+
* {@link TableStyleTable}), so a table whose `styleName` names a custom style still resolves to a
|
|
514
560
|
* real definition on re-write instead of dangling, and the file's nominated default table/pivot
|
|
515
561
|
* styles survive.
|
|
516
562
|
*/
|
|
517
563
|
restoreTableStyles(table: TableStyleTable): void;
|
|
518
564
|
/**
|
|
519
|
-
* Reinstate the theme part read from a file
|
|
520
|
-
* reaches (see {@link PreservedTheme})
|
|
565
|
+
* Reinstate the theme part read from a file: opaque preserved XML plus the closure of parts it
|
|
566
|
+
* reaches (see {@link PreservedTheme}), so a workbook's colour and font schemes survive a re-write
|
|
521
567
|
* instead of being replaced by the library's default Office theme. Passing `undefined` drops back
|
|
522
568
|
* to that default.
|
|
523
569
|
*/
|
|
524
|
-
restoreThemePart(theme: PreservedTheme | undefined): void;
|
|
570
|
+
restoreThemePart(theme: PreservedTheme | undefined, declared: DeclaredThemeSchemes): void;
|
|
525
571
|
/**
|
|
526
572
|
* Reinstate the named cell styles (`cellStyleXfs`/`cellStyles`) read from a file, index for index,
|
|
527
573
|
* so a cell's link to a named style (its `xfId`) stays valid on re-write. Index 0 is the Normal
|
|
@@ -529,7 +575,7 @@ export interface WorkbookInternals {
|
|
|
529
575
|
*/
|
|
530
576
|
restoreNamedStyles(styles: readonly NamedCellStyle[]): void;
|
|
531
577
|
/**
|
|
532
|
-
* Reinstate font id 0 as a file declared it
|
|
578
|
+
* Reinstate font id 0 as a file declared it: the face its unstyled cells render in, and the metric
|
|
533
579
|
* its column widths are expressed in character units of. Restored rather than assumed because the
|
|
534
580
|
* library must not inject its own default ahead of one a file already states: doing so replaces the
|
|
535
581
|
* declared face on every empty cell and silently changes what every `<col width>` means.
|
|
@@ -538,13 +584,13 @@ export interface WorkbookInternals {
|
|
|
538
584
|
*/
|
|
539
585
|
restoreDefaultFont(font: Font | undefined): void;
|
|
540
586
|
/**
|
|
541
|
-
* Reinstate the threaded-comment identity registry (`xl/persons/person.xml`) read from a file
|
|
587
|
+
* Reinstate the threaded-comment identity registry (`xl/persons/person.xml`) read from a file: the
|
|
542
588
|
* authors and mentioned people a comment thread's messages point at.
|
|
543
589
|
*
|
|
544
590
|
* Entries are keyed by {@link Person.id} and by nothing else. A single human legitimately owns
|
|
545
591
|
* several entries: Excel interns a *mentioned* identity as its own `providerId="PeoplePicker"` entry
|
|
546
|
-
* beside that person's `providerId="AD"` authoring entry
|
|
547
|
-
* different id
|
|
592
|
+
* beside that person's `providerId="AD"` authoring entry (same `displayName`, same `userId`, a
|
|
593
|
+
* different id) and points the mention at the new one. Collapsing entries by name or `userId` would
|
|
548
594
|
* merge those two and silently re-point every mention at the wrong identity.
|
|
549
595
|
*
|
|
550
596
|
* {@link Workbook.addPerson} is the authoring verb.
|