amendsheet 0.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.
@@ -0,0 +1,325 @@
1
+ /**
2
+ * `code` is what to branch on. Messages are meant to be read by people and may
3
+ * be reworded.
4
+ *
5
+ * Two codes mean the caller passed something the library cannot use, and are
6
+ * the ones worth answering with a different value: `bad-reference` and
7
+ * `unwritable-value`. Every other code is about the file, or the runtime
8
+ * reading it, not a value you passed.
9
+ *
10
+ * The union is open. An existing code will not change without a major version,
11
+ * but new ones arrive in minor releases, because there is no knowing today
12
+ * every way an xlsx can be malformed. A switch over this needs a default.
13
+ */
14
+ type XlsxErrorCode = 'not-a-zip' | 'missing-part' | 'unreadable-part' | 'malformed-xml'
15
+ /** Well formed xml that says something no reader can honour. */
16
+ | 'invalid-content'
17
+ /** A part decompresses to more bytes than this runtime can hold at once. */
18
+ | 'part-too-large' | 'bad-reference' | 'unwritable-value' | (string & {});
19
+ /**
20
+ * Where a failure happened, as tightly as the throw site knows it. A cell
21
+ * failure carries all three of `part`, `sheet` and `reference`; a part-level
22
+ * failure carries `part`; only a whole-file failure with nowhere finer to point
23
+ * (a non-zip, a low-level parse offset already in the message) carries just
24
+ * `cause`. The argument is required so no throw can silently drop the location.
25
+ */
26
+ interface XlsxErrorContext {
27
+ readonly part?: string;
28
+ /** The worksheet name, when a cell or sheet is the locus. */
29
+ readonly sheet?: string;
30
+ readonly reference?: string;
31
+ readonly cause?: unknown;
32
+ }
33
+ declare class XlsxError extends Error {
34
+ readonly code: XlsxErrorCode;
35
+ /** Where in the document the failure was, as tightly as it was known. */
36
+ readonly part: string | undefined;
37
+ readonly sheet: string | undefined;
38
+ readonly reference: string | undefined;
39
+ constructor(code: XlsxErrorCode, message: string, context: XlsxErrorContext);
40
+ }
41
+
42
+ /** An expression without the leading `=`, so text starting with `=` stays text. */
43
+ interface FormulaInput {
44
+ readonly formula: string;
45
+ }
46
+ type CellInput = number | string | boolean | Date | null | FormulaInput;
47
+ /**
48
+ * What a caller may still do once the worksheet is protected. Each is `true` when
49
+ * the action stays permitted; omitted falls to Excel's default — the format,
50
+ * insert, delete, sort and filter family locked, and selecting cells allowed.
51
+ * Cells resist editing per their own `locked` flag, which only bites here.
52
+ */
53
+ interface SheetProtection {
54
+ readonly selectLockedCells?: boolean;
55
+ readonly selectUnlockedCells?: boolean;
56
+ readonly formatCells?: boolean;
57
+ readonly formatColumns?: boolean;
58
+ readonly formatRows?: boolean;
59
+ readonly insertColumns?: boolean;
60
+ readonly insertRows?: boolean;
61
+ readonly insertHyperlinks?: boolean;
62
+ readonly deleteColumns?: boolean;
63
+ readonly deleteRows?: boolean;
64
+ readonly sort?: boolean;
65
+ readonly autoFilter?: boolean;
66
+ readonly pivotTables?: boolean;
67
+ /** Editing drawing objects; Excel locks this by default when protecting. */
68
+ readonly editObjects?: boolean;
69
+ /** Editing scenarios; Excel locks this by default when protecting. */
70
+ readonly editScenarios?: boolean;
71
+ }
72
+
73
+ interface CellAddress {
74
+ /** One based, matching how references are written. */
75
+ readonly row: number;
76
+ readonly column: number;
77
+ }
78
+ /**
79
+ * Bijective base 26: there is no zero digit, so A-Z then AA, not A-Z then BA.
80
+ * The result may be past the last column a sheet can hold, because reading is
81
+ * lenient and this is the conversion reading goes through.
82
+ */
83
+ declare function columnToIndex(letters: string): number;
84
+ declare function indexToColumn(index: number): string;
85
+ /** Scanned rather than matched: this runs once per cell. */
86
+ declare function parseReference(reference: string): CellAddress;
87
+ declare function formatReference(address: CellAddress): string;
88
+
89
+ /** `true` and `'single'` both write a bare `<u/>`; the accounting and double
90
+ * variants carry a `val`. A read reports `true` for a plain single underline. */
91
+ type UnderlineStyle = 'single' | 'double' | 'singleAccounting' | 'doubleAccounting';
92
+ type FontVerticalAlign = 'baseline' | 'superscript' | 'subscript';
93
+ /**
94
+ * A colour a cell can carry: an `RRGGBB`/`AARRGGBB` hex literal, a reference into
95
+ * the workbook theme's colour scheme (`tint` lightens or darkens it, -1 to 1), or
96
+ * an index into the legacy palette. A theme or indexed colour is a reference, not
97
+ * a value, so it is kept as one rather than flattened to the hex it resolves to.
98
+ */
99
+ type Color = string | {
100
+ readonly theme: number;
101
+ readonly tint?: number;
102
+ } | {
103
+ readonly indexed: number;
104
+ };
105
+ interface FontFormat {
106
+ readonly bold?: boolean;
107
+ readonly italic?: boolean;
108
+ readonly strike?: boolean;
109
+ readonly underline?: boolean | UnderlineStyle;
110
+ readonly verticalAlign?: FontVerticalAlign;
111
+ readonly size?: number;
112
+ readonly color?: Color;
113
+ readonly name?: string;
114
+ }
115
+ /** ECMA-376 ST_PatternType, minus `none` (no fill) and `solid` (its own arm). */
116
+ type PatternStyle = 'gray125' | 'gray0625' | 'mediumGray' | 'darkGray' | 'lightGray' | 'darkHorizontal' | 'darkVertical' | 'darkDown' | 'darkUp' | 'darkGrid' | 'darkTrellis' | 'lightHorizontal' | 'lightVertical' | 'lightDown' | 'lightUp' | 'lightGrid' | 'lightTrellis';
117
+ interface SolidFill {
118
+ readonly type: 'solid';
119
+ /** The cell's background colour. */
120
+ readonly color: Color;
121
+ }
122
+ interface PatternFill {
123
+ readonly type: 'pattern';
124
+ readonly pattern: PatternStyle;
125
+ /** The pattern's foreground colour. */
126
+ readonly color: Color;
127
+ /** The colour behind the pattern; the default window background when absent. */
128
+ readonly background?: Color;
129
+ }
130
+ type FillFormat = SolidFill | PatternFill;
131
+ /** ECMA-376 ST_BorderStyle; `none` is expressed by leaving the side out. */
132
+ type BorderStyle = 'thin' | 'medium' | 'thick' | 'dashed' | 'dotted' | 'double' | 'hair' | 'mediumDashed' | 'dashDot' | 'mediumDashDot' | 'dashDotDot' | 'mediumDashDotDot' | 'slantDashDot';
133
+ interface BorderSide {
134
+ readonly style: BorderStyle;
135
+ /** The side's line colour. */
136
+ readonly color?: Color;
137
+ }
138
+ interface BorderFormat {
139
+ readonly top?: BorderSide;
140
+ readonly bottom?: BorderSide;
141
+ readonly left?: BorderSide;
142
+ readonly right?: BorderSide;
143
+ /** Applied to all four sides; a specific side overrides it. */
144
+ readonly all?: BorderSide;
145
+ }
146
+ type HorizontalAlignment = 'general' | 'left' | 'center' | 'right' | 'fill' | 'justify' | 'centerContinuous' | 'distributed';
147
+ type VerticalAlignment = 'top' | 'center' | 'bottom' | 'justify' | 'distributed';
148
+ interface Alignment {
149
+ readonly horizontal?: HorizontalAlignment;
150
+ readonly vertical?: VerticalAlignment;
151
+ readonly wrapText?: boolean;
152
+ /** Degrees anticlockwise, 0–180; 255 stacks the text top to bottom. */
153
+ readonly textRotation?: number;
154
+ readonly indent?: number;
155
+ }
156
+ interface CellProtection {
157
+ /** Whether the cell resists editing once the sheet is protected. */
158
+ readonly locked?: boolean;
159
+ /** Whether the cell's formula is hidden once the sheet is protected. */
160
+ readonly hidden?: boolean;
161
+ }
162
+
163
+ type SheetState = 'visible' | 'hidden' | 'veryHidden';
164
+
165
+ type CellValue = {
166
+ readonly kind: 'number';
167
+ readonly value: number;
168
+ } | {
169
+ readonly kind: 'text';
170
+ readonly value: string;
171
+ } | {
172
+ readonly kind: 'boolean';
173
+ readonly value: boolean;
174
+ } | {
175
+ readonly kind: 'error';
176
+ readonly value: string;
177
+ } | {
178
+ readonly kind: 'empty';
179
+ }
180
+ /**
181
+ * The stored number is kept so a date can be written back unchanged. Which
182
+ * formats count as dates is a heuristic and may change in any release, so a
183
+ * cell can move between `number` and `date`; `serial` and `value` are the
184
+ * same double, and reading whichever is there survives that.
185
+ */
186
+ | {
187
+ readonly kind: 'date';
188
+ readonly value: Date;
189
+ readonly serial: number;
190
+ };
191
+ /**
192
+ * A shared formula stores its source once, on the cell that owns the range.
193
+ * The dependents carry a cached value and no source of their own, which is why
194
+ * this is a union rather than a string that is sometimes empty.
195
+ */
196
+ type CellFormula =
197
+ /** Without the leading `=`. */
198
+ {
199
+ readonly kind: 'expression';
200
+ readonly expression: string;
201
+ }
202
+ /** `master` is absent when the sheet holds no cell owning that group. */
203
+ | {
204
+ readonly kind: 'shared';
205
+ readonly master?: string;
206
+ };
207
+ interface Cell {
208
+ readonly address: CellAddress;
209
+ /**
210
+ * Canonical, so it always equals `formatReference(cell.address)`. The one
211
+ * exception is an address no column letter can name, which a lenient read
212
+ * accepts and which keeps the spelling the file gave it.
213
+ */
214
+ readonly reference: string;
215
+ readonly value: CellValue;
216
+ readonly formula?: CellFormula;
217
+ readonly numberFormat?: string;
218
+ /** Absent when the cell uses the default font, so carries none of its own. */
219
+ readonly font?: FontFormat;
220
+ /** Absent unless the cell has a solid fill. */
221
+ readonly fill?: FillFormat;
222
+ /** Absent unless at least one side has a border. */
223
+ readonly border?: BorderFormat;
224
+ /** Absent unless the cell sets an alignment of its own. */
225
+ readonly alignment?: Alignment;
226
+ /** Absent unless the cell sets a `locked` or `hidden` protection of its own. */
227
+ readonly protection?: CellProtection;
228
+ }
229
+ interface Worksheet {
230
+ readonly name: string;
231
+ readonly state: SheetState;
232
+ /**
233
+ * As the workbook part spells it, so a defined name or a part this library
234
+ * does not interpret can be matched against the sheet it refers to.
235
+ */
236
+ readonly sheetId: string;
237
+ /**
238
+ * The worksheet protection in force, in the shape `protect()` takes, or
239
+ * undefined when the sheet is not protected. Reflects a pending `protect()` or
240
+ * `unprotect()` as well as what the file was read with.
241
+ */
242
+ readonly protection?: SheetProtection;
243
+ /**
244
+ * Every cell the sheet stores. A cell that was cleared, or that carries only
245
+ * formatting, is still stored, and arrives with a value of `kind: 'empty'`.
246
+ *
247
+ * Each call re-reads the sheet, so a call per cell is quadratic.
248
+ */
249
+ cells(): Iterable<Cell>;
250
+ /** Undefined when the sheet stores nothing at that reference. */
251
+ cell(reference: string): Cell | undefined;
252
+ /**
253
+ * Visible to `cells()` and `cell()` immediately, written by `toBytes()`.
254
+ * A `numberFormat` is a format code such as `"$"#,##0.00`; without one the
255
+ * cell keeps the formatting it already had.
256
+ *
257
+ * Throws `XlsxError` with code `unwritable-value` for a value the format
258
+ * cannot hold, and records nothing when it does, so the rest of a batch of
259
+ * edits still writes.
260
+ */
261
+ set(reference: string, value: CellInput, options?: SetOptions): void;
262
+ /**
263
+ * Applies formatting to a cell without changing its value or formula, so a
264
+ * formula cell can be restyled without losing its expression. A cell that is
265
+ * not there yet is created empty with the formatting. Unlike `set`, this is
266
+ * refused by nothing: restyling a shared-formula master or a merged cell is
267
+ * safe, since only the cell format changes.
268
+ */
269
+ format(reference: string, options: SetOptions): void;
270
+ /**
271
+ * Turns on worksheet protection, which is what makes a cell's `locked` and
272
+ * `hidden` flags bite. Without `options` it matches Excel's Protect Sheet
273
+ * default; `options` names the actions that stay permitted. Replaces any
274
+ * protection the sheet already declared. Passwords are not written.
275
+ */
276
+ protect(options?: SheetProtection): void;
277
+ /** Removes worksheet protection, if the sheet had any. */
278
+ unprotect(): void;
279
+ /**
280
+ * Merges a rectangular range like `A1:B2`, joining any merges the sheet
281
+ * already has. Excel shows only the top-left cell's value; the others keep
282
+ * whatever they hold, since a merge does not clear them. Refuses a range that
283
+ * is not two references either side of a colon.
284
+ */
285
+ merge(range: string): void;
286
+ /**
287
+ * Sets a row's height in points, marking it a custom height so a reader keeps
288
+ * it. Refuses a row number below 1 or a height that is not a finite number at
289
+ * least zero.
290
+ */
291
+ setRowHeight(row: number, height: number): void;
292
+ /**
293
+ * Sets a column's width, in the units Excel shows, splitting a `cols` range
294
+ * that spans more than the column so the rest keeps its own width. The column
295
+ * is a letter like `A`. Refuses a width that is not a finite number at least
296
+ * zero.
297
+ */
298
+ setColumnWidth(column: string, width: number): void;
299
+ }
300
+ interface SetOptions {
301
+ /** A number format code, applied to the cell being written. */
302
+ readonly numberFormat?: string;
303
+ /** Font to apply, merged onto the font the cell already carries. */
304
+ readonly font?: FontFormat;
305
+ /** Solid fill colour for the cell's background. */
306
+ readonly fill?: FillFormat;
307
+ /** Borders to apply, merged onto the sides the cell already has. */
308
+ readonly border?: BorderFormat;
309
+ /** Alignment to apply, merged onto the alignment the cell already has. */
310
+ readonly alignment?: Alignment;
311
+ /** Protection to apply, merged onto the protection the cell already has. */
312
+ readonly protection?: CellProtection;
313
+ }
314
+ interface Workbook {
315
+ readonly sheets: readonly Worksheet[];
316
+ /** Undefined when no sheet has that name. Names are compared exactly. */
317
+ sheet(name: string): Worksheet | undefined;
318
+ /** Which year serials count from. A 1904 workbook is 1462 days behind. */
319
+ readonly epoch: 1900 | 1904;
320
+ /** Parts that were never interpreted are written exactly as they were read. */
321
+ toBytes(): Uint8Array;
322
+ }
323
+ declare function readWorkbook(bytes: Uint8Array): Workbook;
324
+
325
+ export { type Alignment, type BorderFormat, type BorderSide, type BorderStyle, type Cell, type CellAddress, type CellFormula, type CellInput, type CellProtection, type CellValue, type Color, type FillFormat, type FontFormat, type FontVerticalAlign, type FormulaInput, type HorizontalAlignment, type PatternFill, type PatternStyle, type SetOptions, type SheetProtection, type SheetState, type SolidFill, type UnderlineStyle, type VerticalAlignment, type Workbook, type Worksheet, XlsxError, type XlsxErrorCode, type XlsxErrorContext, columnToIndex, formatReference, indexToColumn, parseReference, readWorkbook };
@@ -0,0 +1,325 @@
1
+ /**
2
+ * `code` is what to branch on. Messages are meant to be read by people and may
3
+ * be reworded.
4
+ *
5
+ * Two codes mean the caller passed something the library cannot use, and are
6
+ * the ones worth answering with a different value: `bad-reference` and
7
+ * `unwritable-value`. Every other code is about the file, or the runtime
8
+ * reading it, not a value you passed.
9
+ *
10
+ * The union is open. An existing code will not change without a major version,
11
+ * but new ones arrive in minor releases, because there is no knowing today
12
+ * every way an xlsx can be malformed. A switch over this needs a default.
13
+ */
14
+ type XlsxErrorCode = 'not-a-zip' | 'missing-part' | 'unreadable-part' | 'malformed-xml'
15
+ /** Well formed xml that says something no reader can honour. */
16
+ | 'invalid-content'
17
+ /** A part decompresses to more bytes than this runtime can hold at once. */
18
+ | 'part-too-large' | 'bad-reference' | 'unwritable-value' | (string & {});
19
+ /**
20
+ * Where a failure happened, as tightly as the throw site knows it. A cell
21
+ * failure carries all three of `part`, `sheet` and `reference`; a part-level
22
+ * failure carries `part`; only a whole-file failure with nowhere finer to point
23
+ * (a non-zip, a low-level parse offset already in the message) carries just
24
+ * `cause`. The argument is required so no throw can silently drop the location.
25
+ */
26
+ interface XlsxErrorContext {
27
+ readonly part?: string;
28
+ /** The worksheet name, when a cell or sheet is the locus. */
29
+ readonly sheet?: string;
30
+ readonly reference?: string;
31
+ readonly cause?: unknown;
32
+ }
33
+ declare class XlsxError extends Error {
34
+ readonly code: XlsxErrorCode;
35
+ /** Where in the document the failure was, as tightly as it was known. */
36
+ readonly part: string | undefined;
37
+ readonly sheet: string | undefined;
38
+ readonly reference: string | undefined;
39
+ constructor(code: XlsxErrorCode, message: string, context: XlsxErrorContext);
40
+ }
41
+
42
+ /** An expression without the leading `=`, so text starting with `=` stays text. */
43
+ interface FormulaInput {
44
+ readonly formula: string;
45
+ }
46
+ type CellInput = number | string | boolean | Date | null | FormulaInput;
47
+ /**
48
+ * What a caller may still do once the worksheet is protected. Each is `true` when
49
+ * the action stays permitted; omitted falls to Excel's default — the format,
50
+ * insert, delete, sort and filter family locked, and selecting cells allowed.
51
+ * Cells resist editing per their own `locked` flag, which only bites here.
52
+ */
53
+ interface SheetProtection {
54
+ readonly selectLockedCells?: boolean;
55
+ readonly selectUnlockedCells?: boolean;
56
+ readonly formatCells?: boolean;
57
+ readonly formatColumns?: boolean;
58
+ readonly formatRows?: boolean;
59
+ readonly insertColumns?: boolean;
60
+ readonly insertRows?: boolean;
61
+ readonly insertHyperlinks?: boolean;
62
+ readonly deleteColumns?: boolean;
63
+ readonly deleteRows?: boolean;
64
+ readonly sort?: boolean;
65
+ readonly autoFilter?: boolean;
66
+ readonly pivotTables?: boolean;
67
+ /** Editing drawing objects; Excel locks this by default when protecting. */
68
+ readonly editObjects?: boolean;
69
+ /** Editing scenarios; Excel locks this by default when protecting. */
70
+ readonly editScenarios?: boolean;
71
+ }
72
+
73
+ interface CellAddress {
74
+ /** One based, matching how references are written. */
75
+ readonly row: number;
76
+ readonly column: number;
77
+ }
78
+ /**
79
+ * Bijective base 26: there is no zero digit, so A-Z then AA, not A-Z then BA.
80
+ * The result may be past the last column a sheet can hold, because reading is
81
+ * lenient and this is the conversion reading goes through.
82
+ */
83
+ declare function columnToIndex(letters: string): number;
84
+ declare function indexToColumn(index: number): string;
85
+ /** Scanned rather than matched: this runs once per cell. */
86
+ declare function parseReference(reference: string): CellAddress;
87
+ declare function formatReference(address: CellAddress): string;
88
+
89
+ /** `true` and `'single'` both write a bare `<u/>`; the accounting and double
90
+ * variants carry a `val`. A read reports `true` for a plain single underline. */
91
+ type UnderlineStyle = 'single' | 'double' | 'singleAccounting' | 'doubleAccounting';
92
+ type FontVerticalAlign = 'baseline' | 'superscript' | 'subscript';
93
+ /**
94
+ * A colour a cell can carry: an `RRGGBB`/`AARRGGBB` hex literal, a reference into
95
+ * the workbook theme's colour scheme (`tint` lightens or darkens it, -1 to 1), or
96
+ * an index into the legacy palette. A theme or indexed colour is a reference, not
97
+ * a value, so it is kept as one rather than flattened to the hex it resolves to.
98
+ */
99
+ type Color = string | {
100
+ readonly theme: number;
101
+ readonly tint?: number;
102
+ } | {
103
+ readonly indexed: number;
104
+ };
105
+ interface FontFormat {
106
+ readonly bold?: boolean;
107
+ readonly italic?: boolean;
108
+ readonly strike?: boolean;
109
+ readonly underline?: boolean | UnderlineStyle;
110
+ readonly verticalAlign?: FontVerticalAlign;
111
+ readonly size?: number;
112
+ readonly color?: Color;
113
+ readonly name?: string;
114
+ }
115
+ /** ECMA-376 ST_PatternType, minus `none` (no fill) and `solid` (its own arm). */
116
+ type PatternStyle = 'gray125' | 'gray0625' | 'mediumGray' | 'darkGray' | 'lightGray' | 'darkHorizontal' | 'darkVertical' | 'darkDown' | 'darkUp' | 'darkGrid' | 'darkTrellis' | 'lightHorizontal' | 'lightVertical' | 'lightDown' | 'lightUp' | 'lightGrid' | 'lightTrellis';
117
+ interface SolidFill {
118
+ readonly type: 'solid';
119
+ /** The cell's background colour. */
120
+ readonly color: Color;
121
+ }
122
+ interface PatternFill {
123
+ readonly type: 'pattern';
124
+ readonly pattern: PatternStyle;
125
+ /** The pattern's foreground colour. */
126
+ readonly color: Color;
127
+ /** The colour behind the pattern; the default window background when absent. */
128
+ readonly background?: Color;
129
+ }
130
+ type FillFormat = SolidFill | PatternFill;
131
+ /** ECMA-376 ST_BorderStyle; `none` is expressed by leaving the side out. */
132
+ type BorderStyle = 'thin' | 'medium' | 'thick' | 'dashed' | 'dotted' | 'double' | 'hair' | 'mediumDashed' | 'dashDot' | 'mediumDashDot' | 'dashDotDot' | 'mediumDashDotDot' | 'slantDashDot';
133
+ interface BorderSide {
134
+ readonly style: BorderStyle;
135
+ /** The side's line colour. */
136
+ readonly color?: Color;
137
+ }
138
+ interface BorderFormat {
139
+ readonly top?: BorderSide;
140
+ readonly bottom?: BorderSide;
141
+ readonly left?: BorderSide;
142
+ readonly right?: BorderSide;
143
+ /** Applied to all four sides; a specific side overrides it. */
144
+ readonly all?: BorderSide;
145
+ }
146
+ type HorizontalAlignment = 'general' | 'left' | 'center' | 'right' | 'fill' | 'justify' | 'centerContinuous' | 'distributed';
147
+ type VerticalAlignment = 'top' | 'center' | 'bottom' | 'justify' | 'distributed';
148
+ interface Alignment {
149
+ readonly horizontal?: HorizontalAlignment;
150
+ readonly vertical?: VerticalAlignment;
151
+ readonly wrapText?: boolean;
152
+ /** Degrees anticlockwise, 0–180; 255 stacks the text top to bottom. */
153
+ readonly textRotation?: number;
154
+ readonly indent?: number;
155
+ }
156
+ interface CellProtection {
157
+ /** Whether the cell resists editing once the sheet is protected. */
158
+ readonly locked?: boolean;
159
+ /** Whether the cell's formula is hidden once the sheet is protected. */
160
+ readonly hidden?: boolean;
161
+ }
162
+
163
+ type SheetState = 'visible' | 'hidden' | 'veryHidden';
164
+
165
+ type CellValue = {
166
+ readonly kind: 'number';
167
+ readonly value: number;
168
+ } | {
169
+ readonly kind: 'text';
170
+ readonly value: string;
171
+ } | {
172
+ readonly kind: 'boolean';
173
+ readonly value: boolean;
174
+ } | {
175
+ readonly kind: 'error';
176
+ readonly value: string;
177
+ } | {
178
+ readonly kind: 'empty';
179
+ }
180
+ /**
181
+ * The stored number is kept so a date can be written back unchanged. Which
182
+ * formats count as dates is a heuristic and may change in any release, so a
183
+ * cell can move between `number` and `date`; `serial` and `value` are the
184
+ * same double, and reading whichever is there survives that.
185
+ */
186
+ | {
187
+ readonly kind: 'date';
188
+ readonly value: Date;
189
+ readonly serial: number;
190
+ };
191
+ /**
192
+ * A shared formula stores its source once, on the cell that owns the range.
193
+ * The dependents carry a cached value and no source of their own, which is why
194
+ * this is a union rather than a string that is sometimes empty.
195
+ */
196
+ type CellFormula =
197
+ /** Without the leading `=`. */
198
+ {
199
+ readonly kind: 'expression';
200
+ readonly expression: string;
201
+ }
202
+ /** `master` is absent when the sheet holds no cell owning that group. */
203
+ | {
204
+ readonly kind: 'shared';
205
+ readonly master?: string;
206
+ };
207
+ interface Cell {
208
+ readonly address: CellAddress;
209
+ /**
210
+ * Canonical, so it always equals `formatReference(cell.address)`. The one
211
+ * exception is an address no column letter can name, which a lenient read
212
+ * accepts and which keeps the spelling the file gave it.
213
+ */
214
+ readonly reference: string;
215
+ readonly value: CellValue;
216
+ readonly formula?: CellFormula;
217
+ readonly numberFormat?: string;
218
+ /** Absent when the cell uses the default font, so carries none of its own. */
219
+ readonly font?: FontFormat;
220
+ /** Absent unless the cell has a solid fill. */
221
+ readonly fill?: FillFormat;
222
+ /** Absent unless at least one side has a border. */
223
+ readonly border?: BorderFormat;
224
+ /** Absent unless the cell sets an alignment of its own. */
225
+ readonly alignment?: Alignment;
226
+ /** Absent unless the cell sets a `locked` or `hidden` protection of its own. */
227
+ readonly protection?: CellProtection;
228
+ }
229
+ interface Worksheet {
230
+ readonly name: string;
231
+ readonly state: SheetState;
232
+ /**
233
+ * As the workbook part spells it, so a defined name or a part this library
234
+ * does not interpret can be matched against the sheet it refers to.
235
+ */
236
+ readonly sheetId: string;
237
+ /**
238
+ * The worksheet protection in force, in the shape `protect()` takes, or
239
+ * undefined when the sheet is not protected. Reflects a pending `protect()` or
240
+ * `unprotect()` as well as what the file was read with.
241
+ */
242
+ readonly protection?: SheetProtection;
243
+ /**
244
+ * Every cell the sheet stores. A cell that was cleared, or that carries only
245
+ * formatting, is still stored, and arrives with a value of `kind: 'empty'`.
246
+ *
247
+ * Each call re-reads the sheet, so a call per cell is quadratic.
248
+ */
249
+ cells(): Iterable<Cell>;
250
+ /** Undefined when the sheet stores nothing at that reference. */
251
+ cell(reference: string): Cell | undefined;
252
+ /**
253
+ * Visible to `cells()` and `cell()` immediately, written by `toBytes()`.
254
+ * A `numberFormat` is a format code such as `"$"#,##0.00`; without one the
255
+ * cell keeps the formatting it already had.
256
+ *
257
+ * Throws `XlsxError` with code `unwritable-value` for a value the format
258
+ * cannot hold, and records nothing when it does, so the rest of a batch of
259
+ * edits still writes.
260
+ */
261
+ set(reference: string, value: CellInput, options?: SetOptions): void;
262
+ /**
263
+ * Applies formatting to a cell without changing its value or formula, so a
264
+ * formula cell can be restyled without losing its expression. A cell that is
265
+ * not there yet is created empty with the formatting. Unlike `set`, this is
266
+ * refused by nothing: restyling a shared-formula master or a merged cell is
267
+ * safe, since only the cell format changes.
268
+ */
269
+ format(reference: string, options: SetOptions): void;
270
+ /**
271
+ * Turns on worksheet protection, which is what makes a cell's `locked` and
272
+ * `hidden` flags bite. Without `options` it matches Excel's Protect Sheet
273
+ * default; `options` names the actions that stay permitted. Replaces any
274
+ * protection the sheet already declared. Passwords are not written.
275
+ */
276
+ protect(options?: SheetProtection): void;
277
+ /** Removes worksheet protection, if the sheet had any. */
278
+ unprotect(): void;
279
+ /**
280
+ * Merges a rectangular range like `A1:B2`, joining any merges the sheet
281
+ * already has. Excel shows only the top-left cell's value; the others keep
282
+ * whatever they hold, since a merge does not clear them. Refuses a range that
283
+ * is not two references either side of a colon.
284
+ */
285
+ merge(range: string): void;
286
+ /**
287
+ * Sets a row's height in points, marking it a custom height so a reader keeps
288
+ * it. Refuses a row number below 1 or a height that is not a finite number at
289
+ * least zero.
290
+ */
291
+ setRowHeight(row: number, height: number): void;
292
+ /**
293
+ * Sets a column's width, in the units Excel shows, splitting a `cols` range
294
+ * that spans more than the column so the rest keeps its own width. The column
295
+ * is a letter like `A`. Refuses a width that is not a finite number at least
296
+ * zero.
297
+ */
298
+ setColumnWidth(column: string, width: number): void;
299
+ }
300
+ interface SetOptions {
301
+ /** A number format code, applied to the cell being written. */
302
+ readonly numberFormat?: string;
303
+ /** Font to apply, merged onto the font the cell already carries. */
304
+ readonly font?: FontFormat;
305
+ /** Solid fill colour for the cell's background. */
306
+ readonly fill?: FillFormat;
307
+ /** Borders to apply, merged onto the sides the cell already has. */
308
+ readonly border?: BorderFormat;
309
+ /** Alignment to apply, merged onto the alignment the cell already has. */
310
+ readonly alignment?: Alignment;
311
+ /** Protection to apply, merged onto the protection the cell already has. */
312
+ readonly protection?: CellProtection;
313
+ }
314
+ interface Workbook {
315
+ readonly sheets: readonly Worksheet[];
316
+ /** Undefined when no sheet has that name. Names are compared exactly. */
317
+ sheet(name: string): Worksheet | undefined;
318
+ /** Which year serials count from. A 1904 workbook is 1462 days behind. */
319
+ readonly epoch: 1900 | 1904;
320
+ /** Parts that were never interpreted are written exactly as they were read. */
321
+ toBytes(): Uint8Array;
322
+ }
323
+ declare function readWorkbook(bytes: Uint8Array): Workbook;
324
+
325
+ export { type Alignment, type BorderFormat, type BorderSide, type BorderStyle, type Cell, type CellAddress, type CellFormula, type CellInput, type CellProtection, type CellValue, type Color, type FillFormat, type FontFormat, type FontVerticalAlign, type FormulaInput, type HorizontalAlignment, type PatternFill, type PatternStyle, type SetOptions, type SheetProtection, type SheetState, type SolidFill, type UnderlineStyle, type VerticalAlignment, type Workbook, type Worksheet, XlsxError, type XlsxErrorCode, type XlsxErrorContext, columnToIndex, formatReference, indexToColumn, parseReference, readWorkbook };