@simplysm/excel 13.0.82 → 13.0.84
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 +371 -0
- package/package.json +3 -4
package/README.md
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# @simplysm/excel
|
|
2
|
+
|
|
3
|
+
Excel file (.xlsx) processing library for reading, writing, and manipulating workbooks. Supports both low-level cell operations and high-level schema-based data mapping via Zod.
|
|
4
|
+
|
|
5
|
+
Works in both Node.js and browser environments. Uses lazy-loading architecture for memory-efficient handling of large files.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @simplysm/excel
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Peer dependency:** `@simplysm/core-common`
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### Create and export a workbook
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { ExcelWorkbook } from "@simplysm/excel";
|
|
21
|
+
|
|
22
|
+
await using wb = new ExcelWorkbook();
|
|
23
|
+
const ws = await wb.addWorksheet("Sheet1");
|
|
24
|
+
|
|
25
|
+
await ws.cell(0, 0).setValue("Name");
|
|
26
|
+
await ws.cell(0, 1).setValue("Age");
|
|
27
|
+
await ws.cell(1, 0).setValue("Alice");
|
|
28
|
+
await ws.cell(1, 1).setValue(30);
|
|
29
|
+
|
|
30
|
+
const bytes = await wb.toBytes(); // Uint8Array
|
|
31
|
+
const blob = await wb.toBlob(); // Blob (for browser downloads)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Read an existing workbook
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { ExcelWorkbook } from "@simplysm/excel";
|
|
38
|
+
|
|
39
|
+
await using wb = new ExcelWorkbook(fileBytes); // Uint8Array or Blob
|
|
40
|
+
const ws = await wb.getWorksheet(0); // by index
|
|
41
|
+
// const ws = await wb.getWorksheet("Sheet1"); // or by name
|
|
42
|
+
|
|
43
|
+
const value = await ws.cell(0, 0).getValue(); // read cell value
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Schema-based read/write with ExcelWrapper
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { z } from "zod";
|
|
50
|
+
import { ExcelWrapper } from "@simplysm/excel";
|
|
51
|
+
|
|
52
|
+
const schema = z.object({
|
|
53
|
+
name: z.string().describe("Name"), // .describe() sets the Excel header
|
|
54
|
+
age: z.number().describe("Age"),
|
|
55
|
+
email: z.string().optional().describe("Email"),
|
|
56
|
+
active: z.boolean().default(false).describe("Active"),
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const wrapper = new ExcelWrapper(schema);
|
|
60
|
+
|
|
61
|
+
// Write records to Excel
|
|
62
|
+
await using wb = await wrapper.write("Users", [
|
|
63
|
+
{ name: "Alice", age: 30, email: "alice@example.com", active: true },
|
|
64
|
+
{ name: "Bob", age: 25 },
|
|
65
|
+
]);
|
|
66
|
+
const bytes = await wb.toBytes();
|
|
67
|
+
|
|
68
|
+
// Read records from Excel
|
|
69
|
+
const records = await wrapper.read(bytes, "Users");
|
|
70
|
+
// records[0] => { name: "Alice", age: 30, email: "alice@example.com", active: true }
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## API Reference
|
|
74
|
+
|
|
75
|
+
### ExcelWorkbook
|
|
76
|
+
|
|
77
|
+
Excel workbook processing class. Manages ZIP resources internally and uses lazy-loading for memory efficiency.
|
|
78
|
+
|
|
79
|
+
**Resource management:** Always release resources after use via `await using` (recommended) or `close()`.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// Recommended: automatic cleanup
|
|
83
|
+
await using wb = new ExcelWorkbook(bytes);
|
|
84
|
+
|
|
85
|
+
// Alternative: manual cleanup
|
|
86
|
+
const wb = new ExcelWorkbook(bytes);
|
|
87
|
+
try {
|
|
88
|
+
// ... operations
|
|
89
|
+
} finally {
|
|
90
|
+
await wb.close();
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### Constructor
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
new ExcelWorkbook() // create empty workbook
|
|
98
|
+
new ExcelWorkbook(bytes: Bytes) // open from Uint8Array
|
|
99
|
+
new ExcelWorkbook(blob: Blob) // open from Blob
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### Methods
|
|
103
|
+
|
|
104
|
+
| Method | Returns | Description |
|
|
105
|
+
|--------|---------|-------------|
|
|
106
|
+
| `getWorksheetNames()` | `Promise<string[]>` | Return all worksheet names |
|
|
107
|
+
| `getWorksheet(index: number)` | `Promise<ExcelWorksheet>` | Get worksheet by 0-based index |
|
|
108
|
+
| `getWorksheet(name: string)` | `Promise<ExcelWorksheet>` | Get worksheet by name |
|
|
109
|
+
| `addWorksheet(name: string)` | `Promise<ExcelWorksheet>` | Create a new worksheet |
|
|
110
|
+
| `toBytes()` | `Promise<Bytes>` | Export workbook as byte array |
|
|
111
|
+
| `toBlob()` | `Promise<Blob>` | Export workbook as Blob |
|
|
112
|
+
| `close()` | `Promise<void>` | Release resources (safe to call multiple times) |
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### ExcelWorksheet
|
|
117
|
+
|
|
118
|
+
Represents a worksheet. Provides cell access, row/column operations, data table processing, and image insertion.
|
|
119
|
+
|
|
120
|
+
#### Cell Access
|
|
121
|
+
|
|
122
|
+
| Method | Returns | Description |
|
|
123
|
+
|--------|---------|-------------|
|
|
124
|
+
| `cell(r, c)` | `ExcelCell` | Get cell at row `r`, column `c` (0-based) |
|
|
125
|
+
| `row(r)` | `ExcelRow` | Get row object (0-based) |
|
|
126
|
+
| `col(c)` | `ExcelCol` | Get column object (0-based) |
|
|
127
|
+
| `getCells()` | `Promise<ExcelCell[][]>` | Get all cells as a 2D array |
|
|
128
|
+
| `getRange()` | `Promise<ExcelAddressRangePoint>` | Get the data range of the worksheet |
|
|
129
|
+
|
|
130
|
+
#### Name
|
|
131
|
+
|
|
132
|
+
| Method | Returns | Description |
|
|
133
|
+
|--------|---------|-------------|
|
|
134
|
+
| `getName()` | `Promise<string>` | Get worksheet name |
|
|
135
|
+
| `setName(name)` | `Promise<void>` | Rename worksheet |
|
|
136
|
+
|
|
137
|
+
#### Data Operations
|
|
138
|
+
|
|
139
|
+
| Method | Returns | Description |
|
|
140
|
+
|--------|---------|-------------|
|
|
141
|
+
| `getDataTable(opt?)` | `Promise<Record<string, ExcelValueType>[]>` | Read data as record array (first row = headers) |
|
|
142
|
+
| `setDataMatrix(matrix)` | `Promise<void>` | Write 2D array data |
|
|
143
|
+
| `setRecords(records)` | `Promise<void>` | Write record array (auto-generates headers) |
|
|
144
|
+
|
|
145
|
+
**`getDataTable` options:**
|
|
146
|
+
|
|
147
|
+
| Option | Type | Description |
|
|
148
|
+
|--------|------|-------------|
|
|
149
|
+
| `headerRowIndex` | `number` | Header row index (default: first row of range) |
|
|
150
|
+
| `checkEndColIndex` | `number` | Column index to detect data end (stops when empty) |
|
|
151
|
+
| `usableHeaderNameFn` | `(name: string) => boolean` | Filter function for usable headers |
|
|
152
|
+
|
|
153
|
+
#### Copy Operations
|
|
154
|
+
|
|
155
|
+
| Method | Returns | Description |
|
|
156
|
+
|--------|---------|-------------|
|
|
157
|
+
| `copyRow(srcR, targetR)` | `Promise<void>` | Copy row (overwrite target) |
|
|
158
|
+
| `copyCell(srcAddr, targetAddr)` | `Promise<void>` | Copy cell |
|
|
159
|
+
| `copyRowStyle(srcR, targetR)` | `Promise<void>` | Copy row style only |
|
|
160
|
+
| `copyCellStyle(srcAddr, targetAddr)` | `Promise<void>` | Copy cell style only |
|
|
161
|
+
| `insertCopyRow(srcR, targetR)` | `Promise<void>` | Insert-copy row (shifts existing rows down) |
|
|
162
|
+
|
|
163
|
+
#### View Settings
|
|
164
|
+
|
|
165
|
+
| Method | Returns | Description |
|
|
166
|
+
|--------|---------|-------------|
|
|
167
|
+
| `setZoom(percent)` | `Promise<void>` | Set zoom scale |
|
|
168
|
+
| `freezeAt({ r?, c? })` | `Promise<void>` | Freeze panes at row/column |
|
|
169
|
+
|
|
170
|
+
#### Image
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
await ws.addImage({
|
|
174
|
+
bytes: imageBytes, // image binary data (Uint8Array)
|
|
175
|
+
ext: "png", // file extension
|
|
176
|
+
from: { r: 0, c: 0 }, // start position (0-based)
|
|
177
|
+
to: { r: 5, c: 3 }, // end position (optional)
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
| Parameter | Type | Description |
|
|
182
|
+
|-----------|------|-------------|
|
|
183
|
+
| `bytes` | `Bytes` | Image binary data |
|
|
184
|
+
| `ext` | `string` | Image extension (png, jpg, etc.) |
|
|
185
|
+
| `from` | `{ r, c, rOff?, cOff? }` | Start position. `rOff`/`cOff` are EMU offsets. |
|
|
186
|
+
| `to` | `{ r, c, rOff?, cOff? }` | End position. Defaults to one cell from `from`. |
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
### ExcelCell
|
|
191
|
+
|
|
192
|
+
Represents a single cell. All methods are async for lazy-loading efficiency.
|
|
193
|
+
|
|
194
|
+
#### Properties
|
|
195
|
+
|
|
196
|
+
| Property | Type | Description |
|
|
197
|
+
|----------|------|-------------|
|
|
198
|
+
| `addr` | `ExcelAddressPoint` | Cell address (`{ r, c }`, 0-based) |
|
|
199
|
+
|
|
200
|
+
#### Value
|
|
201
|
+
|
|
202
|
+
| Method | Returns | Description |
|
|
203
|
+
|--------|---------|-------------|
|
|
204
|
+
| `getValue()` | `Promise<ExcelValueType>` | Get cell value |
|
|
205
|
+
| `setValue(val)` | `Promise<void>` | Set cell value (`undefined` deletes the cell) |
|
|
206
|
+
| `getFormula()` | `Promise<string \| undefined>` | Get cell formula |
|
|
207
|
+
| `setFormula(val)` | `Promise<void>` | Set cell formula (`undefined` removes it) |
|
|
208
|
+
|
|
209
|
+
Supported value types (`ExcelValueType`): `string`, `number`, `boolean`, `DateOnly`, `DateTime`, `Time`, `undefined`
|
|
210
|
+
|
|
211
|
+
#### Style
|
|
212
|
+
|
|
213
|
+
| Method | Returns | Description |
|
|
214
|
+
|--------|---------|-------------|
|
|
215
|
+
| `setStyle(opts)` | `Promise<void>` | Set cell style |
|
|
216
|
+
| `getStyleId()` | `Promise<string \| undefined>` | Get raw style ID |
|
|
217
|
+
| `setStyleId(id)` | `Promise<void>` | Set raw style ID |
|
|
218
|
+
|
|
219
|
+
**Style options (`ExcelStyleOptions`):**
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
await cell.setStyle({
|
|
223
|
+
background: "00FF0000", // ARGB hex (8 digits)
|
|
224
|
+
border: ["left", "right", "top", "bottom"], // border positions
|
|
225
|
+
horizontalAlign: "center", // "left" | "center" | "right"
|
|
226
|
+
verticalAlign: "center", // "top" | "center" | "bottom"
|
|
227
|
+
numberFormat: "number", // "number" | "string" | "DateOnly" | "DateTime" | "Time"
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### Merge
|
|
232
|
+
|
|
233
|
+
| Method | Returns | Description |
|
|
234
|
+
|--------|---------|-------------|
|
|
235
|
+
| `merge(r, c)` | `Promise<void>` | Merge from this cell to end position `(r, c)` |
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
// Merge A1:C3 (3 rows x 3 columns)
|
|
239
|
+
await ws.cell(0, 0).merge(2, 2);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
### ExcelRow
|
|
245
|
+
|
|
246
|
+
Represents a worksheet row.
|
|
247
|
+
|
|
248
|
+
| Method | Returns | Description |
|
|
249
|
+
|--------|---------|-------------|
|
|
250
|
+
| `cell(c)` | `ExcelCell` | Get cell at column `c` (0-based) |
|
|
251
|
+
| `getCells()` | `Promise<ExcelCell[]>` | Get all cells in the row |
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
### ExcelCol
|
|
256
|
+
|
|
257
|
+
Represents a worksheet column.
|
|
258
|
+
|
|
259
|
+
| Method | Returns | Description |
|
|
260
|
+
|--------|---------|-------------|
|
|
261
|
+
| `cell(r)` | `ExcelCell` | Get cell at row `r` (0-based) |
|
|
262
|
+
| `getCells()` | `Promise<ExcelCell[]>` | Get all cells in the column |
|
|
263
|
+
| `setWidth(size)` | `Promise<void>` | Set column width |
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### ExcelWrapper\<TSchema\>
|
|
268
|
+
|
|
269
|
+
Zod schema-based Excel wrapper for type-safe read/write. Define a Zod object schema where each field's `.describe()` sets the Excel column header name.
|
|
270
|
+
|
|
271
|
+
#### Constructor
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
new ExcelWrapper(schema: z.ZodObject<z.ZodRawShape>)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
#### Methods
|
|
278
|
+
|
|
279
|
+
| Method | Returns | Description |
|
|
280
|
+
|--------|---------|-------------|
|
|
281
|
+
| `read(file, wsNameOrIndex?, options?)` | `Promise<z.infer<TSchema>[]>` | Read Excel file into typed record array |
|
|
282
|
+
| `write(wsName, records, options?)` | `Promise<ExcelWorkbook>` | Write records to a new workbook |
|
|
283
|
+
|
|
284
|
+
**`read` parameters:**
|
|
285
|
+
|
|
286
|
+
| Parameter | Type | Default | Description |
|
|
287
|
+
|-----------|------|---------|-------------|
|
|
288
|
+
| `file` | `Bytes \| Blob` | | Excel file data |
|
|
289
|
+
| `wsNameOrIndex` | `string \| number` | `0` | Worksheet name or index |
|
|
290
|
+
| `options.excludes` | `(keyof T)[]` | | Fields to exclude from reading |
|
|
291
|
+
|
|
292
|
+
**`write` parameters:**
|
|
293
|
+
|
|
294
|
+
| Parameter | Type | Description |
|
|
295
|
+
|-----------|------|-------------|
|
|
296
|
+
| `wsName` | `string` | Worksheet name |
|
|
297
|
+
| `records` | `Partial<T>[]` | Record array to write |
|
|
298
|
+
| `options.excludes` | `(keyof T)[]` | Fields to exclude from columns |
|
|
299
|
+
|
|
300
|
+
**Write behavior:**
|
|
301
|
+
- Generates headers from schema field descriptions
|
|
302
|
+
- Applies border style to all data cells
|
|
303
|
+
- Highlights required field headers with yellow background
|
|
304
|
+
- Sets zoom to 85% and freezes the header row
|
|
305
|
+
|
|
306
|
+
**Supported Zod types:** `z.string()`, `z.number()`, `z.boolean()`, `z.instanceof(DateOnly)`, `z.instanceof(DateTime)`, `z.instanceof(Time)`. Supports `z.optional()`, `z.nullable()`, `z.default()` wrappers.
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### ExcelUtils
|
|
311
|
+
|
|
312
|
+
Static utility class for Excel address conversion and date/number processing.
|
|
313
|
+
|
|
314
|
+
#### Address Conversion
|
|
315
|
+
|
|
316
|
+
| Method | Returns | Description |
|
|
317
|
+
|--------|---------|-------------|
|
|
318
|
+
| `stringifyAddr({ r, c })` | `string` | Coordinates to "A1" format |
|
|
319
|
+
| `stringifyRowAddr(r)` | `string` | Row index to string (0 -> "1") |
|
|
320
|
+
| `stringifyColAddr(c)` | `string` | Column index to string (0 -> "A", 26 -> "AA") |
|
|
321
|
+
| `parseCellAddr(addr)` | `ExcelAddressPoint` | "B3" -> `{ r: 2, c: 1 }` |
|
|
322
|
+
| `parseRowAddr(addr)` | `number` | Extract row index from address |
|
|
323
|
+
| `parseColAddr(addr)` | `number` | Extract column index from address |
|
|
324
|
+
| `parseRangeAddr(rangeAddr)` | `ExcelAddressRangePoint` | "A1:C3" -> `{ s: {r:0,c:0}, e: {r:2,c:2} }` |
|
|
325
|
+
| `stringifyRangeAddr(point)` | `string` | Range coordinates to "A1:C3" format |
|
|
326
|
+
|
|
327
|
+
#### Date/Number Conversion
|
|
328
|
+
|
|
329
|
+
| Method | Returns | Description |
|
|
330
|
+
|--------|---------|-------------|
|
|
331
|
+
| `convertTimeTickToNumber(tick)` | `number` | JS timestamp (ms) to Excel date number |
|
|
332
|
+
| `convertNumberToTimeTick(value)` | `number` | Excel date number to JS timestamp (ms) |
|
|
333
|
+
|
|
334
|
+
#### Number Format
|
|
335
|
+
|
|
336
|
+
| Method | Returns | Description |
|
|
337
|
+
|--------|---------|-------------|
|
|
338
|
+
| `convertNumFmtIdToName(id)` | `ExcelNumberFormat` | Built-in format ID to name |
|
|
339
|
+
| `convertNumFmtCodeToName(code)` | `ExcelNumberFormat` | Format code string to name |
|
|
340
|
+
| `convertNumFmtNameToId(name)` | `number` | Format name to built-in ID |
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
### Types
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
/** Supported cell value types */
|
|
348
|
+
type ExcelValueType = number | string | DateOnly | DateTime | Time | boolean | undefined;
|
|
349
|
+
|
|
350
|
+
/** Number format names */
|
|
351
|
+
type ExcelNumberFormat = "number" | "string" | "DateOnly" | "DateTime" | "Time";
|
|
352
|
+
|
|
353
|
+
/** Cell address (0-based) */
|
|
354
|
+
interface ExcelAddressPoint { r: number; c: number; }
|
|
355
|
+
|
|
356
|
+
/** Range address (0-based) */
|
|
357
|
+
interface ExcelAddressRangePoint { s: ExcelAddressPoint; e: ExcelAddressPoint; }
|
|
358
|
+
|
|
359
|
+
/** Cell style options */
|
|
360
|
+
interface ExcelStyleOptions {
|
|
361
|
+
background?: string; // ARGB hex (e.g. "00FF0000")
|
|
362
|
+
border?: ExcelBorderPosition[]; // "left" | "right" | "top" | "bottom"
|
|
363
|
+
horizontalAlign?: ExcelHorizontalAlign; // "left" | "center" | "right"
|
|
364
|
+
verticalAlign?: ExcelVerticalAlign; // "top" | "center" | "bottom"
|
|
365
|
+
numberFormat?: ExcelNumberFormat;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
type ExcelBorderPosition = "left" | "right" | "top" | "bottom";
|
|
369
|
+
type ExcelHorizontalAlign = "center" | "left" | "right";
|
|
370
|
+
type ExcelVerticalAlign = "center" | "top" | "bottom";
|
|
371
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/excel",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.84",
|
|
4
4
|
"description": "Excel file processing library",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -15,13 +15,12 @@
|
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
17
|
"src",
|
|
18
|
-
"tests"
|
|
19
|
-
"docs"
|
|
18
|
+
"tests"
|
|
20
19
|
],
|
|
21
20
|
"sideEffects": false,
|
|
22
21
|
"dependencies": {
|
|
23
22
|
"mime": "^4.1.0",
|
|
24
23
|
"zod": "^4.3.6",
|
|
25
|
-
"@simplysm/core-common": "13.0.
|
|
24
|
+
"@simplysm/core-common": "13.0.84"
|
|
26
25
|
}
|
|
27
26
|
}
|