@dipanshuhandoo/excelio 0.0.0-stage → 1.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 +11 -0
- package/LICENSE +21 -0
- package/README.md +242 -3
- package/dist/cjs/index.cjs +584 -0
- package/dist/cjs/index.cjs.map +7 -0
- package/dist/cjs/index.d.cts +172 -0
- package/dist/cjs/workers/reader.worker.cjs +212 -0
- package/dist/cjs/workers/reader.worker.cjs.map +7 -0
- package/dist/cjs/workers/writer.worker.cjs +274 -0
- package/dist/cjs/workers/writer.worker.cjs.map +7 -0
- package/dist/cjs-min/index.cjs +2 -0
- package/dist/cjs-min/index.cjs.map +7 -0
- package/dist/cjs-min/index.d.cts +172 -0
- package/dist/cjs-min/workers/reader.worker.cjs +2 -0
- package/dist/cjs-min/workers/reader.worker.cjs.map +7 -0
- package/dist/cjs-min/workers/writer.worker.cjs +2 -0
- package/dist/cjs-min/workers/writer.worker.cjs.map +7 -0
- package/dist/esm/index.d.ts +172 -0
- package/dist/esm/index.js +547 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/workers/reader.worker.js +189 -0
- package/dist/esm/workers/reader.worker.js.map +7 -0
- package/dist/esm/workers/writer.worker.js +251 -0
- package/dist/esm/workers/writer.worker.js.map +7 -0
- package/dist/esm-min/index.d.ts +172 -0
- package/dist/esm-min/index.js +2 -0
- package/dist/esm-min/index.js.map +7 -0
- package/dist/esm-min/workers/reader.worker.js +2 -0
- package/dist/esm-min/workers/reader.worker.js.map +7 -0
- package/dist/esm-min/workers/writer.worker.js +2 -0
- package/dist/esm-min/workers/writer.worker.js.map +7 -0
- package/package.json +48 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (Unreleased)
|
|
4
|
+
|
|
5
|
+
- Package as `@dipanshuhandoo/excelio`, supporting Node.js 22 and 24 LTS.
|
|
6
|
+
- Add readable/minified ESM and CommonJS builds, worker bundles, and declarations.
|
|
7
|
+
- Preserve Buffer results across worker threads and keep stream inputs inline.
|
|
8
|
+
- Add installed-tarball consumer verification and explicit public npm commands.
|
|
9
|
+
- Add runnable use-case examples, including XLSX-to-JSON conversion, selection/cleanup
|
|
10
|
+
tooling, and CI coverage.
|
|
11
|
+
- Document XLSX API behavior, memory limitations, and release/support policies.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DipanshuHandoo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,242 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# ExcelIO
|
|
2
|
+
|
|
3
|
+
`@dipanshuhandoo/excelio` converts JavaScript row objects to XLSX workbooks and
|
|
4
|
+
reads XLSX files into structured data. It supports streaming writes, multiple
|
|
5
|
+
sheets/workbooks, row transforms and validation, and configurable worker-thread
|
|
6
|
+
offloading. It is a Node.js library, not a browser library.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @dipanshuhandoo/excelio
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Requires Node.js 22 or later. Node 22 and 24 LTS are the tested support matrix.
|
|
15
|
+
TypeScript consumers should install `typescript` and `@types/node` as development
|
|
16
|
+
dependencies; NodeNext resolution supports both import and require declarations.
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { excelio } from '@dipanshuhandoo/excelio';
|
|
22
|
+
|
|
23
|
+
const spec = [{
|
|
24
|
+
workbook: 'sales',
|
|
25
|
+
properties: { author: 'system', title: 'Sales Report' },
|
|
26
|
+
sheets: [{
|
|
27
|
+
sheet: 'Orders',
|
|
28
|
+
columns: [
|
|
29
|
+
{ key: 'customer', header: 'Customer', width: 30 },
|
|
30
|
+
{ key: 'amount', type: 'number', format: '#,##0.00' },
|
|
31
|
+
{ key: 'date', type: 'date' }
|
|
32
|
+
],
|
|
33
|
+
styling: { headerBold: true, freezeHeader: true, autoFilter: true },
|
|
34
|
+
data: [{ customer: 'Alice', amount: 100, date: new Date('2026-01-15') }]
|
|
35
|
+
}]
|
|
36
|
+
}];
|
|
37
|
+
|
|
38
|
+
const buffer = await excelio.write(spec);
|
|
39
|
+
await excelio.write(spec, { to: 'sales.xlsx' });
|
|
40
|
+
const result = await excelio.read(buffer);
|
|
41
|
+
console.log(result.data[0].sheets[0].data);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
CommonJS exposes the same named exports:
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
const { excelio, ExcelIoError } = require('@dipanshuhandoo/excelio');
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Opt-in minified builds have the same API and include their own worker files:
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
import { excelio } from '@dipanshuhandoo/excelio/min';
|
|
54
|
+
// CommonJS: const { excelio } = require('@dipanshuhandoo/excelio/min');
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Minification reduces library code size, not ExcelJS's installed dependencies or
|
|
58
|
+
workbook-processing time. Both builds include source maps and declarations.
|
|
59
|
+
|
|
60
|
+
## Runnable Examples
|
|
61
|
+
|
|
62
|
+
See the [example guide](https://github.com/DipanshuHandoo/excelio/blob/main/examples/README.md)
|
|
63
|
+
for buffer round-trips, styled multi-sheet reports, validated imports, streaming,
|
|
64
|
+
workers/concurrent exports, progress/cancellation, CommonJS/minified usage, and
|
|
65
|
+
XLSX-to-JSON conversion.
|
|
66
|
+
Examples live in the repository and use public package exports.
|
|
67
|
+
|
|
68
|
+
From a checkout, run all cases or select one:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
npm run examples
|
|
72
|
+
npm run examples -- 03-import-validation
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The runner builds first, checks results, and cleans up temporary spreadsheets.
|
|
76
|
+
Run the file examples directly after building to keep their XLSX/JSON output:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
node examples/02-sales-report.mjs
|
|
80
|
+
node examples/04-streaming.mjs
|
|
81
|
+
node examples/08-excel-to-json.mjs
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
These save to the ignored example-output/ directory by default.
|
|
85
|
+
|
|
86
|
+
## API
|
|
87
|
+
|
|
88
|
+
### Writing
|
|
89
|
+
|
|
90
|
+
- `await excelio.write(spec)` returns a Buffer for one workbook or Buffer[] for
|
|
91
|
+
multiple workbooks.
|
|
92
|
+
- `await excelio.write(spec, { to: filePath })` writes one workbook and returns
|
|
93
|
+
the path. A writable stream target is also supported and returned unchanged.
|
|
94
|
+
- `excelio.writeStream(spec)` returns a readable stream synchronously, writes
|
|
95
|
+
only the first workbook, and runs inline. Consume it or pipe it to a destination;
|
|
96
|
+
handle asynchronous errors via the stream's error event or pipeline.
|
|
97
|
+
- A single `to` target cannot receive multiple workbooks. Omit it to receive
|
|
98
|
+
separate buffers, or write each workbook individually. No ZIP wrapper is added.
|
|
99
|
+
|
|
100
|
+
`spec` is a non-empty array of workbooks, each containing a non-empty `sheets`
|
|
101
|
+
array. Sheets contain `sheet`, optional `columns` and `styling`, and a `data`
|
|
102
|
+
array. Workbook properties support author, company, title, created, and modified.
|
|
103
|
+
The `workbook` field is logical metadata, not an automatic filename.
|
|
104
|
+
|
|
105
|
+
Columns support key, header, width, type (`string`, `number`, `boolean`, `date`),
|
|
106
|
+
and Excel number-format string. Without explicit columns, keys are inferred from
|
|
107
|
+
the first row only. Width defaults to 15. Sheet names replace forbidden Excel
|
|
108
|
+
characters, truncate to 31 characters, and receive suffixes when duplicated.
|
|
109
|
+
`logger.warn` reports truncation.
|
|
110
|
+
|
|
111
|
+
### Reading
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
const result = await excelio.read('sales.xlsx');
|
|
115
|
+
// Also accepts a Buffer or readable stream.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The result contains:
|
|
119
|
+
|
|
120
|
+
```js
|
|
121
|
+
{
|
|
122
|
+
ok: true,
|
|
123
|
+
data: [{ workbook: undefined, sheets: [{ sheet: 'Orders', columns: [], data: [] }] }],
|
|
124
|
+
errors: [],
|
|
125
|
+
stats: { totalRows: 0, totalSheets: 1, durationMs: 0 }
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Column entries contain `key` and `header`. Read data uses header text as object
|
|
130
|
+
keys, not the original write keys. A column written as `{ key: 'customer',
|
|
131
|
+
header: 'Customer' }` reads back as `{ Customer: 'Alice' }`. Keep header equal to
|
|
132
|
+
key for round-trippable field names. The original workbook label, properties,
|
|
133
|
+
column types, widths, and styling are not reconstructed in the read result.
|
|
134
|
+
|
|
135
|
+
Read options: `headerRow` (default 1), `nullForBlank` (true), `trimStrings` (true),
|
|
136
|
+
and `dateFormat` (`iso`, `date`, or `epoch`; default `iso`). Entirely blank rows
|
|
137
|
+
are skipped. Formula cells return cached results, not formula text; rich text
|
|
138
|
+
and hyperlinks return displayed text. Excel error values become null.
|
|
139
|
+
`totalRows` counts accepted rows after transformation and validation.
|
|
140
|
+
|
|
141
|
+
### Transforms and Validation
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
const result = await excelio.read(buffer, {
|
|
145
|
+
afterRead: row => ({ ...row, email: row.email?.toLowerCase() }),
|
|
146
|
+
validateRow: row => row.amount < 0
|
|
147
|
+
? { code: 'NEGATIVE_AMOUNT', message: 'Amount must be non-negative', column: 'amount' }
|
|
148
|
+
: null,
|
|
149
|
+
onRowError: 'collect'
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
await excelio.write(spec, {
|
|
153
|
+
beforeWrite: row => ({ ...row, amount: Number(row.amount) })
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Hooks are synchronous. They receive `(row, ctx)` where ctx contains workbookIndex,
|
|
158
|
+
workbookName, sheetIndex, sheetName, and the 1-based Excel rowNumber. Read applies
|
|
159
|
+
afterRead before validateRow. Invalid rows are excluded from data and collected
|
|
160
|
+
in errors by default; `onRowError: 'fail'` throws on the first issue. A hook
|
|
161
|
+
returning null/undefined keeps the original row. Write transforms do not add
|
|
162
|
+
columns beyond the explicit or inferred column set.
|
|
163
|
+
|
|
164
|
+
### Workers, Progress, and Cancellation
|
|
165
|
+
|
|
166
|
+
```js
|
|
167
|
+
await excelio.write(spec, { useWorker: true });
|
|
168
|
+
await excelio.read(buffer, { useWorker: false });
|
|
169
|
+
await excelio.write(spec, { workerThreshold: { rows: 100_000, bytes: 50 * 1024 * 1024 } });
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`useWorker` defaults to `auto`. Writes offload at 50,000 total rows; reads offload
|
|
173
|
+
at 10 MiB for buffers or file paths. Threshold comparisons are inclusive.
|
|
174
|
+
Each offloaded operation creates one worker, then terminates it. There is no
|
|
175
|
+
reusable worker pool, concurrency cap, or parallel splitting of a workbook.
|
|
176
|
+
Submit independent operations concurrently only when memory and CPU permit.
|
|
177
|
+
|
|
178
|
+
Functions (`beforeWrite`, `afterRead`, `validateRow`, `onProgress`), `logger`,
|
|
179
|
+
`signal`, stream inputs, and writable stream destinations force inline execution,
|
|
180
|
+
even when useWorker is true. Worker payloads must be structured-cloneable;
|
|
181
|
+
functions or unsupported values embedded in row data cannot be sent to workers.
|
|
182
|
+
Bundlers/serverless deployments must preserve the emitted entrypoint and its
|
|
183
|
+
sibling workers directory. Import the package normally rather than copying a
|
|
184
|
+
single bundled file.
|
|
185
|
+
|
|
186
|
+
`onProgress` receives phase and rowsProcessed plus available workbook/sheet
|
|
187
|
+
metadata. `batchSize` defaults to 5,000 and controls notifications, not memory
|
|
188
|
+
or yielding. Writes emit a final notification; reads notify at batch boundaries.
|
|
189
|
+
`signal` is checked between rows and sheets, but cannot interrupt initial XLSX
|
|
190
|
+
loading, commit, or synchronous row loops. Do not rely on timely cancellation of
|
|
191
|
+
an in-progress operation from an event-loop callback.
|
|
192
|
+
|
|
193
|
+
### Values and Errors
|
|
194
|
+
|
|
195
|
+
Date columns accept Date, ISO date strings, and epoch milliseconds. Number
|
|
196
|
+
columns convert finite numeric strings; boolean columns recognize true/false,
|
|
197
|
+
the strings 'true'/'false', and 1/0. Unsupported coercions are left unchanged;
|
|
198
|
+
these hints are not schema validation. Multiline and multilingual text is supported.
|
|
199
|
+
|
|
200
|
+
`ExcelIoError` exposes code, optional cause, and optional details. Codes include
|
|
201
|
+
INVALID_SPEC, IO_ERROR, ABORTED, WORKER_ERROR, and ROW_VALIDATION. Collected read
|
|
202
|
+
errors contain workbook index, sheet, row, column, code, and message. `ok` is
|
|
203
|
+
false when collected errors exist; callers decide whether to accept partial data.
|
|
204
|
+
Some lower-level ExcelJS/write errors can propagate as ordinary Error instances.
|
|
205
|
+
|
|
206
|
+
## Memory and Scope
|
|
207
|
+
|
|
208
|
+
Writes use ExcelJS's streaming XLSX writer and commit rows incrementally, but
|
|
209
|
+
input arrays and shared strings remain in memory; buffer output also collects
|
|
210
|
+
the complete file. Direct file/stream output avoids that final buffer.
|
|
211
|
+
Reading currently loads the entire workbook and collects accepted rows.
|
|
212
|
+
Workers keep processing off the main thread but do not guarantee lower total
|
|
213
|
+
memory or faster completion; cloning large inputs adds overhead.
|
|
214
|
+
|
|
215
|
+
Browsers, legacy XLS, charts, pivots, macros, encryption, and advanced formatting
|
|
216
|
+
are outside this library's API. Only features described above are supported.
|
|
217
|
+
|
|
218
|
+
## Development and Releases
|
|
219
|
+
|
|
220
|
+
```sh
|
|
221
|
+
npm ci
|
|
222
|
+
npm run verify
|
|
223
|
+
npm run build:min
|
|
224
|
+
npm run test:perf
|
|
225
|
+
npm run pack:check
|
|
226
|
+
npm run publish:dry-run
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
`build` produces dist/esm, dist/cjs, dist/esm-min, and dist/cjs-min with bundled
|
|
230
|
+
worker entrypoints and matching declarations. `build:min` regenerates only the
|
|
231
|
+
minified outputs; run a full build for a release. The only direct runtime
|
|
232
|
+
dependency is ExcelJS; esbuild, TypeScript, and Node types are development tools.
|
|
233
|
+
|
|
234
|
+
See [Contributing](https://github.com/DipanshuHandoo/excelio/blob/main/CONTRIBUTING.md),
|
|
235
|
+
[Releasing](https://github.com/DipanshuHandoo/excelio/blob/main/RELEASING.md),
|
|
236
|
+
[Security](https://github.com/DipanshuHandoo/excelio/blob/main/SECURITY.md), and
|
|
237
|
+
[CHANGELOG.md](CHANGELOG.md). Public npm availability
|
|
238
|
+
starts with the first approved publication; repository setup does not publish it.
|
|
239
|
+
|
|
240
|
+
## License
|
|
241
|
+
|
|
242
|
+
MIT. See [LICENSE](LICENSE).
|