@justybase/spreadsheet-tasks 2.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +74 -0
- package/README.md +20 -2
- package/browser/browser-spreadsheet.js +131 -43
- package/browser/justybase-spreadsheet.min.js +13 -13
- package/dist/cjs/index.d.ts +167 -7
- package/dist/cjs/index.js +2420 -685
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +2404 -685
- package/dist/esm/index.js.map +1 -1
- package/docs/API.md +98 -3
- package/package.json +4 -3
package/docs/API.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
- [XlsbReader](#xlsbreader)
|
|
8
8
|
- [XlsxReader](#xlsxreader)
|
|
9
9
|
- [XlsxUpdater](#xlsxupdater)
|
|
10
|
+
- [XlsmUpdater](#xlsmupdater)
|
|
10
11
|
- [XlsbUpdater](#xlsbupdater)
|
|
11
12
|
- [Excel conversion](#excel-conversion)
|
|
12
13
|
- [ReaderFactory](#readerfactory)
|
|
@@ -61,7 +62,10 @@ Writes data to the current sheet.
|
|
|
61
62
|
- `string` - Written as shared string
|
|
62
63
|
- `number` - Written as number (integer or double)
|
|
63
64
|
- `boolean` - Written as boolean
|
|
64
|
-
- `Date` - Written as Excel date serial number
|
|
65
|
+
- `Date` - Written as Excel date serial number. The serial is taken from the UTC
|
|
66
|
+
time (`getTime()`), not local wall-clock time: `new Date(2024, 5, 30)` in UTC+2
|
|
67
|
+
is stored as 2024-06-29 22:00 and shows that way in Excel. Use `Date.UTC(...)`
|
|
68
|
+
for date-only values
|
|
65
69
|
- `null` / `undefined` - Written as empty cell
|
|
66
70
|
|
|
67
71
|
**Example:**
|
|
@@ -160,6 +164,12 @@ console.log(sheets); // ['Sheet1', 'Sheet2']
|
|
|
160
164
|
Reads the next row. Returns `true` if a row was read, `false` if end of sheet reached.
|
|
161
165
|
Always use `await` (both XLSB and XLSX are async in v2+).
|
|
162
166
|
|
|
167
|
+
Empty rows: gaps in the sheet (missing `<row>` / `BrtRowHdr`, including leading
|
|
168
|
+
gaps) are returned as empty rows (`[]`, `getValue()` → `null`). Like xlspy,
|
|
169
|
+
gap positions are yielded; unlike xlspy's padded `[None] * cols`, this reader
|
|
170
|
+
yields a zero-length row so callers must not assume `fieldCount` width.
|
|
171
|
+
The 1904 date system (`workbookPr date1904` / `BrtWbProp`) is honoured.
|
|
172
|
+
|
|
163
173
|
**Example:**
|
|
164
174
|
```typescript
|
|
165
175
|
while (await reader.read()) {
|
|
@@ -167,6 +177,27 @@ while (await reader.read()) {
|
|
|
167
177
|
}
|
|
168
178
|
```
|
|
169
179
|
|
|
180
|
+
#### `selectSheet(nameOrIndex: string | number): Promise<void>`
|
|
181
|
+
|
|
182
|
+
Selects a worksheet for subsequent `read()` calls. Resets row/EOF and `fieldCount`.
|
|
183
|
+
Default is sheet 0.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
await reader.selectSheet('Second');
|
|
187
|
+
await reader.selectSheet(0);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### `nextResult(): Promise<boolean>`
|
|
191
|
+
|
|
192
|
+
Advances to the next worksheet. Returns `true` if another sheet was selected,
|
|
193
|
+
`false` at the end.
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
do {
|
|
197
|
+
while (await reader.read()) { /* rows */ }
|
|
198
|
+
} while (await reader.nextResult());
|
|
199
|
+
```
|
|
200
|
+
|
|
170
201
|
#### `getValue(columnIndex: number): CellValue`
|
|
171
202
|
|
|
172
203
|
Gets value at the specified column index in the current row.
|
|
@@ -176,6 +207,9 @@ Gets value at the specified column index in the current row.
|
|
|
176
207
|
|
|
177
208
|
**Returns:** `CellValue` (string, number, boolean, Date, bigint, or null/undefined)
|
|
178
209
|
|
|
210
|
+
Date cells are returned as `Date` objects built from the serial in UTC, the same
|
|
211
|
+
convention the writers use, so a write/read round trip keeps the same instant.
|
|
212
|
+
|
|
179
213
|
**Example:**
|
|
180
214
|
```typescript
|
|
181
215
|
while (await reader.read()) {
|
|
@@ -220,6 +254,16 @@ Returns array of worksheet names.
|
|
|
220
254
|
#### `read(): Promise<boolean>`
|
|
221
255
|
|
|
222
256
|
Reads the next row. Returns `true` if a row was read. Always use `await`.
|
|
257
|
+
Empty gap rows (including leading) are returned as empty rows; see
|
|
258
|
+
[XlsbReader](#xlsbreader) for `selectSheet`/`nextResult`, which behave identically.
|
|
259
|
+
|
|
260
|
+
#### `selectSheet(nameOrIndex: string | number): Promise<void>`
|
|
261
|
+
|
|
262
|
+
See [XlsbReader](#xlsbreader).
|
|
263
|
+
|
|
264
|
+
#### `nextResult(): Promise<boolean>`
|
|
265
|
+
|
|
266
|
+
See [XlsbReader](#xlsbreader).
|
|
223
267
|
|
|
224
268
|
#### `getValue(columnIndex: number): CellValue`
|
|
225
269
|
|
|
@@ -244,8 +288,9 @@ new XlsxUpdater(filePath: string)
|
|
|
244
288
|
**Parameters:**
|
|
245
289
|
- `filePath` - Path to an existing `.xlsx` file
|
|
246
290
|
|
|
247
|
-
Throws if the file does not exist, is not a valid XLSX, or is an XLSB
|
|
248
|
-
|
|
291
|
+
Throws if the file does not exist, is not a valid XLSX package, or is an XLSB.
|
|
292
|
+
Macro-enabled `.xlsm` packages can use the explicit [XlsmUpdater](#xlsmupdater)
|
|
293
|
+
alias; unknown VBA members are preserved.
|
|
249
294
|
|
|
250
295
|
**Example:**
|
|
251
296
|
```typescript
|
|
@@ -286,6 +331,12 @@ Clears the entire cell data of the target sheet and writes new rows in its place
|
|
|
286
331
|
- Pivot tables whose `worksheetSource` references the updated sheet get their
|
|
287
332
|
`ref` and `recordCount` adjusted, and `refreshOnLoad="1"` is added to the
|
|
288
333
|
pivot table definitions so Excel refreshes them on open.
|
|
334
|
+
- The stale calculation chain (`xl/calcChain.xml`) is removed with its
|
|
335
|
+
`Content_Types`/rels entries; Excel rebuilds it on open.
|
|
336
|
+
- ListObject tables (`xl/tables/*.xml`) anchored at `A1` get their `<table>`
|
|
337
|
+
and `<autoFilter>` `ref` updated to the new dimension. Tables whose column
|
|
338
|
+
count changes are left untouched (their `tableColumns` would need rebuilding),
|
|
339
|
+
and ranges are capped so they never overlap another table.
|
|
289
340
|
|
|
290
341
|
**Example:**
|
|
291
342
|
```typescript
|
|
@@ -299,10 +350,28 @@ updater.save('report_new.xlsx');
|
|
|
299
350
|
Writes the updated workbook to disk. When `outputPath` is omitted, the source
|
|
300
351
|
file is overwritten in place.
|
|
301
352
|
|
|
353
|
+
#### `replaceSheetDataStream(sheetName: string, rows: RowSource, options?: ReplaceSheetDataOptions): Promise<void>`
|
|
354
|
+
|
|
355
|
+
Replaces worksheet rows from a synchronous or asynchronous one-pass row source.
|
|
356
|
+
The row source is processed incrementally and is not collected into a complete
|
|
357
|
+
2D array. Use `saveStreaming()` to also avoid materialising the final ZIP buffer.
|
|
358
|
+
|
|
359
|
+
#### `saveStreaming(outputPath?: string): Promise<void>`
|
|
360
|
+
|
|
361
|
+
Writes the updated package through a temporary file and installs it atomically.
|
|
362
|
+
Staged worksheet parts are streamed; `save()` remains the simpler synchronous
|
|
363
|
+
buffering path.
|
|
364
|
+
|
|
302
365
|
#### `toBuffer(): Buffer`
|
|
303
366
|
|
|
304
367
|
Returns the updated workbook as an in-memory ZIP buffer.
|
|
305
368
|
|
|
369
|
+
## XlsmUpdater
|
|
370
|
+
|
|
371
|
+
`XlsmUpdater` is an explicit alias of `XlsxUpdater` for macro-enabled `.xlsm`
|
|
372
|
+
packages. It has the same API as `XlsxUpdater` and preserves VBA parts without
|
|
373
|
+
parsing or modifying them.
|
|
374
|
+
|
|
306
375
|
---
|
|
307
376
|
|
|
308
377
|
## XlsbUpdater
|
|
@@ -364,6 +433,10 @@ Clears the entire cell data of the target sheet and writes new rows in its place
|
|
|
364
433
|
- Pivot caches whose `worksheetSource` references the updated sheet get their
|
|
365
434
|
range and record count adjusted, and the `refreshOnLoad` flag is set so Excel
|
|
366
435
|
refreshes them on open.
|
|
436
|
+
- The stale calculation chain (`xl/calcChain.bin`) is removed with its
|
|
437
|
+
`Content_Types`/rels entries.
|
|
438
|
+
- XLSB ListObject tables are **not** patched (documented limitation); only the
|
|
439
|
+
sheet dimension (`BrtWsDim`) and pivot caches are updated.
|
|
367
440
|
|
|
368
441
|
**Example:**
|
|
369
442
|
```typescript
|
|
@@ -458,6 +531,18 @@ await reader.open('data.xlsb');
|
|
|
458
531
|
|
|
459
532
|
## Types
|
|
460
533
|
|
|
534
|
+
### Excel limits (throw, xlspy parity)
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
import { MAX_ROWS, MAX_COLS, MAX_CELL_CHARS } from '@justybase/spreadsheet-tasks';
|
|
538
|
+
// MAX_ROWS = 1_048_576, MAX_COLS = 16_384, MAX_CELL_CHARS = 32_767 UTF-16 units
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
Writers throw when a limit is exceeded (no truncation, workbook not published).
|
|
542
|
+
`writeSheet` also throws when a row/header is longer than `columnCount`, matching
|
|
543
|
+
streaming `writeRow` behaviour. Astral characters count as 2 units
|
|
544
|
+
(`'😀'.length === 2`).
|
|
545
|
+
|
|
461
546
|
### Supported Cell Types
|
|
462
547
|
|
|
463
548
|
| TypeScript Type | Excel Cell Type |
|
|
@@ -469,6 +554,16 @@ await reader.open('data.xlsb');
|
|
|
469
554
|
| `Date` | Date Serial Number |
|
|
470
555
|
| `null` / `undefined` | Empty Cell |
|
|
471
556
|
|
|
557
|
+
### `RowSource`
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
type RowSource =
|
|
561
|
+
| Iterable<ReadonlyArray<CellValue>>
|
|
562
|
+
| AsyncIterable<ReadonlyArray<CellValue>>;
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
Used by `replaceSheetDataStream()` in both updater classes.
|
|
566
|
+
|
|
472
567
|
### Sheet Name Restrictions
|
|
473
568
|
|
|
474
569
|
Sheet names have the following restrictions:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justybase/spreadsheet-tasks",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "High-performance TypeScript library for reading and writing Excel files in XLSB and XLSX formats. XLSB is 3.3x faster to write and 2.3x faster to read than XLSX.",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"build": "tsup && node -e \"require('fs').copyFileSync('dist-esm-package.json','dist/esm/package.json')\"",
|
|
27
27
|
"build:browser": "esbuild src/browser/download.ts --bundle --minify --format=iife --global-name=JustybaseSpreadsheet --outfile=browser/justybase-spreadsheet.min.js && esbuild src/browser/download.ts --bundle --format=esm --outfile=browser/browser-spreadsheet.js",
|
|
28
28
|
"lint": "eslint src/",
|
|
29
|
-
"typecheck": "tsc --noEmit",
|
|
29
|
+
"typecheck": "tsc --noEmit && tsc -p tsconfig.browser.json",
|
|
30
30
|
"test": "npm run typecheck && npm run test:smoke && npm run test:unit && npm run test:integration && npm run test:dist",
|
|
31
31
|
"test:smoke": "npx ts-node tests/smoke.test.ts",
|
|
32
|
-
"test:unit": "npx ts-node tests/unit/bigbuffer.test.ts && npx ts-node tests/unit/biff-reader-writer.test.ts && npx ts-node tests/unit/xlsb-writer.test.ts && npx ts-node tests/unit/excel-converter.test.ts",
|
|
32
|
+
"test:unit": "npx ts-node tests/unit/bigbuffer.test.ts && npx ts-node tests/unit/biff-reader-writer.test.ts && npx ts-node tests/unit/xlsb-writer.test.ts && npx ts-node tests/unit/excel-converter.test.ts && npx ts-node tests/unit/updater-streaming.test.ts && npx ts-node tests/unit/xlsx-reader-cell-refs.test.ts && npx ts-node tests/unit/writer-limits-columns.test.ts && npx ts-node tests/unit/reader-xml-fixes.test.ts && npx ts-node tests/unit/xlsb-sst-dim.test.ts && npx ts-node tests/unit/updater-cleanup.test.ts && npx ts-node tests/unit/oa-1900-leap.test.ts && npx ts-node tests/unit/reader-row-limit.test.ts",
|
|
33
33
|
"test:integration": "npx ts-node tests/integration/xlsb-writer.test.ts && npx ts-node tests/integration/xlsx-writer.test.ts && npx ts-node tests/integration/xlsx-updater.test.ts && npx ts-node tests/integration/xlsb-updater.test.ts",
|
|
34
34
|
"test:dist": "npm run build && npx ts-node tests/dist-surface.test.ts",
|
|
35
35
|
"test:excel-conversion": "npm run build && npx ts-node tests/excel-compat/conversion.ts",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"benchmark": "npm run build && npx ts-node benchmarks/performance.bench.ts",
|
|
39
39
|
"benchmark:comparison": "npm run build && npx ts-node benchmarks/comparison.bench.ts",
|
|
40
40
|
"test:excel-compat": "npm run build && npx tsx tests/excel-compat/run.ts",
|
|
41
|
+
"test:cross": "npx ts-node tests/cross/xlspy-cross.test.ts",
|
|
41
42
|
"prepublishOnly": "npm run build && npm run build:browser && npm test"
|
|
42
43
|
},
|
|
43
44
|
"keywords": [
|