@simplysm/excel 13.0.98 → 13.0.99

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 CHANGED
@@ -8,25 +8,75 @@ Excel file processing library. Platform-neutral (works in both browser and Node.
8
8
  npm install @simplysm/excel
9
9
  ```
10
10
 
11
- ## Exports
12
-
13
- ```typescript
14
- import {
15
- ExcelWorkbook,
16
- ExcelWorksheet,
17
- ExcelRow,
18
- ExcelCol,
19
- ExcelCell,
20
- ExcelUtils,
21
- ExcelWrapper,
22
- } from "@simplysm/excel";
23
- ```
24
-
25
- ## Quick Start
11
+ ## API Overview
12
+
13
+ ### Types
14
+
15
+ | API | Type | Description |
16
+ |-----|------|-------------|
17
+ | `ExcelValueType` | type | Union of supported cell value types (`number`, `string`, `DateOnly`, `DateTime`, `Time`, `boolean`, `undefined`) |
18
+ | `ExcelNumberFormat` | type | Number format name (`"number"`, `"string"`, `"DateOnly"`, `"DateTime"`, `"Time"`) |
19
+ | `ExcelCellType` | type | Cell type identifier (`"s"`, `"b"`, `"str"`, `"n"`, `"inlineStr"`, `"e"`) |
20
+ | `ExcelAddressPoint` | interface | Cell coordinate (`r`, `c`, 0-based) |
21
+ | `ExcelAddressRangePoint` | interface | Range of cell coordinates (`s`, `e`) |
22
+ | `ExcelBorderPosition` | type | Border position (`"left"`, `"right"`, `"top"`, `"bottom"`) |
23
+ | `ExcelHorizontalAlign` | type | Horizontal alignment (`"center"`, `"left"`, `"right"`) |
24
+ | `ExcelVerticalAlign` | type | Vertical alignment (`"center"`, `"top"`, `"bottom"`) |
25
+ | `ExcelStyleOptions` | interface | Cell style options (`background`, `border`, `horizontalAlign`, `verticalAlign`, `numberFormat`) |
26
+ | `ExcelXml` | interface | Excel XML interface (`data`, `cleanup()`) |
27
+ | `ExcelXmlContentTypeData` | interface | Content type XML data |
28
+ | `ExcelXmlRelationshipData` | interface | Relationship XML data |
29
+ | `ExcelRelationshipData` | interface | Single relationship data |
30
+ | `ExcelXmlWorkbookData` | interface | Workbook XML data |
31
+ | `ExcelXmlWorksheetData` | interface | Worksheet XML data |
32
+ | `ExcelRowData` | interface | Row XML data |
33
+ | `ExcelCellData` | interface | Cell XML data |
34
+ | `ExcelXmlDrawingData` | interface | Drawing XML data |
35
+ | `ExcelXmlSharedStringData` | interface | Shared strings XML data |
36
+ | `ExcelXmlSharedStringDataSi` | type | Shared string item |
37
+ | `ExcelXmlSharedStringDataText` | type | Shared string text |
38
+ | `ExcelXmlStyleData` | interface | Style XML data |
39
+ | `ExcelXmlStyleDataXf` | interface | Cell format definition |
40
+ | `ExcelXmlStyleDataFill` | interface | Fill style definition |
41
+ | `ExcelXmlStyleDataBorder` | interface | Border style definition |
42
+
43
+ -> See [docs/types.md](./docs/types.md) for details.
44
+
45
+ ### Utilities
46
+
47
+ | API | Type | Description |
48
+ |-----|------|-------------|
49
+ | `ExcelUtils` | class | Cell address conversion, date/number conversion, number format processing |
50
+
51
+ -> See [docs/utilities.md](./docs/utilities.md) for details.
52
+
53
+ ### Core Classes
54
+
55
+ | API | Type | Description |
56
+ |-----|------|-------------|
57
+ | `ExcelWorkbook` | class | Workbook processing with lazy-loading ZIP architecture |
58
+ | `ExcelWorksheet` | class | Worksheet with cell access, copying, data tables, images |
59
+ | `ExcelRow` | class | Row with cell access |
60
+ | `ExcelCol` | class | Column with cell access and width configuration |
61
+ | `ExcelCell` | class | Cell with value, formula, style, and merge operations |
62
+
63
+ -> See [docs/core-classes.md](./docs/core-classes.md) for details.
64
+
65
+ ### Wrapper
66
+
67
+ | API | Type | Description |
68
+ |-----|------|-------------|
69
+ | `ExcelWrapper` | class | Zod schema-based type-safe Excel read/write |
70
+
71
+ -> See [docs/wrapper.md](./docs/wrapper.md) for details.
72
+
73
+ ## Usage Examples
26
74
 
27
75
  ### Create a new workbook
28
76
 
29
77
  ```typescript
78
+ import { ExcelWorkbook } from "@simplysm/excel";
79
+
30
80
  await using wb = new ExcelWorkbook();
31
81
  const ws = await wb.addWorksheet("Sheet1");
32
82
  await ws.cell(0, 0).setValue("Name");
@@ -49,6 +99,7 @@ const dataTable = await ws.getDataTable();
49
99
 
50
100
  ```typescript
51
101
  import { z } from "zod";
102
+ import { ExcelWrapper } from "@simplysm/excel";
52
103
 
53
104
  const schema = z.object({
54
105
  name: z.string().describe("Name"),
@@ -66,9 +117,3 @@ await using wb = await wrapper.write("Sheet1", [
66
117
  ]);
67
118
  const bytes = await wb.toBytes();
68
119
  ```
69
-
70
- ## Documentation
71
-
72
- - [Types](docs/types.md)
73
- - [Core Classes](docs/core-classes.md)
74
- - [Wrapper](docs/wrapper.md)
@@ -0,0 +1,541 @@
1
+ # Core Classes
2
+
3
+ ## ExcelWorkbook
4
+
5
+ Excel workbook processing class. Internally manages ZIP resources.
6
+
7
+ Adopts a Lazy Loading architecture for memory efficiency with large Excel files: XML inside the ZIP is read and parsed only at the point of access.
8
+
9
+ ```typescript
10
+ import { ExcelWorkbook } from "@simplysm/excel";
11
+ ```
12
+
13
+ ### Constructor
14
+
15
+ ```typescript
16
+ constructor(arg?: Blob | Bytes)
17
+ ```
18
+
19
+ - `arg` -- Existing Excel file data (Blob or Uint8Array). Creates a new workbook if omitted.
20
+
21
+ ### Methods
22
+
23
+ #### `getWorksheetNames`
24
+
25
+ Return all worksheet names in the workbook.
26
+
27
+ ```typescript
28
+ async getWorksheetNames(): Promise<string[]>;
29
+ ```
30
+
31
+ #### `addWorksheet`
32
+
33
+ Create and return a new worksheet.
34
+
35
+ ```typescript
36
+ async addWorksheet(name: string): Promise<ExcelWorksheet>;
37
+ ```
38
+
39
+ #### `getWorksheet`
40
+
41
+ Look up a worksheet by name or index (0-based).
42
+
43
+ ```typescript
44
+ async getWorksheet(nameOrIndex: string | number): Promise<ExcelWorksheet>;
45
+ ```
46
+
47
+ #### `toBytes`
48
+
49
+ Export workbook as byte array.
50
+
51
+ ```typescript
52
+ async toBytes(): Promise<Bytes>;
53
+ ```
54
+
55
+ #### `toBlob`
56
+
57
+ Export workbook as Blob.
58
+
59
+ ```typescript
60
+ async toBlob(): Promise<Blob>;
61
+ ```
62
+
63
+ #### `close`
64
+
65
+ Release workbook resources. Safe to call on an already closed workbook (no-op). The workbook instance cannot be used after this call.
66
+
67
+ ```typescript
68
+ async close(): Promise<void>;
69
+ ```
70
+
71
+ Implements `Symbol.asyncDispose` for use with `await using`.
72
+
73
+ ### Example
74
+
75
+ ```typescript
76
+ // Using await using (recommended)
77
+ await using wb = new ExcelWorkbook(bytes);
78
+ const ws = await wb.getWorksheet(0);
79
+ // Resources automatically released at scope exit
80
+
81
+ // Or using try-finally
82
+ const wb = new ExcelWorkbook(bytes);
83
+ try {
84
+ const ws = await wb.getWorksheet(0);
85
+ } finally {
86
+ await wb.close();
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ ## ExcelWorksheet
93
+
94
+ Class representing an Excel worksheet. Provides cell access, row/column copying, data table processing, and image insertion.
95
+
96
+ ### Cell Access
97
+
98
+ #### `row`
99
+
100
+ Return row object (0-based).
101
+
102
+ ```typescript
103
+ row(r: number): ExcelRow;
104
+ ```
105
+
106
+ #### `cell`
107
+
108
+ Return cell object (0-based row/column).
109
+
110
+ ```typescript
111
+ cell(r: number, c: number): ExcelCell;
112
+ ```
113
+
114
+ #### `col`
115
+
116
+ Return column object (0-based).
117
+
118
+ ```typescript
119
+ col(c: number): ExcelCol;
120
+ ```
121
+
122
+ ### Name Methods
123
+
124
+ #### `getName`
125
+
126
+ ```typescript
127
+ async getName(): Promise<string>;
128
+ ```
129
+
130
+ #### `setName`
131
+
132
+ ```typescript
133
+ async setName(newName: string): Promise<void>;
134
+ ```
135
+
136
+ ### Copy Methods
137
+
138
+ #### `copyRowStyle`
139
+
140
+ Copy style from source row to target row.
141
+
142
+ ```typescript
143
+ async copyRowStyle(srcR: number, targetR: number): Promise<void>;
144
+ ```
145
+
146
+ #### `copyCellStyle`
147
+
148
+ Copy style from source cell to target cell.
149
+
150
+ ```typescript
151
+ async copyCellStyle(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint): Promise<void>;
152
+ ```
153
+
154
+ #### `copyRow`
155
+
156
+ Copy source row to target row (overwrite).
157
+
158
+ ```typescript
159
+ async copyRow(srcR: number, targetR: number): Promise<void>;
160
+ ```
161
+
162
+ #### `copyCell`
163
+
164
+ Copy source cell to target cell.
165
+
166
+ ```typescript
167
+ async copyCell(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint): Promise<void>;
168
+ ```
169
+
170
+ #### `insertCopyRow`
171
+
172
+ Insert-copy the source row at the target position. Existing rows at and below the target are shifted down by one.
173
+
174
+ ```typescript
175
+ async insertCopyRow(srcR: number, targetR: number): Promise<void>;
176
+ ```
177
+
178
+ ### Range Methods
179
+
180
+ #### `getRange`
181
+
182
+ Return data range of the worksheet.
183
+
184
+ ```typescript
185
+ async getRange(): Promise<ExcelAddressRangePoint>;
186
+ ```
187
+
188
+ #### `getCells`
189
+
190
+ Return all cells as a 2D array.
191
+
192
+ ```typescript
193
+ async getCells(): Promise<ExcelCell[][]>;
194
+ ```
195
+
196
+ ### Data Methods
197
+
198
+ #### `getDataTable`
199
+
200
+ Return worksheet data as a table (record array).
201
+
202
+ ```typescript
203
+ async getDataTable(opt?: {
204
+ headerRowIndex?: number;
205
+ checkEndColIndex?: number;
206
+ usableHeaderNameFn?: (headerName: string) => boolean;
207
+ }): Promise<Record<string, ExcelValueType>[]>;
208
+ ```
209
+
210
+ **Parameters:**
211
+ - `opt.headerRowIndex` -- Header row index (default: first row)
212
+ - `opt.checkEndColIndex` -- Column index to determine data end. Data ends when this column is empty.
213
+ - `opt.usableHeaderNameFn` -- Function to filter usable headers
214
+
215
+ #### `setDataMatrix`
216
+
217
+ Write 2D array data to the worksheet.
218
+
219
+ ```typescript
220
+ async setDataMatrix(matrix: ExcelValueType[][]): Promise<void>;
221
+ ```
222
+
223
+ #### `setRecords`
224
+
225
+ Write record array to the worksheet. Headers are auto-generated in the first row, data follows in subsequent rows.
226
+
227
+ ```typescript
228
+ async setRecords(records: Record<string, ExcelValueType>[]): Promise<void>;
229
+ ```
230
+
231
+ ### View Methods
232
+
233
+ #### `setZoom`
234
+
235
+ Set worksheet zoom scale (percent).
236
+
237
+ ```typescript
238
+ async setZoom(percent: number): Promise<void>;
239
+ ```
240
+
241
+ #### `freezeAt`
242
+
243
+ Set freeze panes for rows/columns.
244
+
245
+ ```typescript
246
+ async freezeAt(point: { r?: number; c?: number }): Promise<void>;
247
+ ```
248
+
249
+ ### Image Methods
250
+
251
+ #### `addImage`
252
+
253
+ Insert an image into the worksheet.
254
+
255
+ ```typescript
256
+ async addImage(opts: {
257
+ bytes: Bytes;
258
+ ext: string;
259
+ from: { r: number; c: number; rOff?: number | string; cOff?: number | string };
260
+ to?: { r: number; c: number; rOff?: number | string; cOff?: number | string };
261
+ }): Promise<void>;
262
+ ```
263
+
264
+ **Parameters:**
265
+ - `opts.bytes` -- Image binary data
266
+ - `opts.ext` -- Image extension (png, jpg, etc.)
267
+ - `opts.from` -- Image start position (0-based row/column index, rOff/cOff in EMU offset)
268
+ - `opts.to` -- Image end position (if omitted, inserted at from position with original size)
269
+
270
+ ---
271
+
272
+ ## ExcelRow
273
+
274
+ Class representing a row in an Excel worksheet. Provides cell access functionality.
275
+
276
+ #### `cell`
277
+
278
+ Return cell at the given column index (0-based).
279
+
280
+ ```typescript
281
+ cell(c: number): ExcelCell;
282
+ ```
283
+
284
+ #### `getCells`
285
+
286
+ Return all cells in the row.
287
+
288
+ ```typescript
289
+ async getCells(): Promise<ExcelCell[]>;
290
+ ```
291
+
292
+ ---
293
+
294
+ ## ExcelCol
295
+
296
+ Class representing a column in an Excel worksheet. Provides cell access and column width configuration.
297
+
298
+ #### `cell`
299
+
300
+ Return cell at the given row index (0-based).
301
+
302
+ ```typescript
303
+ cell(r: number): ExcelCell;
304
+ ```
305
+
306
+ #### `getCells`
307
+
308
+ Return all cells in the column.
309
+
310
+ ```typescript
311
+ async getCells(): Promise<ExcelCell[]>;
312
+ ```
313
+
314
+ #### `setWidth`
315
+
316
+ Set column width.
317
+
318
+ ```typescript
319
+ async setWidth(size: number): Promise<void>;
320
+ ```
321
+
322
+ ---
323
+
324
+ ## ExcelCell
325
+
326
+ Class representing an Excel cell. Provides value read/write, formula, style, and cell merge functionality.
327
+
328
+ All cell methods are `async` because the required XML (SharedStrings, Styles, etc.) is loaded on-demand for memory efficiency.
329
+
330
+ ### Properties
331
+
332
+ #### `addr`
333
+
334
+ Cell address (0-based row/column index).
335
+
336
+ ```typescript
337
+ readonly addr: ExcelAddressPoint;
338
+ ```
339
+
340
+ ### Value Methods
341
+
342
+ #### `getValue`
343
+
344
+ Return cell value.
345
+
346
+ ```typescript
347
+ async getValue(): Promise<ExcelValueType>;
348
+ ```
349
+
350
+ #### `setValue`
351
+
352
+ Set cell value (`undefined` deletes the cell).
353
+
354
+ ```typescript
355
+ async setValue(val: ExcelValueType): Promise<void>;
356
+ ```
357
+
358
+ #### `getFormula`
359
+
360
+ Return cell formula.
361
+
362
+ ```typescript
363
+ async getFormula(): Promise<string | undefined>;
364
+ ```
365
+
366
+ #### `setFormula`
367
+
368
+ Set formula on cell (`undefined` removes the formula).
369
+
370
+ ```typescript
371
+ async setFormula(val: string | undefined): Promise<void>;
372
+ ```
373
+
374
+ ### Merge Methods
375
+
376
+ #### `merge`
377
+
378
+ Merge cells from current cell to the specified end coordinates.
379
+
380
+ ```typescript
381
+ async merge(r: number, c: number): Promise<void>;
382
+ ```
383
+
384
+ **Example:**
385
+ ```typescript
386
+ // Merges range A1:C3 (3 rows x 3 columns)
387
+ await ws.cell(0, 0).merge(2, 2);
388
+ ```
389
+
390
+ ### Style Methods
391
+
392
+ #### `getStyleId`
393
+
394
+ Return cell style ID.
395
+
396
+ ```typescript
397
+ async getStyleId(): Promise<string | undefined>;
398
+ ```
399
+
400
+ #### `setStyleId`
401
+
402
+ Set cell style ID.
403
+
404
+ ```typescript
405
+ async setStyleId(styleId: string | undefined): Promise<void>;
406
+ ```
407
+
408
+ #### `setStyle`
409
+
410
+ Set cell style.
411
+
412
+ ```typescript
413
+ async setStyle(opts: ExcelStyleOptions): Promise<void>;
414
+ ```
415
+
416
+ ---
417
+
418
+ ## ExcelUtils
419
+
420
+ Collection of Excel utility functions. Provides cell address conversion, date/number conversion, and number format processing.
421
+
422
+ ```typescript
423
+ import { ExcelUtils } from "@simplysm/excel";
424
+ ```
425
+
426
+ ### Address Conversion
427
+
428
+ #### `stringifyAddr`
429
+
430
+ Convert cell coordinates to "A1" format string.
431
+
432
+ ```typescript
433
+ static stringifyAddr(point: ExcelAddressPoint): string;
434
+ ```
435
+
436
+ #### `stringifyRowAddr`
437
+
438
+ Convert row index (0-based) to row address string (e.g. `0` -> `"1"`).
439
+
440
+ ```typescript
441
+ static stringifyRowAddr(r: number): string;
442
+ ```
443
+
444
+ #### `stringifyColAddr`
445
+
446
+ Convert column index (0-based) to column address string (e.g. `0` -> `"A"`, `26` -> `"AA"`).
447
+
448
+ ```typescript
449
+ static stringifyColAddr(c: number): string;
450
+ ```
451
+
452
+ #### `parseRowAddr`
453
+
454
+ Extract row index from cell address (e.g. `"A3"` -> `2`).
455
+
456
+ ```typescript
457
+ static parseRowAddr(addr: string): number;
458
+ ```
459
+
460
+ #### `parseColAddr`
461
+
462
+ Extract column index from cell address (e.g. `"B3"` -> `1`).
463
+
464
+ ```typescript
465
+ static parseColAddr(addr: string): number;
466
+ ```
467
+
468
+ #### `parseCellAddr`
469
+
470
+ Convert cell address to coordinates (e.g. `"B3"` -> `{r: 2, c: 1}`).
471
+
472
+ ```typescript
473
+ static parseCellAddr(addr: string): ExcelAddressPoint;
474
+ ```
475
+
476
+ #### `parseRangeAddr`
477
+
478
+ Convert range address to coordinates (e.g. `"A1:C3"` -> `{s: {r:0,c:0}, e: {r:2,c:2}}`).
479
+
480
+ ```typescript
481
+ static parseRangeAddr(rangeAddr: string): ExcelAddressRangePoint;
482
+ ```
483
+
484
+ #### `stringifyRangeAddr`
485
+
486
+ Convert range coordinates to address string.
487
+
488
+ ```typescript
489
+ static stringifyRangeAddr(point: ExcelAddressRangePoint): string;
490
+ ```
491
+
492
+ ### Date/Number Conversion
493
+
494
+ #### `convertTimeTickToNumber`
495
+
496
+ Convert JavaScript timestamp (ms) to Excel date number. Excel counts 1900-01-01 as 1 (1899-12-30 is date 0).
497
+
498
+ ```typescript
499
+ static convertTimeTickToNumber(tick: number): number;
500
+ ```
501
+
502
+ #### `convertNumberToTimeTick`
503
+
504
+ Convert Excel date number to JavaScript timestamp (ms).
505
+
506
+ ```typescript
507
+ static convertNumberToTimeTick(value: number): number;
508
+ ```
509
+
510
+ ### Number Format
511
+
512
+ #### `convertNumFmtCodeToName`
513
+
514
+ Convert number format code to format name.
515
+
516
+ ```typescript
517
+ static convertNumFmtCodeToName(numFmtCode: string): ExcelNumberFormat;
518
+ ```
519
+
520
+ #### `convertNumFmtIdToName`
521
+
522
+ Convert number format ID to format name.
523
+
524
+ ```typescript
525
+ static convertNumFmtIdToName(numFmtId: number): ExcelNumberFormat;
526
+ ```
527
+
528
+ Built-in format ID ranges:
529
+ - `0-13, 37-40, 48`: number/general/currency/percent formats
530
+ - `14-17, 27-31, 34-36, 50-58`: date formats (including localized)
531
+ - `22`: date+time format
532
+ - `18-21, 32-33, 45-47`: time formats
533
+ - `49`: text format
534
+
535
+ #### `convertNumFmtNameToId`
536
+
537
+ Convert number format name to format ID.
538
+
539
+ ```typescript
540
+ static convertNumFmtNameToId(numFmtName: ExcelNumberFormat): number;
541
+ ```
package/docs/types.md ADDED
@@ -0,0 +1,297 @@
1
+ # Types
2
+
3
+ All type exports from the excel package.
4
+
5
+ ```typescript
6
+ import type {
7
+ ExcelValueType,
8
+ ExcelNumberFormat,
9
+ ExcelCellType,
10
+ ExcelAddressPoint,
11
+ ExcelAddressRangePoint,
12
+ ExcelStyleOptions,
13
+ ExcelBorderPosition,
14
+ ExcelHorizontalAlign,
15
+ ExcelVerticalAlign,
16
+ ExcelXml,
17
+ // XML data types (internal)
18
+ ExcelXmlContentTypeData,
19
+ ExcelXmlRelationshipData,
20
+ ExcelXmlWorkbookData,
21
+ ExcelXmlWorksheetData,
22
+ ExcelRowData,
23
+ ExcelCellData,
24
+ ExcelXmlDrawingData,
25
+ ExcelXmlSharedStringData,
26
+ ExcelXmlSharedStringDataSi,
27
+ ExcelXmlSharedStringDataText,
28
+ ExcelXmlStyleData,
29
+ ExcelXmlStyleDataXf,
30
+ ExcelXmlStyleDataFill,
31
+ ExcelXmlStyleDataBorder,
32
+ } from "@simplysm/excel";
33
+ ```
34
+
35
+ ## Value Types
36
+
37
+ ### `ExcelValueType`
38
+
39
+ Union of supported cell value types.
40
+
41
+ ```typescript
42
+ type ExcelValueType = number | string | DateOnly | DateTime | Time | boolean | undefined;
43
+ ```
44
+
45
+ ### `ExcelNumberFormat`
46
+
47
+ Number format name.
48
+
49
+ ```typescript
50
+ type ExcelNumberFormat = "number" | "string" | "DateOnly" | "DateTime" | "Time";
51
+ ```
52
+
53
+ ### `ExcelCellType`
54
+
55
+ Excel cell type identifier.
56
+
57
+ ```typescript
58
+ type ExcelCellType = "s" | "b" | "str" | "n" | "inlineStr" | "e";
59
+ ```
60
+
61
+ - `s` -- shared string (SharedString)
62
+ - `b` -- boolean
63
+ - `str` -- formula result string
64
+ - `n` -- number
65
+ - `inlineStr` -- inline string (rich text)
66
+ - `e` -- error
67
+
68
+ ## Address Types
69
+
70
+ ### `ExcelAddressPoint`
71
+
72
+ Cell coordinate (0-based).
73
+
74
+ ```typescript
75
+ interface ExcelAddressPoint {
76
+ r: number;
77
+ c: number;
78
+ }
79
+ ```
80
+
81
+ ### `ExcelAddressRangePoint`
82
+
83
+ Range of cell coordinates (start and end).
84
+
85
+ ```typescript
86
+ interface ExcelAddressRangePoint {
87
+ s: ExcelAddressPoint;
88
+ e: ExcelAddressPoint;
89
+ }
90
+ ```
91
+
92
+ ## Style Types
93
+
94
+ ### `ExcelBorderPosition`
95
+
96
+ ```typescript
97
+ type ExcelBorderPosition = "left" | "right" | "top" | "bottom";
98
+ ```
99
+
100
+ ### `ExcelHorizontalAlign`
101
+
102
+ ```typescript
103
+ type ExcelHorizontalAlign = "center" | "left" | "right";
104
+ ```
105
+
106
+ ### `ExcelVerticalAlign`
107
+
108
+ ```typescript
109
+ type ExcelVerticalAlign = "center" | "top" | "bottom";
110
+ ```
111
+
112
+ ### `ExcelStyleOptions`
113
+
114
+ Cell style options.
115
+
116
+ ```typescript
117
+ interface ExcelStyleOptions {
118
+ /** Background color (ARGB format, e.g. "00FF0000") */
119
+ background?: string;
120
+ /** Border positions */
121
+ border?: ExcelBorderPosition[];
122
+ /** Horizontal alignment */
123
+ horizontalAlign?: ExcelHorizontalAlign;
124
+ /** Vertical alignment */
125
+ verticalAlign?: ExcelVerticalAlign;
126
+ /** Number format */
127
+ numberFormat?: ExcelNumberFormat;
128
+ }
129
+ ```
130
+
131
+ **Example:**
132
+ ```typescript
133
+ await cell.setStyle({
134
+ background: "00FF0000",
135
+ border: ["left", "right", "top", "bottom"],
136
+ horizontalAlign: "center",
137
+ verticalAlign: "center",
138
+ numberFormat: "number",
139
+ });
140
+ ```
141
+
142
+ ## Excel XML Interface
143
+
144
+ ### `ExcelXml`
145
+
146
+ ```typescript
147
+ interface ExcelXml {
148
+ readonly data: unknown;
149
+ cleanup(): void;
150
+ }
151
+ ```
152
+
153
+ ## XML Data Types
154
+
155
+ These types represent the internal XML structure of `.xlsx` files. They are used internally by the library but exported for advanced use cases.
156
+
157
+ ### `ExcelXmlContentTypeData`
158
+
159
+ Content type definitions (`[Content_Types].xml`).
160
+
161
+ ```typescript
162
+ interface ExcelXmlContentTypeData {
163
+ Types: {
164
+ $: { xmlns: string };
165
+ Default: { $: { Extension: string; ContentType: string } }[];
166
+ Override: { $: { PartName: string; ContentType: string } }[];
167
+ };
168
+ }
169
+ ```
170
+
171
+ ### `ExcelXmlRelationshipData`
172
+
173
+ Relationship definitions (`.rels` files).
174
+
175
+ ```typescript
176
+ interface ExcelXmlRelationshipData {
177
+ Relationships: {
178
+ $: { xmlns: string };
179
+ Relationship?: ExcelRelationshipData[];
180
+ };
181
+ }
182
+ ```
183
+
184
+ ### `ExcelXmlWorkbookData`
185
+
186
+ Workbook XML data.
187
+
188
+ ```typescript
189
+ interface ExcelXmlWorkbookData {
190
+ workbook: {
191
+ $: { "xmlns": string; "xmlns:r"?: string };
192
+ bookViews?: [{ workbookView: [{}] }];
193
+ sheets?: [{ sheet: { $: { "name": string; "sheetId": string; "r:id": string } }[] }];
194
+ };
195
+ }
196
+ ```
197
+
198
+ ### `ExcelXmlWorksheetData`
199
+
200
+ Worksheet XML data. Contains sheet data, dimensions, views, columns, merge cells, and drawing references.
201
+
202
+ ### `ExcelRowData`
203
+
204
+ ```typescript
205
+ interface ExcelRowData {
206
+ $: { r: string }; // row address (1-based)
207
+ c?: ExcelCellData[];
208
+ }
209
+ ```
210
+
211
+ ### `ExcelCellData`
212
+
213
+ ```typescript
214
+ interface ExcelCellData {
215
+ $: {
216
+ r: string; // cell address (e.g. "A1")
217
+ s?: string; // styleId
218
+ t?: ExcelCellType; // type
219
+ };
220
+ v?: [string]; // value
221
+ f?: [string]; // formula
222
+ is?: { t?: (string | { _?: string })[] }[]; // inline string
223
+ }
224
+ ```
225
+
226
+ ### `ExcelXmlDrawingData`
227
+
228
+ Drawing XML data (embedded images).
229
+
230
+ ### `ExcelXmlSharedStringData`
231
+
232
+ Shared strings table.
233
+
234
+ ```typescript
235
+ interface ExcelXmlSharedStringData {
236
+ sst: {
237
+ $: { xmlns: string };
238
+ si?: ExcelXmlSharedStringDataSi[];
239
+ };
240
+ }
241
+ ```
242
+
243
+ ### `ExcelXmlSharedStringDataSi`
244
+
245
+ ```typescript
246
+ type ExcelXmlSharedStringDataSi =
247
+ | { t: ExcelXmlSharedStringDataText }
248
+ | { r: { t: ExcelXmlSharedStringDataText }[] };
249
+ ```
250
+
251
+ ### `ExcelXmlSharedStringDataText`
252
+
253
+ ```typescript
254
+ type ExcelXmlSharedStringDataText = [
255
+ string | { $: { space?: "preserve" }; _?: string },
256
+ ];
257
+ ```
258
+
259
+ ### `ExcelXmlStyleData`
260
+
261
+ Style definitions (styles.xml). Contains number formats, fonts, fills, borders, and cell formats.
262
+
263
+ ### `ExcelXmlStyleDataXf`
264
+
265
+ Cell format definition.
266
+
267
+ ```typescript
268
+ interface ExcelXmlStyleDataXf {
269
+ $: {
270
+ numFmtId?: string;
271
+ fontId?: string;
272
+ fillId?: string;
273
+ borderId?: string;
274
+ xfId?: string;
275
+ applyNumberFormat?: string;
276
+ applyFont?: string;
277
+ applyAlignment?: string;
278
+ applyFill?: string;
279
+ applyBorder?: string;
280
+ };
281
+ alignment?: [{ $: { horizontal?: "center" | "left" | "right"; vertical?: "center" | "top" | "bottom" } }];
282
+ }
283
+ ```
284
+
285
+ ### `ExcelXmlStyleDataFill`
286
+
287
+ Fill style definition.
288
+
289
+ ```typescript
290
+ interface ExcelXmlStyleDataFill {
291
+ patternFill: [{ $: { patternType: "none" | "solid" | "gray125" }; fgColor?: [{ $: { rgb: string } }] }];
292
+ }
293
+ ```
294
+
295
+ ### `ExcelXmlStyleDataBorder`
296
+
297
+ Border style definition. Each side (`top`, `left`, `right`, `bottom`) has `style` (`"thin"` | `"medium"`) and optional `color`.
@@ -0,0 +1,128 @@
1
+ # Utilities
2
+
3
+ ## `ExcelUtils`
4
+
5
+ Collection of Excel utility functions. Provides cell address conversion, date/number conversion, and number format processing.
6
+
7
+ ```typescript
8
+ import { ExcelUtils } from "@simplysm/excel";
9
+ ```
10
+
11
+ ### Address Conversion
12
+
13
+ #### `stringifyAddr`
14
+
15
+ Convert cell coordinates to "A1" format string.
16
+
17
+ ```typescript
18
+ static stringifyAddr(point: ExcelAddressPoint): string;
19
+ ```
20
+
21
+ #### `stringifyRowAddr`
22
+
23
+ Convert row index (0-based) to row address string (e.g. `0` -> `"1"`).
24
+
25
+ ```typescript
26
+ static stringifyRowAddr(r: number): string;
27
+ ```
28
+
29
+ #### `stringifyColAddr`
30
+
31
+ Convert column index (0-based) to column address string (e.g. `0` -> `"A"`, `26` -> `"AA"`).
32
+
33
+ ```typescript
34
+ static stringifyColAddr(c: number): string;
35
+ ```
36
+
37
+ **Throws:** `Error` if column index is outside range `0-16383`.
38
+
39
+ #### `parseRowAddr`
40
+
41
+ Extract row index from cell address (e.g. `"A3"` -> `2`).
42
+
43
+ ```typescript
44
+ static parseRowAddr(addr: string): number;
45
+ ```
46
+
47
+ #### `parseColAddr`
48
+
49
+ Extract column index from cell address (e.g. `"B3"` -> `1`).
50
+
51
+ ```typescript
52
+ static parseColAddr(addr: string): number;
53
+ ```
54
+
55
+ #### `parseCellAddr`
56
+
57
+ Convert cell address to coordinates (e.g. `"B3"` -> `{r: 2, c: 1}`).
58
+
59
+ ```typescript
60
+ static parseCellAddr(addr: string): ExcelAddressPoint;
61
+ ```
62
+
63
+ #### `parseRangeAddr`
64
+
65
+ Convert range address to coordinates (e.g. `"A1:C3"` -> `{s: {r:0,c:0}, e: {r:2,c:2}}`).
66
+
67
+ ```typescript
68
+ static parseRangeAddr(rangeAddr: string): ExcelAddressRangePoint;
69
+ ```
70
+
71
+ #### `stringifyRangeAddr`
72
+
73
+ Convert range coordinates to address string.
74
+
75
+ ```typescript
76
+ static stringifyRangeAddr(point: ExcelAddressRangePoint): string;
77
+ ```
78
+
79
+ ### Date/Number Conversion
80
+
81
+ #### `convertTimeTickToNumber`
82
+
83
+ Convert JavaScript timestamp (ms) to Excel date number. Excel counts 1900-01-01 as 1 (1899-12-30 is date 0).
84
+
85
+ ```typescript
86
+ static convertTimeTickToNumber(tick: number): number;
87
+ ```
88
+
89
+ #### `convertNumberToTimeTick`
90
+
91
+ Convert Excel date number to JavaScript timestamp (ms).
92
+
93
+ ```typescript
94
+ static convertNumberToTimeTick(value: number): number;
95
+ ```
96
+
97
+ ### Number Format
98
+
99
+ #### `convertNumFmtCodeToName`
100
+
101
+ Convert number format code to format name.
102
+
103
+ ```typescript
104
+ static convertNumFmtCodeToName(numFmtCode: string): ExcelNumberFormat;
105
+ ```
106
+
107
+ #### `convertNumFmtIdToName`
108
+
109
+ Convert number format ID to format name.
110
+
111
+ ```typescript
112
+ static convertNumFmtIdToName(numFmtId: number): ExcelNumberFormat;
113
+ ```
114
+
115
+ Built-in format ID ranges:
116
+ - `0-13, 37-40, 48`: number/general/currency/percent formats
117
+ - `14-17, 27-31, 34-36, 50-58`: date formats (including localized)
118
+ - `22`: date+time format
119
+ - `18-21, 32-33, 45-47`: time formats
120
+ - `49`: text format
121
+
122
+ #### `convertNumFmtNameToId`
123
+
124
+ Convert number format name to format ID.
125
+
126
+ ```typescript
127
+ static convertNumFmtNameToId(numFmtName: ExcelNumberFormat): number;
128
+ ```
@@ -0,0 +1,100 @@
1
+ # ExcelWrapper
2
+
3
+ Zod schema-based Excel wrapper. Infers type information from schema to provide type-safe read/write.
4
+
5
+ ```typescript
6
+ import { ExcelWrapper } from "@simplysm/excel";
7
+ ```
8
+
9
+ ## Class: `ExcelWrapper<TSchema>`
10
+
11
+ ### Constructor
12
+
13
+ ```typescript
14
+ constructor(schema: TSchema)
15
+ ```
16
+
17
+ - `schema` -- Zod object schema. Defines the record structure. Use `.describe()` on fields to specify Excel header names.
18
+
19
+ ### `read`
20
+
21
+ Read Excel file into record array.
22
+
23
+ ```typescript
24
+ async read(
25
+ file: Bytes | Blob,
26
+ wsNameOrIndex?: string | number,
27
+ options?: { excludes?: (keyof z.infer<TSchema>)[] },
28
+ ): Promise<z.infer<TSchema>[]>;
29
+ ```
30
+
31
+ **Parameters:**
32
+ - `file` -- Excel file data (Uint8Array or Blob)
33
+ - `wsNameOrIndex` -- Worksheet name or index (default: `0`)
34
+ - `options.excludes` -- Field keys to exclude from reading
35
+
36
+ Values are automatically converted based on the Zod schema type:
37
+ - `ZodString` -- converts to string
38
+ - `ZodNumber` -- converts to number
39
+ - `ZodBoolean` -- converts to boolean (`"1"`, `"true"` -> `true`)
40
+ - `DateOnly`, `DateTime`, `Time` -- preserved as-is from Excel
41
+
42
+ Each row is validated against the Zod schema. Rows where all values are empty are skipped.
43
+
44
+ ### `write`
45
+
46
+ Record array to Excel workbook.
47
+
48
+ The caller is responsible for managing the returned workbook's resources. Use `await using` or call `close()` after use.
49
+
50
+ ```typescript
51
+ async write(
52
+ wsName: string,
53
+ records: Partial<z.infer<TSchema>>[],
54
+ options?: { excludes?: (keyof z.infer<TSchema>)[] },
55
+ ): Promise<ExcelWorkbook>;
56
+ ```
57
+
58
+ **Parameters:**
59
+ - `wsName` -- Worksheet name
60
+ - `records` -- Record array to write
61
+ - `options.excludes` -- Field keys to exclude from writing
62
+
63
+ **Behavior:**
64
+ - Headers are written in the first row using `.describe()` names (or field keys if no description)
65
+ - Data rows follow from row index 1
66
+ - All cells get border styling (`left`, `right`, `top`, `bottom`)
67
+ - Required field headers (non-optional, non-nullable, non-default, non-boolean) are highlighted in yellow (`00FFFF00`)
68
+ - Zoom is set to 85%
69
+ - First row is frozen
70
+
71
+ ## Example
72
+
73
+ ```typescript
74
+ import { z } from "zod";
75
+ import { ExcelWrapper } from "@simplysm/excel";
76
+
77
+ const schema = z.object({
78
+ name: z.string().describe("Name"),
79
+ age: z.number().describe("Age"),
80
+ email: z.string().optional().describe("Email"),
81
+ active: z.boolean().default(false).describe("Active"),
82
+ });
83
+
84
+ const wrapper = new ExcelWrapper(schema);
85
+
86
+ // Read Excel file
87
+ const records = await wrapper.read(fileBytes);
88
+ // records: { name: string; age: number; email?: string; active: boolean }[]
89
+
90
+ // Write to Excel
91
+ await using wb = await wrapper.write("Users", [
92
+ { name: "Alice", age: 30, email: "alice@example.com" },
93
+ { name: "Bob", age: 25 },
94
+ ]);
95
+ const bytes = await wb.toBytes();
96
+
97
+ // Exclude specific fields
98
+ const records2 = await wrapper.read(fileBytes, 0, { excludes: ["email"] });
99
+ await using wb2 = await wrapper.write("Users", records2, { excludes: ["email"] });
100
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/excel",
3
- "version": "13.0.98",
3
+ "version": "13.0.99",
4
4
  "description": "Excel file processing library",
5
5
  "author": "simplysm",
6
6
  "license": "Apache-2.0",
@@ -14,6 +14,7 @@
14
14
  "types": "./dist/index.d.ts",
15
15
  "files": [
16
16
  "dist",
17
+ "docs",
17
18
  "src",
18
19
  "tests"
19
20
  ],
@@ -21,6 +22,6 @@
21
22
  "dependencies": {
22
23
  "mime": "^4.1.0",
23
24
  "zod": "^4.3.6",
24
- "@simplysm/core-common": "13.0.98"
25
+ "@simplysm/core-common": "13.0.99"
25
26
  }
26
27
  }