@justybase/spreadsheet-tasks 1.3.3 → 2.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.
- package/CHANGELOG.md +63 -0
- package/README.md +151 -54
- package/browser/browser-spreadsheet.js +3044 -0
- package/browser/justybase-spreadsheet.min.js +36 -0
- package/dist/cjs/index.d.ts +559 -0
- package/dist/cjs/index.js +4971 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.js +4914 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/docs/API.md +166 -9
- package/docs/PACKAGING.md +32 -0
- package/docs/PUBLISHING.md +8 -1
- package/examples/basic-read.ts +2 -2
- package/examples/basic-write.ts +1 -1
- package/examples/datetime-widths.ts +1 -1
- package/examples/formats-verify.ts +1 -2
- package/examples/large-dataset.ts +2 -2
- package/examples/multiple-sheets.ts +1 -1
- package/examples/streaming-example.ts +3 -1
- package/examples/update-existing.ts +53 -0
- package/package.json +29 -14
- package/dist/BiffReaderWriter.d.ts +0 -44
- package/dist/BiffReaderWriter.d.ts.map +0 -1
- package/dist/BiffReaderWriter.js +0 -282
- package/dist/BiffReaderWriter.js.map +0 -1
- package/dist/BigBuffer.d.ts +0 -24
- package/dist/BigBuffer.d.ts.map +0 -1
- package/dist/BigBuffer.js +0 -120
- package/dist/BigBuffer.js.map +0 -1
- package/dist/ExcelReaderAbstract.d.ts +0 -17
- package/dist/ExcelReaderAbstract.d.ts.map +0 -1
- package/dist/ExcelReaderAbstract.js +0 -25
- package/dist/ExcelReaderAbstract.js.map +0 -1
- package/dist/Formats.d.ts +0 -34
- package/dist/Formats.d.ts.map +0 -1
- package/dist/Formats.js +0 -48
- package/dist/Formats.js.map +0 -1
- package/dist/ReaderFactory.d.ts +0 -6
- package/dist/ReaderFactory.d.ts.map +0 -1
- package/dist/ReaderFactory.js +0 -56
- package/dist/ReaderFactory.js.map +0 -1
- package/dist/XlsbReader.d.ts +0 -24
- package/dist/XlsbReader.d.ts.map +0 -1
- package/dist/XlsbReader.js +0 -186
- package/dist/XlsbReader.js.map +0 -1
- package/dist/XlsbWriter.d.ts +0 -80
- package/dist/XlsbWriter.d.ts.map +0 -1
- package/dist/XlsbWriter.js +0 -964
- package/dist/XlsbWriter.js.map +0 -1
- package/dist/XlsxReader.d.ts +0 -30
- package/dist/XlsxReader.d.ts.map +0 -1
- package/dist/XlsxReader.js +0 -341
- package/dist/XlsxReader.js.map +0 -1
- package/dist/XlsxWriter.d.ts +0 -51
- package/dist/XlsxWriter.d.ts.map +0 -1
- package/dist/XlsxWriter.js +0 -632
- package/dist/XlsxWriter.js.map +0 -1
- package/dist/index.d.ts +0 -10
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -29
- package/dist/index.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.1.0] - 2026-08-07
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `XlsxUpdater` and `XlsbUpdater` — replace the data of a worksheet inside an
|
|
13
|
+
existing `.xlsx` / `.xlsb` file without rebuilding the workbook. Pivot tables,
|
|
14
|
+
other sheets, styles and defined names are preserved; shared strings are
|
|
15
|
+
appended (never reordered), column styles are inherited, and pivot cache
|
|
16
|
+
ranges + `refreshOnLoad` are updated automatically.
|
|
17
|
+
- Shared helpers: `xmlUtils.ts` (XML escaping, column letters, shared strings
|
|
18
|
+
parsing) and `biff12Utils.ts` (BIFF12 record helpers for XLSB).
|
|
19
|
+
- `examples/update-existing.ts` — end-to-end example for refreshing a data
|
|
20
|
+
sheet in an existing XLSX / XLSB report.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- `XlsbUpdater` pivot source range was one row too long when `headers` were not
|
|
25
|
+
provided, causing an empty trailing row (and a "(blank)" item in pivot
|
|
26
|
+
tables). The range now ends exactly at the last data row.
|
|
27
|
+
- Both updaters now trim trailing rows that contain only empty cells (padding
|
|
28
|
+
rows from SQL exports), so they don't appear as "(blank)" in pivot tables.
|
|
29
|
+
- `XlsbUpdater` no longer removes the worksheet's row-block terminator records
|
|
30
|
+
(0x92/0x217/0x1dd/0x1dc) and keeps the sheet dimension record (0x98) in sync
|
|
31
|
+
with the new row count — without these, Excel hid the last written row.
|
|
32
|
+
|
|
33
|
+
## [2.0.0] - 2026-07-25
|
|
34
|
+
|
|
35
|
+
### Breaking
|
|
36
|
+
|
|
37
|
+
- `XlsbReader.read()` is now `async` and returns `Promise<boolean>` (same as `XlsxReader`).
|
|
38
|
+
Update loops from `while (reader.read())` to `while (await reader.read())`.
|
|
39
|
+
- Package entry points moved under `dist/cjs` and `dist/esm` with an `exports` map.
|
|
40
|
+
Most consumers of `@justybase/spreadsheet-tasks` need no import path changes.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- `CellValue` / `PrimitiveCellValue` types for writer and reader cell APIs
|
|
45
|
+
- Shared writer helpers: `sanitizeSheetName`, column-width helpers, `StreamingSheetState`
|
|
46
|
+
- Dual package build (CJS + ESM) via `tsup`
|
|
47
|
+
- Browser sources under `src/browser/` with `npm run build:browser`
|
|
48
|
+
- `docs/PACKAGING.md` (ZIP library rationale + dual package notes)
|
|
49
|
+
- Dist surface smoke test (`npm run test:dist`)
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- `XlsbWriter` / `XlsxWriter` share sanitization, autofit, and streaming state helpers
|
|
54
|
+
- Tests import from `src/` (published surface still verified via `test:dist`)
|
|
55
|
+
- ZIP type definitions use `@types/*` only (hand-written ambient modules removed)
|
|
56
|
+
|
|
57
|
+
### Browser
|
|
58
|
+
|
|
59
|
+
- Source of truth is TypeScript in `src/browser/`; `browser/*.js` writer sources are generated bundles
|
|
60
|
+
|
|
61
|
+
## [1.3.2] - previous
|
|
62
|
+
|
|
63
|
+
See git history for 1.x changes.
|
package/README.md
CHANGED
|
@@ -1,72 +1,112 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @justybase/spreadsheet-tasks
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
High-performance TypeScript library for reading and writing Excel files in XLSB and XLSX formats.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@justybase/spreadsheet-tasks)
|
|
6
|
+
[](https://github.com/justybase/justybase_spreadsheet_tasks/actions/workflows/ci.yml)
|
|
6
7
|
[](https://opensource.org/licenses/MIT)
|
|
7
8
|
|
|
8
|
-
##
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Features](#features)
|
|
12
|
+
- [Benchmark Results](#benchmark-results)
|
|
13
|
+
- [Requirements](#requirements)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Browser Support](#browser-support)
|
|
16
|
+
- [Quick Start](#quick-start)
|
|
17
|
+
- [API Documentation](#api-documentation)
|
|
18
|
+
- [Examples](#examples)
|
|
19
|
+
- [When to Use XLSB vs XLSX](#when-to-use-xlsb-vs-xlsx)
|
|
20
|
+
- [Contributing](#contributing)
|
|
21
|
+
- [License](#license)
|
|
22
|
+
- [Acknowledgments](#acknowledgments)
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- **High Performance** — XLSB is about 3.3× faster to write and 2.3× faster to read than XLSX (see [benchmarks](#benchmark-results))
|
|
27
|
+
- **Small File Size** — XLSB files are ~47% smaller than equivalent XLSX files
|
|
28
|
+
- **TypeScript First** — Full TypeScript support with type definitions
|
|
29
|
+
- **Dual Format Support** — Read and write both XLSB and XLSX formats
|
|
30
|
+
- **Lightweight Node Dependencies** — Small ZIP-focused runtime deps (`adm-zip`, `archiver`, `yauzl`); no heavy Excel framework
|
|
31
|
+
- **Streaming Support** — Efficient memory usage for large files
|
|
32
|
+
- **Multiple Sheets** — Support for multiple worksheets per workbook
|
|
33
|
+
- **Auto-filter** — Automatic filter headers support
|
|
34
|
+
- **In-place Updates** — Replace the data of a worksheet inside an existing XLSX or XLSB (e.g. `report.xlsx` / `report.xlsb`) while keeping pivot tables, other sheets and formatting untouched
|
|
35
|
+
|
|
36
|
+
## Benchmark Results
|
|
37
|
+
|
|
38
|
+
Measured with `npm run benchmark` (50K rows). Your results may vary by hardware and dataset.
|
|
20
39
|
|
|
21
40
|
| Operation | XLSB | XLSX | Performance Gain |
|
|
22
41
|
|-----------|------|------|------------------|
|
|
23
|
-
| Write (50K rows) | 140 ms | 467 ms | **3.
|
|
24
|
-
| Read (50K rows) | 118 ms | 276 ms | **2.
|
|
42
|
+
| Write (50K rows) | 140 ms | 467 ms | **3.3× faster** |
|
|
43
|
+
| Read (50K rows) | 118 ms | 276 ms | **2.3× faster** |
|
|
25
44
|
| File Size | 1.49 MB | 2.83 MB | **47% smaller** |
|
|
26
45
|
|
|
27
|
-
##
|
|
46
|
+
## Requirements
|
|
47
|
+
|
|
48
|
+
- **Node.js** 16 or newer ([`engines`](./package.json) in `package.json`)
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
28
51
|
|
|
29
52
|
```bash
|
|
30
53
|
npm install @justybase/spreadsheet-tasks
|
|
31
54
|
```
|
|
32
55
|
|
|
33
|
-
|
|
56
|
+
CommonJS:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
const { XlsbWriter } = require('@justybase/spreadsheet-tasks');
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
ES modules:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
import { XlsbWriter } from '@justybase/spreadsheet-tasks';
|
|
66
|
+
```
|
|
34
67
|
|
|
35
|
-
|
|
68
|
+
## Browser Support
|
|
36
69
|
|
|
37
|
-
|
|
70
|
+
Browser writers live in TypeScript under `src/browser/` and are bundled with:
|
|
38
71
|
|
|
39
72
|
```bash
|
|
40
|
-
|
|
73
|
+
npm run build:browser
|
|
41
74
|
```
|
|
42
75
|
|
|
43
|
-
|
|
76
|
+
This produces:
|
|
77
|
+
|
|
78
|
+
- `browser/justybase-spreadsheet.min.js` — IIFE (`JustybaseSpreadsheet` global)
|
|
79
|
+
- `browser/browser-spreadsheet.js` — ESM for local demos (`demo.html`, `test.html`)
|
|
80
|
+
|
|
81
|
+
The browser bundle has **no runtime npm dependencies** (ZIP logic is inlined).
|
|
44
82
|
|
|
45
83
|
```html
|
|
46
84
|
<script type="module">
|
|
47
|
-
import { downloadXlsb, downloadXlsx } from '
|
|
48
|
-
|
|
49
|
-
const headers = [
|
|
85
|
+
import { downloadXlsb, downloadXlsx, F } from './browser-spreadsheet.js';
|
|
86
|
+
|
|
87
|
+
const headers = ['ID', 'Name', 'Score'];
|
|
50
88
|
const rows = [
|
|
51
|
-
[1,
|
|
52
|
-
[2,
|
|
89
|
+
[1, 'Alice', 99.5],
|
|
90
|
+
[2, 'Bob', 88.0],
|
|
53
91
|
];
|
|
54
|
-
|
|
55
|
-
// Generates the file and triggers the browser download automatically
|
|
92
|
+
|
|
56
93
|
document.getElementById('downloadBtn').addEventListener('click', () => {
|
|
57
|
-
downloadXlsb('report.xlsb', rows, headers
|
|
94
|
+
downloadXlsb('report.xlsb', rows, headers);
|
|
58
95
|
});
|
|
59
96
|
</script>
|
|
60
97
|
```
|
|
61
98
|
|
|
62
99
|
**Features included in the browser build:**
|
|
63
|
-
|
|
100
|
+
|
|
101
|
+
- Built-in ZIP archiving (no external libraries in the bundle)
|
|
64
102
|
- Memory-efficient `Uint8Array` buffer handling
|
|
65
103
|
- Auto-fitted column widths
|
|
66
104
|
- Frozen and styled headers (styles: `bold`, `fill`, `bold+fill`)
|
|
67
105
|
- Auto-filters enabled by default
|
|
68
106
|
|
|
69
|
-
|
|
107
|
+
See [CHANGELOG.md](./CHANGELOG.md) for v2 breaking changes (`await reader.read()`).
|
|
108
|
+
|
|
109
|
+
## Quick Start
|
|
70
110
|
|
|
71
111
|
### Writing Excel Files
|
|
72
112
|
|
|
@@ -131,13 +171,13 @@ await writer.finalize();
|
|
|
131
171
|
```
|
|
132
172
|
|
|
133
173
|
**Benefits of Streaming API:**
|
|
134
|
-
- ✅ Constant memory usage regardless of dataset size
|
|
135
|
-
- ✅ Write millions of rows without loading all data into RAM
|
|
136
|
-
- ✅ Generate data on-the-fly from databases, APIs, or other sources
|
|
137
|
-
- ✅ Same performance as batch mode
|
|
138
174
|
|
|
139
|
-
|
|
175
|
+
- Constant memory usage regardless of dataset size
|
|
176
|
+
- Write millions of rows without loading all data into RAM
|
|
177
|
+
- Generate data on-the-fly from databases, APIs, or other sources
|
|
178
|
+
- Same performance as batch mode
|
|
140
179
|
|
|
180
|
+
### Reading Excel Files
|
|
141
181
|
|
|
142
182
|
```typescript
|
|
143
183
|
import { XlsbReader, XlsxReader, ReaderFactory } from '@justybase/spreadsheet-tasks';
|
|
@@ -148,7 +188,7 @@ await reader.open('data.xlsb');
|
|
|
148
188
|
|
|
149
189
|
console.log('Sheet names:', reader.getSheetNames());
|
|
150
190
|
|
|
151
|
-
while (reader.read()) {
|
|
191
|
+
while (await reader.read()) {
|
|
152
192
|
const row = [];
|
|
153
193
|
for (let i = 0; i < reader.fieldCount; i++) {
|
|
154
194
|
row.push(reader.getValue(i));
|
|
@@ -162,28 +202,69 @@ await xlsbReader.open('data.xlsb');
|
|
|
162
202
|
// ... same API as above
|
|
163
203
|
```
|
|
164
204
|
|
|
165
|
-
|
|
205
|
+
### Updating Data in an Existing Workbook
|
|
206
|
+
|
|
207
|
+
`XlsxUpdater` and `XlsbUpdater` replace the cell data of a worksheet inside an
|
|
208
|
+
existing workbook without rebuilding it. Everything else — pivot tables, charts,
|
|
209
|
+
other sheets, styles, defined names — is preserved, so you can keep an advanced
|
|
210
|
+
Excel file (like a report with pivot tables wired to a data sheet) and only
|
|
211
|
+
refresh its data:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
import { XlsxUpdater, XlsbUpdater } from '@justybase/spreadsheet-tasks';
|
|
215
|
+
|
|
216
|
+
// XLSX
|
|
217
|
+
const xlsx = new XlsxUpdater('report.xlsx');
|
|
218
|
+
xlsx.replaceSheetData('data1', rows, { headers: ['ID', 'NAME', 'AMOUNT'] });
|
|
219
|
+
xlsx.save(); // overwrite in place, or xlsx.save('report_new.xlsx')
|
|
220
|
+
|
|
221
|
+
// XLSB — the same API
|
|
222
|
+
const xlsb = new XlsbUpdater('report.xlsb');
|
|
223
|
+
xlsb.replaceSheetData('data1', rows, { headers: ['ID', 'NAME', 'AMOUNT'] });
|
|
224
|
+
xlsb.save('report_new.xlsb');
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**What happens under the hood:**
|
|
228
|
+
|
|
229
|
+
- The target sheet's cell data is cleared and replaced with the new rows.
|
|
230
|
+
- New strings are appended to the shared strings table (existing entries and
|
|
231
|
+
their indices are never moved, so other sheets stay valid).
|
|
232
|
+
- New cells reuse the dominant style of their column from the original data
|
|
233
|
+
(dates stay dates, numbers stay numbers). Pass `styleFallback: 'general'`
|
|
234
|
+
to write everything as General.
|
|
235
|
+
- Pivot tables whose cache source is the updated sheet get their source range
|
|
236
|
+
and record count adjusted, and `refreshOnLoad` is enabled so Excel refreshes
|
|
237
|
+
them automatically on open.
|
|
238
|
+
|
|
239
|
+
> **Tip:** always pass the `headers` matching the original columns. When
|
|
240
|
+
> `headers` are omitted, the first data row lands in row 1 and becomes the
|
|
241
|
+
> pivot's field names (Excel reads the first row of the source range as
|
|
242
|
+
> headers), so the pivot's columns would be replaced by the first record's
|
|
243
|
+
> values.
|
|
244
|
+
|
|
245
|
+
## API Documentation
|
|
166
246
|
|
|
167
247
|
See [API Documentation](./docs/API.md) for detailed API reference.
|
|
168
248
|
|
|
169
|
-
##
|
|
249
|
+
## Examples
|
|
170
250
|
|
|
171
251
|
Check out the [examples](./examples) folder for more usage examples:
|
|
172
252
|
|
|
173
|
-
- [Basic Write](./examples/basic-write.ts)
|
|
174
|
-
- [Basic Read](./examples/basic-read.ts)
|
|
175
|
-
- [Multiple Sheets](./examples/multiple-sheets.ts)
|
|
176
|
-
- [
|
|
177
|
-
- [
|
|
253
|
+
- [Basic Write](./examples/basic-write.ts) — Writing data to Excel files
|
|
254
|
+
- [Basic Read](./examples/basic-read.ts) — Reading data from Excel files
|
|
255
|
+
- [Multiple Sheets](./examples/multiple-sheets.ts) — Working with multiple worksheets
|
|
256
|
+
- [Update Existing Workbook](./examples/update-existing.ts) — Replacing the data of a sheet in an existing XLSX/XLSB with pivot tables
|
|
257
|
+
- [Large Dataset](./examples/large-dataset.ts) — Handling large datasets efficiently
|
|
258
|
+
- [Streaming Example](./examples/streaming-example.ts) — Write millions of rows without loading all data in memory
|
|
178
259
|
|
|
179
260
|
Run examples with:
|
|
261
|
+
|
|
180
262
|
```bash
|
|
181
263
|
npm run build
|
|
182
264
|
npx ts-node examples/basic-write.ts
|
|
183
265
|
```
|
|
184
266
|
|
|
185
|
-
|
|
186
|
-
## 🔍 When to Use XLSB vs XLSX
|
|
267
|
+
## When to Use XLSB vs XLSX
|
|
187
268
|
|
|
188
269
|
| Use XLSB When | Use XLSX When |
|
|
189
270
|
|---------------|---------------|
|
|
@@ -192,14 +273,30 @@ npx ts-node examples/basic-write.ts
|
|
|
192
273
|
| Internal/backend processing | Human-readable XML is needed |
|
|
193
274
|
| Storage space is limited | Third-party integrations require it |
|
|
194
275
|
|
|
195
|
-
##
|
|
276
|
+
## Contributing
|
|
277
|
+
|
|
278
|
+
Contributions are welcome. To work on the project locally:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
git clone https://github.com/justybase/justybase_spreadsheet_tasks.git
|
|
282
|
+
cd justybase_spreadsheet_tasks
|
|
283
|
+
npm install
|
|
284
|
+
npm run build
|
|
285
|
+
npm test
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Before opening a pull request:
|
|
289
|
+
|
|
290
|
+
1. Run `npm run lint` and `npm test`.
|
|
291
|
+
2. Add or update tests if you change behavior.
|
|
292
|
+
3. Update [CHANGELOG.md](./CHANGELOG.md) for user-visible changes.
|
|
196
293
|
|
|
197
|
-
|
|
294
|
+
Please open an issue or pull request on [GitHub](https://github.com/justybase/justybase_spreadsheet_tasks).
|
|
198
295
|
|
|
199
|
-
##
|
|
296
|
+
## License
|
|
200
297
|
|
|
201
|
-
This project is licensed under the MIT License
|
|
298
|
+
This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
|
|
202
299
|
|
|
203
|
-
##
|
|
300
|
+
## Acknowledgments
|
|
204
301
|
|
|
205
|
-
- Inspired by and reimplemented from [SpreadSheetTasks](https://github.com/
|
|
302
|
+
- Inspired by and reimplemented from [SpreadSheetTasks](https://github.com/justybae/SpreadSheetTasks)
|