@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
package/docs/API.md
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
- [XlsxWriter](#xlsxwriter)
|
|
7
7
|
- [XlsbReader](#xlsbreader)
|
|
8
8
|
- [XlsxReader](#xlsxreader)
|
|
9
|
+
- [XlsxUpdater](#xlsxupdater)
|
|
10
|
+
- [XlsbUpdater](#xlsbupdater)
|
|
9
11
|
- [ReaderFactory](#readerfactory)
|
|
10
12
|
- [Types](#types)
|
|
11
13
|
|
|
@@ -152,29 +154,30 @@ const sheets = reader.getSheetNames();
|
|
|
152
154
|
console.log(sheets); // ['Sheet1', 'Sheet2']
|
|
153
155
|
```
|
|
154
156
|
|
|
155
|
-
#### `read(): boolean
|
|
157
|
+
#### `read(): Promise<boolean>`
|
|
156
158
|
|
|
157
159
|
Reads the next row. Returns `true` if a row was read, `false` if end of sheet reached.
|
|
160
|
+
Always use `await` (both XLSB and XLSX are async in v2+).
|
|
158
161
|
|
|
159
162
|
**Example:**
|
|
160
163
|
```typescript
|
|
161
|
-
while (reader.read()) {
|
|
164
|
+
while (await reader.read()) {
|
|
162
165
|
// Process row
|
|
163
166
|
}
|
|
164
167
|
```
|
|
165
168
|
|
|
166
|
-
#### `getValue(columnIndex: number):
|
|
169
|
+
#### `getValue(columnIndex: number): CellValue`
|
|
167
170
|
|
|
168
171
|
Gets value at the specified column index in the current row.
|
|
169
172
|
|
|
170
173
|
**Parameters:**
|
|
171
174
|
- `columnIndex` - Zero-based column index
|
|
172
175
|
|
|
173
|
-
**Returns:**
|
|
176
|
+
**Returns:** `CellValue` (string, number, boolean, Date, bigint, or null/undefined)
|
|
174
177
|
|
|
175
178
|
**Example:**
|
|
176
179
|
```typescript
|
|
177
|
-
while (reader.read()) {
|
|
180
|
+
while (await reader.read()) {
|
|
178
181
|
const name = reader.getValue(0);
|
|
179
182
|
const age = reader.getValue(1);
|
|
180
183
|
console.log(`${name}: ${age}`);
|
|
@@ -215,16 +218,170 @@ Returns array of worksheet names.
|
|
|
215
218
|
|
|
216
219
|
#### `read(): Promise<boolean>`
|
|
217
220
|
|
|
218
|
-
Reads the next row. Returns `true` if a row was read.
|
|
219
|
-
|
|
220
|
-
> **Note:** Unlike XlsbReader, this method is async due to the XML parsing nature.
|
|
221
|
+
Reads the next row. Returns `true` if a row was read. Always use `await`.
|
|
221
222
|
|
|
222
|
-
#### `getValue(columnIndex: number):
|
|
223
|
+
#### `getValue(columnIndex: number): CellValue`
|
|
223
224
|
|
|
224
225
|
Gets value at the specified column index.
|
|
225
226
|
|
|
226
227
|
---
|
|
227
228
|
|
|
229
|
+
## XlsxUpdater
|
|
230
|
+
|
|
231
|
+
Updates the data of a worksheet inside an existing `.xlsx` file without rebuilding
|
|
232
|
+
the workbook. Everything outside the target sheet's cell data — pivot tables and
|
|
233
|
+
their caches, other sheets, styles, themes, defined names — is preserved, which
|
|
234
|
+
makes it possible to refresh a data sheet that pivot tables / charts / formulas
|
|
235
|
+
are wired to.
|
|
236
|
+
|
|
237
|
+
### Constructor
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
new XlsxUpdater(filePath: string)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Parameters:**
|
|
244
|
+
- `filePath` - Path to an existing `.xlsx` file
|
|
245
|
+
|
|
246
|
+
Throws if the file does not exist, is not a valid XLSX, or is an XLSB
|
|
247
|
+
(XLSB updates are not supported yet).
|
|
248
|
+
|
|
249
|
+
**Example:**
|
|
250
|
+
```typescript
|
|
251
|
+
const updater = new XlsxUpdater('report.xlsx');
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Methods
|
|
255
|
+
|
|
256
|
+
#### `getSheetNames(): string[]`
|
|
257
|
+
|
|
258
|
+
Returns the worksheet names in workbook order.
|
|
259
|
+
|
|
260
|
+
#### `replaceSheetData(sheetName: string, rows: CellValue[][], options?: ReplaceSheetDataOptions): void`
|
|
261
|
+
|
|
262
|
+
Clears the entire cell data of the target sheet and writes new rows in its place.
|
|
263
|
+
|
|
264
|
+
**Parameters:**
|
|
265
|
+
- `sheetName` - Name of the worksheet to replace. Throws if not found.
|
|
266
|
+
- `rows` - 2D array of new data (`null` / `undefined` cells stay empty).
|
|
267
|
+
Trailing rows that contain no non-empty cells are trimmed so the written
|
|
268
|
+
range matches the actual data (pivot tables won't pick up "(blank)" items
|
|
269
|
+
from padding rows).
|
|
270
|
+
- `options` - Optional object:
|
|
271
|
+
- `headers?: string[]` - Optional header row written into row 1
|
|
272
|
+
- `styleFallback?: 'inherit' | 'general'` - Style strategy for new cells
|
|
273
|
+
(default `'inherit'`)
|
|
274
|
+
|
|
275
|
+
**Behavior:**
|
|
276
|
+
- The sheet's `<dimension>` and `<autoFilter>` ranges are recalculated and end
|
|
277
|
+
exactly at the last data row.
|
|
278
|
+
- When `headers` are omitted, the first data row lands in row 1 and becomes the
|
|
279
|
+
pivot's field names — always pass `headers` matching the original columns.
|
|
280
|
+
- New strings are appended to `xl/sharedStrings.xml` (existing entries and their
|
|
281
|
+
indices are never modified); files without a shared string table use inline strings.
|
|
282
|
+
- With `styleFallback: 'inherit'` (default), new cells reuse the dominant style
|
|
283
|
+
of their column from the existing data, and `Date` cells fall back to a date
|
|
284
|
+
style found in `styles.xml` when the column has none.
|
|
285
|
+
- Pivot tables whose `worksheetSource` references the updated sheet get their
|
|
286
|
+
`ref` and `recordCount` adjusted, and `refreshOnLoad="1"` is added to the
|
|
287
|
+
pivot table definitions so Excel refreshes them on open.
|
|
288
|
+
|
|
289
|
+
**Example:**
|
|
290
|
+
```typescript
|
|
291
|
+
const updater = new XlsxUpdater('report.xlsx');
|
|
292
|
+
updater.replaceSheetData('data1', rows, { headers: ['ID', 'NAME'] });
|
|
293
|
+
updater.save('report_new.xlsx');
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### `save(outputPath?: string): void`
|
|
297
|
+
|
|
298
|
+
Writes the updated workbook to disk. When `outputPath` is omitted, the source
|
|
299
|
+
file is overwritten in place.
|
|
300
|
+
|
|
301
|
+
#### `toBuffer(): Buffer`
|
|
302
|
+
|
|
303
|
+
Returns the updated workbook as an in-memory ZIP buffer.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## XlsbUpdater
|
|
308
|
+
|
|
309
|
+
Updates the data of a worksheet inside an existing `.xlsb` file without
|
|
310
|
+
rebuilding the workbook. Everything outside the target sheet's rows — pivot
|
|
311
|
+
tables and their caches, other sheets, styles, column widths, views — is
|
|
312
|
+
preserved byte-for-byte.
|
|
313
|
+
|
|
314
|
+
The API is identical to [XlsxUpdater](#xlsxupdater); see that section for the
|
|
315
|
+
behavior of `replaceSheetData` (inherited column styles, shared-strings
|
|
316
|
+
appending, pivot cache range + `refreshOnLoad`).
|
|
317
|
+
|
|
318
|
+
### Constructor
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
new XlsbUpdater(filePath: string)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Parameters:**
|
|
325
|
+
- `filePath` - Path to an existing `.xlsb` file
|
|
326
|
+
|
|
327
|
+
Throws if the file does not exist, is not a valid XLSB, or is an XLSX
|
|
328
|
+
(XLSB-only updater).
|
|
329
|
+
|
|
330
|
+
### Methods
|
|
331
|
+
|
|
332
|
+
#### `getSheetNames(): string[]`
|
|
333
|
+
|
|
334
|
+
Returns the worksheet names in workbook order.
|
|
335
|
+
|
|
336
|
+
#### `replaceSheetData(sheetName: string, rows: CellValue[][], options?: ReplaceSheetDataOptions): void`
|
|
337
|
+
|
|
338
|
+
Clears the entire cell data of the target sheet and writes new rows in its place.
|
|
339
|
+
|
|
340
|
+
**Parameters:**
|
|
341
|
+
- `sheetName` - Name of the worksheet to replace. Throws if not found.
|
|
342
|
+
- `rows` - 2D array of new data (`null` / `undefined` cells stay empty).
|
|
343
|
+
Trailing rows that contain no non-empty cells are trimmed so the written
|
|
344
|
+
range matches the actual data (pivot tables won't pick up "(blank)" items
|
|
345
|
+
from padding rows).
|
|
346
|
+
- `options` - Optional object:
|
|
347
|
+
- `headers?: string[]` - Optional header row written into row 1
|
|
348
|
+
- `styleFallback?: 'inherit' | 'general'` - Style strategy for new cells
|
|
349
|
+
(default `'inherit'`)
|
|
350
|
+
|
|
351
|
+
**Behavior:**
|
|
352
|
+
- Only the worksheet's row records are replaced; column widths, views, and all
|
|
353
|
+
other sheet records are preserved. Auto-filter ranges are recalculated.
|
|
354
|
+
- The sheet's dimension record and the pivot cache source range end exactly at
|
|
355
|
+
the last data row.
|
|
356
|
+
- When `headers` are omitted, the first data row lands in row 1 and becomes the
|
|
357
|
+
pivot's field names — always pass `headers` matching the original columns.
|
|
358
|
+
- New strings are appended to `xl/sharedStrings.bin` (existing entries and their
|
|
359
|
+
indices are never modified).
|
|
360
|
+
- With `styleFallback: 'inherit'` (default), new cells reuse the dominant cell
|
|
361
|
+
style (xf) of their column from the existing data, and `Date` cells fall back
|
|
362
|
+
to a date style found in `styles.bin` when the column has none.
|
|
363
|
+
- Pivot caches whose `worksheetSource` references the updated sheet get their
|
|
364
|
+
range and record count adjusted, and the `refreshOnLoad` flag is set so Excel
|
|
365
|
+
refreshes them on open.
|
|
366
|
+
|
|
367
|
+
**Example:**
|
|
368
|
+
```typescript
|
|
369
|
+
const updater = new XlsbUpdater('report.xlsb');
|
|
370
|
+
updater.replaceSheetData('data1', rows, { headers: ['ID', 'NAME'] });
|
|
371
|
+
updater.save('report_new.xlsb');
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
#### `save(outputPath?: string): void`
|
|
375
|
+
|
|
376
|
+
Writes the updated workbook to disk. When `outputPath` is omitted, the source
|
|
377
|
+
file is overwritten in place.
|
|
378
|
+
|
|
379
|
+
#### `toBuffer(): Buffer`
|
|
380
|
+
|
|
381
|
+
Returns the updated workbook as an in-memory ZIP buffer.
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
228
385
|
## ReaderFactory
|
|
229
386
|
|
|
230
387
|
Factory class for creating appropriate reader based on file extension.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Dependencies and packaging notes
|
|
2
|
+
|
|
3
|
+
## ZIP libraries
|
|
4
|
+
|
|
5
|
+
The Node package uses three ZIP libraries on purpose — they match different I/O models:
|
|
6
|
+
|
|
7
|
+
| Library | Used by | Why |
|
|
8
|
+
|---------|---------|-----|
|
|
9
|
+
| **archiver** | `XlsbWriter`, `XlsxWriter` | Streaming ZIP **write** into a file stream (low memory for large workbooks) |
|
|
10
|
+
| **adm-zip** | `XlsbReader` | Synchronous full-load ZIP **read** (XLSB worksheets are binary and parsed sync with BIFF) |
|
|
11
|
+
| **yauzl** | `XlsxReader` | Lazy async ZIP **read** (XLSX sheet XML can be large; entries loaded on demand) |
|
|
12
|
+
|
|
13
|
+
Unifying on a single ZIP library is intentionally out of scope until a measured migration (especially XLSB reader sync path) is justified.
|
|
14
|
+
|
|
15
|
+
Type definitions come from `@types/adm-zip`, `@types/archiver`, and `@types/yauzl` (no hand-written ambient modules).
|
|
16
|
+
|
|
17
|
+
## Dual package (CJS + ESM)
|
|
18
|
+
|
|
19
|
+
`npm run build` (tsup) emits:
|
|
20
|
+
|
|
21
|
+
- `dist/cjs/` — CommonJS (`require`)
|
|
22
|
+
- `dist/esm/` — ESM (`import`), with a local `package.json` `{ "type": "module" }`
|
|
23
|
+
|
|
24
|
+
Consumers should use the package root export:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
// CJS
|
|
28
|
+
const { XlsbWriter } = require('@justybase/spreadsheet-tasks');
|
|
29
|
+
|
|
30
|
+
// ESM
|
|
31
|
+
import { XlsbWriter } from '@justybase/spreadsheet-tasks';
|
|
32
|
+
```
|
package/docs/PUBLISHING.md
CHANGED
|
@@ -32,11 +32,16 @@ If the automated workflow fails or you need to publish manually:
|
|
|
32
32
|
|
|
33
33
|
### Steps
|
|
34
34
|
|
|
35
|
-
1. Build the project:
|
|
35
|
+
1. Build the project (CJS + ESM):
|
|
36
36
|
```bash
|
|
37
37
|
npm run build
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
Optionally build the browser IIFE bundle:
|
|
41
|
+
```bash
|
|
42
|
+
npm run build:browser
|
|
43
|
+
```
|
|
44
|
+
|
|
40
45
|
2. Run tests to ensure everything works:
|
|
41
46
|
```bash
|
|
42
47
|
npm test
|
|
@@ -47,6 +52,8 @@ If the automated workflow fails or you need to publish manually:
|
|
|
47
52
|
npm publish --access public
|
|
48
53
|
```
|
|
49
54
|
|
|
55
|
+
See [PACKAGING.md](./PACKAGING.md) for dual CJS/ESM layout and ZIP dependency notes.
|
|
56
|
+
|
|
50
57
|
## First Time Publishing
|
|
51
58
|
|
|
52
59
|
For the first time publishing a scoped package (`@justybase/spreadsheet-tasks`):
|
package/examples/basic-read.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Run with: npx ts-node examples/basic-read.ts
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { XlsbReader, XlsxReader, ReaderFactory } from '../dist';
|
|
10
|
+
import { XlsbReader, XlsxReader, ReaderFactory } from '../dist/cjs';
|
|
11
11
|
import * as path from 'path';
|
|
12
12
|
|
|
13
13
|
async function readXlsbExample() {
|
|
@@ -26,7 +26,7 @@ async function readXlsbExample() {
|
|
|
26
26
|
|
|
27
27
|
// Read all rows
|
|
28
28
|
let rowCount = 0;
|
|
29
|
-
while (reader.read()) {
|
|
29
|
+
while (await reader.read()) {
|
|
30
30
|
const row: any[] = [];
|
|
31
31
|
for (let i = 0; i < reader.fieldCount; i++) {
|
|
32
32
|
row.push(reader.getValue(i));
|
package/examples/basic-write.ts
CHANGED
|
@@ -23,8 +23,7 @@ async function verifyFile(filePath: string, label: string) {
|
|
|
23
23
|
console.log(` Rows: ${reader.rowCount}, Cols: ${reader.fieldCount}`);
|
|
24
24
|
|
|
25
25
|
const allRows: any[][] = [];
|
|
26
|
-
|
|
27
|
-
while (isAsync ? await (reader as XlsxReader).read() : (reader as XlsbReader).read()) {
|
|
26
|
+
while (await reader.read()) {
|
|
28
27
|
const row: any[] = [];
|
|
29
28
|
for (let i = 0; i < reader.fieldCount; i++) {
|
|
30
29
|
row.push(reader.getValue(i));
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Run with: npx ts-node examples/large-dataset.ts
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { XlsbWriter, XlsxWriter, XlsbReader, XlsxReader } from '../dist';
|
|
10
|
+
import { XlsbWriter, XlsxWriter, XlsbReader, XlsxReader } from '../dist/cjs';
|
|
11
11
|
import * as path from 'path';
|
|
12
12
|
import * as fs from 'fs';
|
|
13
13
|
|
|
@@ -106,7 +106,7 @@ async function readLargeXlsb(): Promise<{ time: number; rowCount: number }> {
|
|
|
106
106
|
await reader.open(filePath);
|
|
107
107
|
|
|
108
108
|
let rowCount = 0;
|
|
109
|
-
while (reader.read()) {
|
|
109
|
+
while (await reader.read()) {
|
|
110
110
|
rowCount++;
|
|
111
111
|
// Access values to simulate real-world usage
|
|
112
112
|
for (let i = 0; i < reader.fieldCount; i++) {
|
|
@@ -7,13 +7,15 @@
|
|
|
7
7
|
* Run with: npx ts-node examples/streaming-example.ts
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { XlsbWriter } from '../dist/
|
|
10
|
+
import { XlsbWriter } from '../dist/cjs';
|
|
11
11
|
import * as path from 'path';
|
|
12
|
+
import * as fs from 'fs';
|
|
12
13
|
|
|
13
14
|
async function streamingExample() {
|
|
14
15
|
console.log('=== XlsbWriter Streaming Example ===\n');
|
|
15
16
|
|
|
16
17
|
const outputPath = path.join(__dirname, '..', 'output', 'streaming-example.xlsb');
|
|
18
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
17
19
|
console.log(`Output file: ${outputPath}\n`);
|
|
18
20
|
|
|
19
21
|
const writer = new XlsbWriter(outputPath);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update Existing Workbook Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to replace the data of a worksheet inside an
|
|
5
|
+
* existing Excel file (e.g. a report whose pivot tables are wired to a "data1"
|
|
6
|
+
* sheet) without rebuilding the workbook. The same API works for XLSX and XLSB.
|
|
7
|
+
*
|
|
8
|
+
* Run with: npx ts-node examples/update-existing.ts
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { XlsxUpdater, XlsbUpdater } from '../dist/cjs';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
|
|
15
|
+
const outputDir = path.join(__dirname, 'output');
|
|
16
|
+
if (!fs.existsSync(outputDir)) {
|
|
17
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function updateExistingWorkbook() {
|
|
21
|
+
// New data for the "data1" sheet (same columns as before)
|
|
22
|
+
const rows = [
|
|
23
|
+
[new Date('2026-01-01'), 'PL', 'Warsaw', 1200.5, true],
|
|
24
|
+
[new Date('2026-01-02'), 'DE', 'Berlin', 980.25, true],
|
|
25
|
+
[new Date('2026-01-03'), 'PL', 'Krakow', 1530.0, false],
|
|
26
|
+
];
|
|
27
|
+
const headers = ['DATEKEY', 'COUNTRY', 'CITY', 'AMOUNT', 'ACTIVE'];
|
|
28
|
+
|
|
29
|
+
for (const ext of ['xlsx', 'xlsb']) {
|
|
30
|
+
const input = path.join(__dirname, '..', `report.${ext}`);
|
|
31
|
+
const output = path.join(outputDir, `report_updated.${ext}`);
|
|
32
|
+
|
|
33
|
+
if (!fs.existsSync(input)) {
|
|
34
|
+
console.log(`Template workbook not found: ${input} (skipping)`);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Open the existing workbook (everything outside the replaced sheet
|
|
39
|
+
// — pivot tables, other sheets, styles — is preserved)
|
|
40
|
+
const updater = ext === 'xlsb' ? new XlsbUpdater(input) : new XlsxUpdater(input);
|
|
41
|
+
console.log(`[${ext}] Sheets:`, updater.getSheetNames());
|
|
42
|
+
|
|
43
|
+
updater.replaceSheetData('data1', rows, { headers });
|
|
44
|
+
|
|
45
|
+
// Write the updated workbook to a new file (or omit the path to
|
|
46
|
+
// overwrite the source in place)
|
|
47
|
+
updater.save(output);
|
|
48
|
+
console.log(`[${ext}] Workbook updated: ${output}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
updateExistingWorkbook();
|
|
53
|
+
|
package/package.json
CHANGED
|
@@ -1,30 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justybase/spreadsheet-tasks",
|
|
3
|
-
"version": "1.
|
|
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.
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"
|
|
3
|
+
"version": "2.1.0",
|
|
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
|
+
"main": "./dist/cjs/index.js",
|
|
6
|
+
"module": "./dist/esm/index.js",
|
|
7
|
+
"types": "./dist/cjs/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/cjs/index.d.ts",
|
|
11
|
+
"import": "./dist/esm/index.js",
|
|
12
|
+
"require": "./dist/cjs/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
7
15
|
"files": [
|
|
8
16
|
"dist",
|
|
17
|
+
"browser/justybase-spreadsheet.min.js",
|
|
18
|
+
"browser/browser-spreadsheet.js",
|
|
9
19
|
"README.md",
|
|
20
|
+
"CHANGELOG.md",
|
|
10
21
|
"LICENSE",
|
|
11
22
|
"docs",
|
|
12
23
|
"examples"
|
|
13
24
|
],
|
|
14
25
|
"scripts": {
|
|
15
|
-
"build": "
|
|
26
|
+
"build": "tsup && node -e \"require('fs').copyFileSync('dist-esm-package.json','dist/esm/package.json')\"",
|
|
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",
|
|
16
28
|
"lint": "eslint src/",
|
|
17
29
|
"typecheck": "tsc --noEmit",
|
|
18
|
-
"test": "npm run
|
|
19
|
-
"test:smoke": "
|
|
30
|
+
"test": "npm run typecheck && npm run test:smoke && npm run test:unit && npm run test:integration && npm run test:dist",
|
|
31
|
+
"test:smoke": "npx ts-node tests/smoke.test.ts",
|
|
20
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",
|
|
21
|
-
"test:integration": "
|
|
22
|
-
"test:
|
|
23
|
-
"test:
|
|
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
|
+
"test:dist": "npm run build && npx ts-node tests/dist-surface.test.ts",
|
|
35
|
+
"test:xlsb": "npx ts-node tests/integration/xlsb-writer.test.ts && npx ts-node tests/integration/xlsb-updater.test.ts",
|
|
36
|
+
"test:xlsx": "npx ts-node tests/integration/xlsx-writer.test.ts",
|
|
24
37
|
"benchmark": "npm run build && npx ts-node benchmarks/performance.bench.ts",
|
|
25
38
|
"benchmark:comparison": "npm run build && npx ts-node benchmarks/comparison.bench.ts",
|
|
26
39
|
"test:excel-compat": "npm run build && npx tsx tests/excel-compat/run.ts",
|
|
27
|
-
"prepublishOnly": "npm run build && npm test"
|
|
40
|
+
"prepublishOnly": "npm run build && npm run build:browser && npm test"
|
|
28
41
|
},
|
|
29
42
|
"keywords": [
|
|
30
43
|
"excel",
|
|
@@ -42,11 +55,11 @@
|
|
|
42
55
|
"license": "MIT",
|
|
43
56
|
"repository": {
|
|
44
57
|
"type": "git",
|
|
45
|
-
"url": "git+https://github.com/
|
|
58
|
+
"url": "git+https://github.com/justybase/justybase_spreadsheet_tasks.git"
|
|
46
59
|
},
|
|
47
|
-
"homepage": "https://github.com/
|
|
60
|
+
"homepage": "https://github.com/justybase/justybase_spreadsheet_tasks#readme",
|
|
48
61
|
"bugs": {
|
|
49
|
-
"url": "https://github.com/
|
|
62
|
+
"url": "https://github.com/justybase/justybase_spreadsheet_tasks/issues"
|
|
50
63
|
},
|
|
51
64
|
"engines": {
|
|
52
65
|
"node": ">=16.0.0"
|
|
@@ -62,9 +75,11 @@
|
|
|
62
75
|
"@types/archiver": "^7.0.0",
|
|
63
76
|
"@types/node": "^22.10.5",
|
|
64
77
|
"@types/yauzl": "^2.10.3",
|
|
78
|
+
"esbuild": "0.28.1",
|
|
65
79
|
"eslint": "^9.17.0",
|
|
66
80
|
"exceljs": "^3.4.0",
|
|
67
81
|
"ts-node": "^10.9.2",
|
|
82
|
+
"tsup": "8.5.1",
|
|
68
83
|
"typescript": "^5.7.2",
|
|
69
84
|
"typescript-eslint": "^8.19.1"
|
|
70
85
|
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export declare class BiffReaderWriter {
|
|
2
|
-
private buffer;
|
|
3
|
-
private pos;
|
|
4
|
-
private length;
|
|
5
|
-
_isSheet: boolean;
|
|
6
|
-
_workbookId: number;
|
|
7
|
-
_recId: string | null;
|
|
8
|
-
_workbookName: string | null;
|
|
9
|
-
private _inCellXf;
|
|
10
|
-
private _inNumberFormat;
|
|
11
|
-
private _numberFormatIndex;
|
|
12
|
-
private _format;
|
|
13
|
-
private _formatString;
|
|
14
|
-
_sharedStringValue: string | null;
|
|
15
|
-
_sharedStringUniqueCount: number;
|
|
16
|
-
_cellType: number;
|
|
17
|
-
_intValue: number;
|
|
18
|
-
_doubleVal: number;
|
|
19
|
-
_boolValue: boolean;
|
|
20
|
-
_stringValue: string | null;
|
|
21
|
-
_columnNum: number;
|
|
22
|
-
_xfIndex: number;
|
|
23
|
-
_readCell: boolean;
|
|
24
|
-
_rowIndex: number;
|
|
25
|
-
private _recordStart;
|
|
26
|
-
_xfIndexToNumFmtId: number[];
|
|
27
|
-
_customNumFmts: Set<number>;
|
|
28
|
-
constructor(buffer: Buffer);
|
|
29
|
-
private _tryReadVariableValue;
|
|
30
|
-
private _getDWord;
|
|
31
|
-
private _getInt32;
|
|
32
|
-
private _getWord;
|
|
33
|
-
private _getByte;
|
|
34
|
-
private _getDouble;
|
|
35
|
-
private _getString;
|
|
36
|
-
private _getNullableString;
|
|
37
|
-
readWorkbook(): boolean;
|
|
38
|
-
readSharedStrings(): boolean;
|
|
39
|
-
readStyles(): boolean;
|
|
40
|
-
private _getRkNumber;
|
|
41
|
-
readWorksheet(): boolean;
|
|
42
|
-
}
|
|
43
|
-
export default BiffReaderWriter;
|
|
44
|
-
//# sourceMappingURL=BiffReaderWriter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BiffReaderWriter.d.ts","sourceRoot":"","sources":["../src/BiffReaderWriter.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IAEvB,QAAQ,EAAE,OAAO,CAAS;IAC1B,WAAW,EAAE,MAAM,CAAK;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,aAAa,CAAuB;IAE5C,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACzC,wBAAwB,EAAE,MAAM,CAAK;IAErC,SAAS,EAAE,MAAM,CAAK;IACtB,SAAS,EAAE,MAAM,CAAK;IACtB,UAAU,EAAE,MAAM,CAAO;IACzB,UAAU,EAAE,OAAO,CAAS;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC,UAAU,EAAE,MAAM,CAAM;IACxB,QAAQ,EAAE,MAAM,CAAK;IACrB,SAAS,EAAE,OAAO,CAAS;IAC3B,SAAS,EAAE,MAAM,CAAM;IAGvB,OAAO,CAAC,YAAY,CAAa;IAEjC,kBAAkB,EAAE,MAAM,EAAE,CAAM;IAClC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;gBAE5B,MAAM,EAAE,MAAM;IAS1B,OAAO,CAAC,qBAAqB;IA2B7B,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,kBAAkB;IAW1B,YAAY,IAAI,OAAO;IA4BvB,iBAAiB,IAAI,OAAO;IAyB5B,UAAU,IAAI,OAAO;IAyDrB,OAAO,CAAC,YAAY;IA6BpB,aAAa,IAAI,OAAO;CAoF3B;AAED,eAAe,gBAAgB,CAAC"}
|