@openjsxl/core 0.2.1 → 0.4.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 +32 -3
- package/dist/index.d.ts +251 -11
- package/dist/index.js +1625 -18
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
[](./LICENSE)
|
|
6
6
|
|
|
7
7
|
The zero-dependency OOXML engine behind [`openjsxl`](https://www.npmjs.com/package/openjsxl):
|
|
8
|
-
the `zip → xml → ooxml → reader` layers that turn an `.xlsx` into typed cells
|
|
9
|
-
|
|
8
|
+
the `zip → xml → ooxml → reader` layers that turn an `.xlsx` into typed cells — and the mirror
|
|
9
|
+
`writer` layer that turns plain data back into `.xlsx` bytes. Built only on platform Web APIs
|
|
10
|
+
(`DecompressionStream`, `CompressionStream`, `TextDecoder`, …). No runtime dependencies.
|
|
10
11
|
|
|
11
12
|
**Most users should install [`openjsxl`](https://www.npmjs.com/package/openjsxl) instead** — it
|
|
12
13
|
re-exports everything here and is the stable public surface. Install `@openjsxl/core` directly
|
|
@@ -26,8 +27,10 @@ const wb = await openXlsx(await readFile('data.xlsx'))
|
|
|
26
27
|
const sheet = wb.sheet('Sheet1')
|
|
27
28
|
|
|
28
29
|
sheet.cell('A1') // { ref, type, value } — narrow on `type` for a typed value
|
|
30
|
+
sheet.style('B2') // { font?, fill?, border?, alignment?, numberFormat? } | undefined
|
|
29
31
|
sheet.numberFormat('C1') // "mm-dd-yy" | undefined
|
|
30
32
|
sheet.mergedCells // ["A1:B1", …]
|
|
33
|
+
sheet.freeze // { rows?, cols? } | undefined — plus columns, rowProperties, state, …
|
|
31
34
|
|
|
32
35
|
// Constant-memory streaming for large sheets — one row at a time.
|
|
33
36
|
for await (const row of streamSheetRows(await readFile('huge.xlsx'))) {
|
|
@@ -39,11 +42,37 @@ Malformed input throws a typed `XlsxError` with a discriminating `.code`
|
|
|
39
42
|
(`'not-a-zip' | 'not-xlsx' | 'missing-part' | 'corrupt-zip' | 'part-too-large' | …`), never a
|
|
40
43
|
bare `TypeError` from a corrupt file.
|
|
41
44
|
|
|
45
|
+
## Writing
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { writeXlsx, workbookToInput } from '@openjsxl/core'
|
|
49
|
+
|
|
50
|
+
// Author from plain data — cell types inferred from the JS values.
|
|
51
|
+
const bytes = await writeXlsx({
|
|
52
|
+
sheets: [{ name: 'Report', rows: [['Item', 'Added'], ['Apples', new Date('2024-01-15')]] }],
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
// Or read → modify → write.
|
|
56
|
+
const input = await workbookToInput(await openXlsx(bytes))
|
|
57
|
+
input.sheets[0].rows.push(['Pears', new Date('2024-02-01')])
|
|
58
|
+
const updated = await writeXlsx(input)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Cells can carry styles (`{ value, style }` — the same shape `style(ref)` returns), and sheets
|
|
62
|
+
take `columns` (widths), `rowProperties` (heights), `freeze`, `merges`, `hyperlinks`, and a
|
|
63
|
+
visibility `state`. Output is deterministic; unrepresentable input (no sheets, bad/duplicate
|
|
64
|
+
sheet name, non-finite number, invalid `Date`, XML-illegal characters, malformed or overlapping
|
|
65
|
+
merges) throws `XlsxError` with `code: 'invalid-input'`. The round trip is lossless for values,
|
|
66
|
+
types, sheet names/order, styles, geometry, merges, hyperlinks, and visibility.
|
|
67
|
+
|
|
42
68
|
## Exports
|
|
43
69
|
|
|
44
70
|
- **Reader:** `openXlsx`, `streamSheetRows`, `Workbook`, `Worksheet`, `ReadOptions`
|
|
71
|
+
- **Writer:** `writeXlsx`, `workbookToInput`, `WorkbookInput`, `SheetInput`, `CellInput`,
|
|
72
|
+
`StyledCell`, `CellValue`, `WriteOptions`
|
|
45
73
|
- **Errors:** `XlsxError`, `XlsxErrorCode`
|
|
46
|
-
- **Types:** `Row`, `Cell`, `CellType`, `
|
|
74
|
+
- **Types:** `Row`, `Cell`, `CellType`, `CellStyle` (+ font/fill/border/alignment/color parts),
|
|
75
|
+
`ColumnProps`, `RowProps`, `FreezePane`, `Comment`, `Hyperlink`, `SheetInfo`, `SheetState`, `CellRef`
|
|
47
76
|
- **A1 & dates:** `columnToIndex`, `indexToColumn`, `parseRef`, `formatRef`, `serialToDate`
|
|
48
77
|
|
|
49
78
|
Full guide, design notes, and roadmap: <https://github.com/joaquimserafim/openjsxl>
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type XlsxErrorCode =
|
|
1
|
+
type XlsxErrorCode = "not-a-zip" | "not-xlsx" | "missing-part" | "corrupt-zip" | "unsupported" | "no-such-sheet" | "part-too-large" | "invalid-input";
|
|
2
2
|
declare class XlsxError extends Error {
|
|
3
3
|
/** Machine-readable discriminant; branch on this rather than the message. */
|
|
4
4
|
readonly code: XlsxErrorCode;
|
|
@@ -19,38 +19,47 @@ declare function parseRef(ref: string): CellRef;
|
|
|
19
19
|
declare function formatRef(ref: CellRef): string;
|
|
20
20
|
|
|
21
21
|
declare function serialToDate(serial: number, date1904?: boolean): Date;
|
|
22
|
+
declare function dateToSerial(date: Date, date1904?: boolean): number;
|
|
22
23
|
|
|
23
|
-
type CellType =
|
|
24
|
+
type CellType = "empty" | "string" | "number" | "boolean" | "date" | "error";
|
|
24
25
|
interface CellBase {
|
|
25
26
|
/** A1 reference, e.g. "B2". */
|
|
26
27
|
readonly ref: string;
|
|
27
28
|
}
|
|
28
29
|
type Cell = (CellBase & {
|
|
29
|
-
readonly type:
|
|
30
|
+
readonly type: "empty";
|
|
30
31
|
readonly value: null;
|
|
31
32
|
}) | (CellBase & {
|
|
32
|
-
readonly type:
|
|
33
|
+
readonly type: "string";
|
|
33
34
|
readonly value: string;
|
|
34
35
|
}) | (CellBase & {
|
|
35
|
-
readonly type:
|
|
36
|
+
readonly type: "number";
|
|
36
37
|
readonly value: number;
|
|
37
38
|
}) | (CellBase & {
|
|
38
|
-
readonly type:
|
|
39
|
+
readonly type: "boolean";
|
|
39
40
|
readonly value: boolean;
|
|
40
41
|
}) | (CellBase & {
|
|
41
|
-
readonly type:
|
|
42
|
+
readonly type: "date";
|
|
42
43
|
readonly value: Date;
|
|
43
44
|
}) | (CellBase & {
|
|
44
|
-
readonly type:
|
|
45
|
+
readonly type: "error";
|
|
45
46
|
readonly value: string;
|
|
46
47
|
});
|
|
48
|
+
/**
|
|
49
|
+
* A sheet tab's visibility (the `state` attribute on `<sheet>`). `hidden` sheets can be re-shown
|
|
50
|
+
* from Excel's UI; `veryHidden` ones only through VBA or by editing the file. An absent or
|
|
51
|
+
* unrecognized state reads as `visible` (the spec's default).
|
|
52
|
+
*/
|
|
53
|
+
type SheetState = "visible" | "hidden" | "veryHidden";
|
|
47
54
|
interface SheetInfo {
|
|
48
55
|
/** Sheet name as shown on Excel's tab. */
|
|
49
56
|
readonly name: string;
|
|
50
57
|
/** Workbook-relative part path, resolved via the relationship graph. */
|
|
51
58
|
readonly path: string;
|
|
52
|
-
/** false for hidden or very-hidden sheets. */
|
|
59
|
+
/** false for hidden or very-hidden sheets. Kept alongside {@link state} (which it derives from). */
|
|
53
60
|
readonly visible: boolean;
|
|
61
|
+
/** The tab's visibility state (F4.6). `visible` is `state === "visible"`. */
|
|
62
|
+
readonly state: SheetState;
|
|
54
63
|
}
|
|
55
64
|
interface Comment {
|
|
56
65
|
/** The cell the comment is anchored to, e.g. "B2". */
|
|
@@ -75,6 +84,114 @@ interface Hyperlink {
|
|
|
75
84
|
/** Display-text override for the link, if any. */
|
|
76
85
|
readonly display?: string;
|
|
77
86
|
}
|
|
87
|
+
/** Width/visibility for a 1-based column range (`min`–`max` inclusive), from `<cols>`. */
|
|
88
|
+
interface ColumnProps {
|
|
89
|
+
readonly min: number;
|
|
90
|
+
readonly max: number;
|
|
91
|
+
/** Column width in characters of the default font (Excel's unit), 0 < width ≤ 255. */
|
|
92
|
+
readonly width?: number;
|
|
93
|
+
readonly hidden?: boolean;
|
|
94
|
+
}
|
|
95
|
+
/** Height/visibility of one row, from `<row ht hidden>`. */
|
|
96
|
+
interface RowProps {
|
|
97
|
+
/** Row height in points, 0 < height ≤ 409.5 (Excel's ceiling). */
|
|
98
|
+
readonly height?: number;
|
|
99
|
+
readonly hidden?: boolean;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* A frozen pane: the top `rows` rows and/or leftmost `cols` columns stay visible while the rest
|
|
103
|
+
* scrolls. Split (non-frozen) panes are not modelled and read as no freeze.
|
|
104
|
+
*/
|
|
105
|
+
interface FreezePane {
|
|
106
|
+
readonly rows?: number;
|
|
107
|
+
readonly cols?: number;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A color as OOXML stores it — kept RAW, never resolved. `rgb` is ARGB hex (e.g. `"FFFF0000"`);
|
|
111
|
+
* `theme` indexes the workbook theme's color scheme with an optional `tint` (−1…1); `indexed` is
|
|
112
|
+
* a legacy palette index; `auto` lets the consumer pick (usually black). Theme colors are NOT
|
|
113
|
+
* resolved to rgb on read: resolution needs a theme1.xml parser and is lossy on rewrite (a
|
|
114
|
+
* theme-aware consumer could no longer re-tint) — the raw form is what round-trips faithfully,
|
|
115
|
+
* and it is exactly what openpyxl stores too.
|
|
116
|
+
*/
|
|
117
|
+
type Color = {
|
|
118
|
+
readonly rgb: string;
|
|
119
|
+
} | {
|
|
120
|
+
readonly theme: number;
|
|
121
|
+
readonly tint?: number;
|
|
122
|
+
} | {
|
|
123
|
+
readonly indexed: number;
|
|
124
|
+
} | {
|
|
125
|
+
readonly auto: true;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Underline style. The exotic accounting variants (`singleAccounting`/`doubleAccounting`)
|
|
129
|
+
* degrade to no underline on read and are rejected on write (deferred, documented).
|
|
130
|
+
*/
|
|
131
|
+
type UnderlineStyle = "single" | "double";
|
|
132
|
+
interface FontStyle {
|
|
133
|
+
readonly name?: string;
|
|
134
|
+
/** Font size in points. */
|
|
135
|
+
readonly size?: number;
|
|
136
|
+
readonly bold?: boolean;
|
|
137
|
+
readonly italic?: boolean;
|
|
138
|
+
readonly underline?: UnderlineStyle;
|
|
139
|
+
readonly strike?: boolean;
|
|
140
|
+
readonly color?: Color;
|
|
141
|
+
}
|
|
142
|
+
/** Fill pattern kinds (ECMA-376 §18.18.55). `gray125` is the workbook-reserved fill 1. */
|
|
143
|
+
type PatternType = "none" | "solid" | "mediumGray" | "darkGray" | "lightGray" | "darkHorizontal" | "darkVertical" | "darkDown" | "darkUp" | "darkGrid" | "darkTrellis" | "lightHorizontal" | "lightVertical" | "lightDown" | "lightUp" | "lightGrid" | "lightTrellis" | "gray125" | "gray0625";
|
|
144
|
+
/**
|
|
145
|
+
* A pattern fill. For the everyday solid fill, the visible color is `fgColor` (OOXML's rule —
|
|
146
|
+
* `bgColor` shows only through pattern gaps). Gradient fills are not modelled (deferred): a
|
|
147
|
+
* gradient-filled cell reads as having no fill.
|
|
148
|
+
*/
|
|
149
|
+
interface FillStyle {
|
|
150
|
+
readonly patternType: PatternType;
|
|
151
|
+
readonly fgColor?: Color;
|
|
152
|
+
readonly bgColor?: Color;
|
|
153
|
+
}
|
|
154
|
+
/** Border line styles (ECMA-376 §18.18.3). An edge with no style is simply absent. */
|
|
155
|
+
type BorderLineStyle = "thin" | "medium" | "thick" | "dashed" | "dotted" | "double" | "hair" | "mediumDashed" | "dashDot" | "mediumDashDot" | "dashDotDot" | "mediumDashDotDot" | "slantDashDot";
|
|
156
|
+
interface BorderEdge {
|
|
157
|
+
readonly style: BorderLineStyle;
|
|
158
|
+
readonly color?: Color;
|
|
159
|
+
}
|
|
160
|
+
/** Per-edge borders. Diagonal borders are not modelled (deferred). */
|
|
161
|
+
interface BorderStyle {
|
|
162
|
+
readonly top?: BorderEdge;
|
|
163
|
+
readonly right?: BorderEdge;
|
|
164
|
+
readonly bottom?: BorderEdge;
|
|
165
|
+
readonly left?: BorderEdge;
|
|
166
|
+
}
|
|
167
|
+
type HorizontalAlignment = "left" | "center" | "right" | "justify" | "fill" | "centerContinuous" | "distributed";
|
|
168
|
+
type VerticalAlignment = "top" | "center" | "bottom" | "justify" | "distributed";
|
|
169
|
+
interface Alignment {
|
|
170
|
+
readonly horizontal?: HorizontalAlignment;
|
|
171
|
+
readonly vertical?: VerticalAlignment;
|
|
172
|
+
readonly wrapText?: boolean;
|
|
173
|
+
readonly shrinkToFit?: boolean;
|
|
174
|
+
/** Indent level (whole units of about 3 spaces), 0–250. */
|
|
175
|
+
readonly indent?: number;
|
|
176
|
+
/**
|
|
177
|
+
* Text rotation in degrees, 0–180 (91–180 mean 1–90° downward, per the spec). The legacy
|
|
178
|
+
* marker 255 ("vertical stacked") is not modelled and degrades to no rotation.
|
|
179
|
+
*/
|
|
180
|
+
readonly textRotation?: number;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* The resolved style of one cell. Every component is optional; a cell whose effective format is
|
|
184
|
+
* the workbook default resolves to no style at all (`Worksheet.style(ref)` returns `undefined`).
|
|
185
|
+
* `numberFormat` is always the format CODE string (e.g. `"yyyy-mm-dd"`, `"0.00%"`) — ids are a
|
|
186
|
+
* file-internal detail and never appear in the API.
|
|
187
|
+
*/
|
|
188
|
+
interface CellStyle {
|
|
189
|
+
readonly numberFormat?: string;
|
|
190
|
+
readonly font?: FontStyle;
|
|
191
|
+
readonly fill?: FillStyle;
|
|
192
|
+
readonly border?: BorderStyle;
|
|
193
|
+
readonly alignment?: Alignment;
|
|
194
|
+
}
|
|
78
195
|
|
|
79
196
|
interface StyleTable {
|
|
80
197
|
/** True when the cell format at this `s` index applies a date/time number format. */
|
|
@@ -85,6 +202,12 @@ interface StyleTable {
|
|
|
85
202
|
* built-in with no portable code, or the index is out of range.
|
|
86
203
|
*/
|
|
87
204
|
formatCode(styleIndex: number | undefined): string | undefined;
|
|
205
|
+
/**
|
|
206
|
+
* The full resolved style at this `s` index — number format code, font, fill, border, and
|
|
207
|
+
* alignment. `undefined` when the index is out of range or the xf resolves to the workbook
|
|
208
|
+
* default (no distinguishing component). Cached: repeated calls return the same object.
|
|
209
|
+
*/
|
|
210
|
+
cellStyle(styleIndex: number | undefined): CellStyle | undefined;
|
|
88
211
|
}
|
|
89
212
|
|
|
90
213
|
interface DecodeContext {
|
|
@@ -101,7 +224,7 @@ interface Relationship {
|
|
|
101
224
|
readonly type: string;
|
|
102
225
|
/** Target exactly as written; resolve internal ones with resolveTarget. */
|
|
103
226
|
readonly target: string;
|
|
104
|
-
readonly targetMode:
|
|
227
|
+
readonly targetMode: "Internal" | "External";
|
|
105
228
|
}
|
|
106
229
|
|
|
107
230
|
interface Row {
|
|
@@ -120,6 +243,8 @@ declare class Worksheet {
|
|
|
120
243
|
get path(): string;
|
|
121
244
|
/** false for hidden or very-hidden sheets. */
|
|
122
245
|
get visible(): boolean;
|
|
246
|
+
/** The tab's visibility state (F4.6): `"visible"`, `"hidden"`, or `"veryHidden"`. */
|
|
247
|
+
get state(): SheetState;
|
|
123
248
|
/**
|
|
124
249
|
* Merged-cell ranges in A1 notation (e.g. `['A1:B1', 'A2:A4']`), in document order. Only the
|
|
125
250
|
* top-left cell of a merge holds a value; the rest read as `empty`. Empty when none.
|
|
@@ -138,6 +263,15 @@ declare class Worksheet {
|
|
|
138
263
|
* 0, usually `"General"`), mirroring how date detection defaults.
|
|
139
264
|
*/
|
|
140
265
|
numberFormat(ref: string): string | undefined;
|
|
266
|
+
/**
|
|
267
|
+
* The resolved style of the cell at `ref` — number format code, font, fill, border, and
|
|
268
|
+
* alignment (F4.1). Resolution shares the same effective-style map as {@link numberFormat}
|
|
269
|
+
* (cell `s` → row `customFormat` default → column default), so the two always agree.
|
|
270
|
+
* `undefined` for an unstyled cell, an absent cell, or a workbook with no style table —
|
|
271
|
+
* "no style" and "the default style" are deliberately the same answer. Objects are cached
|
|
272
|
+
* per distinct format record: two cells sharing a format return the same object.
|
|
273
|
+
*/
|
|
274
|
+
style(ref: string): CellStyle | undefined;
|
|
141
275
|
/**
|
|
142
276
|
* The sheet's declared used range in A1 notation (e.g. `"A1:E10"`, or a single cell), from
|
|
143
277
|
* the worksheet's `<dimension>`. `undefined` when the producer omits it — it is an optional
|
|
@@ -149,6 +283,22 @@ declare class Worksheet {
|
|
|
149
283
|
* resolved `author`, and plain `text`. Empty when the sheet has no comments part.
|
|
150
284
|
*/
|
|
151
285
|
get comments(): readonly Comment[];
|
|
286
|
+
/**
|
|
287
|
+
* Column width/visibility declarations (`<cols>`), in document order (F4.5). Entries carrying
|
|
288
|
+
* only a column-default STYLE are not geometry and are omitted — `style(ref)` already resolves
|
|
289
|
+
* them. Empty when the sheet declares none.
|
|
290
|
+
*/
|
|
291
|
+
get columns(): readonly ColumnProps[];
|
|
292
|
+
/**
|
|
293
|
+
* Per-row height/visibility, keyed by 1-based row index (F4.5). Only rows that declare a
|
|
294
|
+
* height or hidden flag appear. Empty map when none do.
|
|
295
|
+
*/
|
|
296
|
+
get rowProperties(): ReadonlyMap<number, RowProps>;
|
|
297
|
+
/**
|
|
298
|
+
* The sheet's frozen pane, or `undefined` when nothing is frozen (F4.5). Split (non-frozen)
|
|
299
|
+
* panes are not modelled and read as `undefined`.
|
|
300
|
+
*/
|
|
301
|
+
get freeze(): FreezePane | undefined;
|
|
152
302
|
/** The cell at an A1 reference. Absent cells read as `empty` (Excel treats them blank). */
|
|
153
303
|
cell(ref: string): Cell;
|
|
154
304
|
/** Stream the populated rows in document order. Sparse: empty rows/cells are absent. */
|
|
@@ -178,4 +328,94 @@ declare function openXlsx(source: Uint8Array | ArrayBuffer, options?: ReadOption
|
|
|
178
328
|
*/
|
|
179
329
|
declare function streamSheetRows(source: Uint8Array | ArrayBuffer, sheetName?: string, options?: ReadOptions): AsyncGenerator<Row>;
|
|
180
330
|
|
|
181
|
-
|
|
331
|
+
/**
|
|
332
|
+
* A value a cell can hold when writing. The OOXML cell type is inferred from it:
|
|
333
|
+
* `string` → inline string, `number` → numeric, `boolean` → `b`, `Date` → date-styled serial.
|
|
334
|
+
* `null` / `undefined` (including array holes) → an empty cell, omitted from the output.
|
|
335
|
+
*/
|
|
336
|
+
type CellValue = string | number | boolean | Date | null | undefined;
|
|
337
|
+
/**
|
|
338
|
+
* A cell with a {@link CellStyle} attached (F4.2). `value` is required but nullable — a styled
|
|
339
|
+
* BLANK cell (`{ value: null, style }`) is real and emits `<c r s/>`, which is how a border or
|
|
340
|
+
* fill lands on a cell with nothing in it. The style type is exactly what `Worksheet.style(ref)`
|
|
341
|
+
* returns, so read → modify → write carries styles as a pass-through.
|
|
342
|
+
*/
|
|
343
|
+
interface StyledCell {
|
|
344
|
+
readonly value: CellValue;
|
|
345
|
+
readonly style?: CellStyle;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* One cell in a row: a bare value, or a value with a style. Discrimination is total — `null` /
|
|
349
|
+
* `undefined` mean empty, `Date` instances are dates, and any OTHER object must be a
|
|
350
|
+
* {@link StyledCell} (an object without a `value` property throws `invalid-input`, catching stray
|
|
351
|
+
* objects loudly). Bare-value rows are untouched: pre-F4.2 input keeps its exact meaning AND its
|
|
352
|
+
* exact output bytes.
|
|
353
|
+
*/
|
|
354
|
+
type CellInput = CellValue | StyledCell;
|
|
355
|
+
interface SheetInput {
|
|
356
|
+
/** Tab name. 1–31 chars, unique (case-insensitively), free of `\ / ? * [ ] :`. */
|
|
357
|
+
readonly name: string;
|
|
358
|
+
/**
|
|
359
|
+
* Rows top-to-bottom; each a left-to-right array of cells. `rows[0][0]` is A1. A hole or
|
|
360
|
+
* `undefined` row is an empty row (the bridge produces sparse arrays; hand-written input may
|
|
361
|
+
* too) — matching how `null`/`undefined`/holes inside a row mean empty cells.
|
|
362
|
+
*/
|
|
363
|
+
readonly rows: readonly (readonly CellInput[] | undefined)[];
|
|
364
|
+
/**
|
|
365
|
+
* Column width/visibility declarations (F4.5) — the same shape `Worksheet.columns` returns.
|
|
366
|
+
* Ranges are 1-based and inclusive; entries need a `width` and/or `hidden: true`.
|
|
367
|
+
*/
|
|
368
|
+
readonly columns?: readonly ColumnProps[];
|
|
369
|
+
/**
|
|
370
|
+
* Per-row height/visibility keyed by 1-based row index (F4.5) — the same records
|
|
371
|
+
* `Worksheet.rowProperties` holds. A row may have properties without having any cells.
|
|
372
|
+
*/
|
|
373
|
+
readonly rowProperties?: Readonly<Record<number, RowProps>>;
|
|
374
|
+
/** Freeze the top `rows` rows and/or leftmost `cols` columns (F4.5). */
|
|
375
|
+
readonly freeze?: FreezePane;
|
|
376
|
+
/**
|
|
377
|
+
* Merged-cell ranges in canonical A1 form, top-left:bottom-right (e.g. `"A1:B2"`) — the same
|
|
378
|
+
* strings `Worksheet.mergedCells` returns (F4.6). Malformed, single-cell, out-of-grid, and
|
|
379
|
+
* overlapping ranges are rejected: Excel repair-prompts on them.
|
|
380
|
+
*/
|
|
381
|
+
readonly merges?: readonly string[];
|
|
382
|
+
/**
|
|
383
|
+
* Hyperlinks on this sheet (F4.6) — the same records `Worksheet.hyperlinks` returns. Each needs
|
|
384
|
+
* a `ref` (cell or range) plus an external `target` and/or an in-workbook `location`; `tooltip`
|
|
385
|
+
* and `display` are optional. External targets get the sheet's relationships part.
|
|
386
|
+
*/
|
|
387
|
+
readonly hyperlinks?: readonly Hyperlink[];
|
|
388
|
+
/**
|
|
389
|
+
* Tab visibility (F4.6). Defaults to `"visible"`; at least one sheet in the workbook must
|
|
390
|
+
* remain visible, or Excel refuses the file.
|
|
391
|
+
*/
|
|
392
|
+
readonly state?: SheetState;
|
|
393
|
+
}
|
|
394
|
+
interface WorkbookInput {
|
|
395
|
+
/** At least one sheet, in tab order. */
|
|
396
|
+
readonly sheets: readonly SheetInput[];
|
|
397
|
+
}
|
|
398
|
+
interface WriteOptions {
|
|
399
|
+
/** Use the 1904 date epoch (legacy Mac) instead of the default 1900 system. */
|
|
400
|
+
readonly date1904?: boolean;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Convert an open {@link Workbook} into {@link WorkbookInput} for {@link writeXlsx}. Each populated
|
|
405
|
+
* cell is placed at its own A1 reference with its resolved style (if any), preserving sheet names
|
|
406
|
+
* and tab order. Rows/columns are left sparse (array holes) — the writer treats a hole as an empty
|
|
407
|
+
* cell — so a workbook with a few far-apart cells does not materialize a dense grid. An unstyled
|
|
408
|
+
* workbook yields bare values only: the exact pre-styles WorkbookInput, and the exact same bytes
|
|
409
|
+
* on rewrite.
|
|
410
|
+
*/
|
|
411
|
+
declare function workbookToInput(workbook: Workbook): Promise<WorkbookInput>;
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Serialize a workbook to `.xlsx` bytes. Async because compression runs on the platform's
|
|
415
|
+
* CompressionStream. Throws {@link XlsxError} with code `invalid-input` for anything that can't be
|
|
416
|
+
* represented — no sheets, a bad sheet name, or a cell value that isn't a string, finite number,
|
|
417
|
+
* boolean, Date, or null.
|
|
418
|
+
*/
|
|
419
|
+
declare function writeXlsx(workbook: WorkbookInput, options?: WriteOptions): Promise<Uint8Array>;
|
|
420
|
+
|
|
421
|
+
export { type Alignment, type BorderEdge, type BorderLineStyle, type BorderStyle, type Cell, type CellInput, type CellRef, type CellStyle, type CellType, type CellValue, type Color, type ColumnProps, type Comment, type FillStyle, type FontStyle, type FreezePane, type HorizontalAlignment, type Hyperlink, type PatternType, type ReadOptions, type Row, type RowProps, type SheetInfo, type SheetInput, type SheetState, type StyledCell, type UnderlineStyle, type VerticalAlignment, Workbook, type WorkbookInput, Worksheet, type WriteOptions, XlsxError, type XlsxErrorCode, columnToIndex, dateToSerial, formatRef, indexToColumn, openXlsx, parseRef, serialToDate, streamSheetRows, workbookToInput, writeXlsx };
|