@niicojs/excel 0.2.4 → 0.2.6

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 niico
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
1
+ MIT License
2
+
3
+ Copyright (c) 2026 niico
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
21
  SOFTWARE.
package/README.md CHANGED
@@ -9,9 +9,6 @@ A TypeScript library for Excel/OpenXML manipulation with maximum format preserva
9
9
  - Full formula support (read/write/preserve)
10
10
  - Cell styles (fonts, fills, borders, alignment)
11
11
  - Merged cells
12
- - Column widths and row heights
13
- - Freeze panes
14
- - Pivot tables with fluent API
15
12
  - Sheet operations (add, delete, rename, copy)
16
13
  - Create sheets from arrays of objects (`addSheetFromData`)
17
14
  - Convert sheets to JSON arrays (`toJson`)
@@ -142,47 +139,6 @@ sheet.unmergeCells('A1:C1');
142
139
  console.log(sheet.mergedCells); // ['A1:C3', 'D5:E10', ...]
143
140
  ```
144
141
 
145
- ## Column Widths and Row Heights
146
-
147
- ```typescript
148
- const sheet = wb.sheet(0);
149
-
150
- // Set column width (by letter or 0-based index)
151
- sheet.setColumnWidth('A', 20);
152
- sheet.setColumnWidth(1, 15); // Column B
153
-
154
- // Get column width
155
- const width = sheet.getColumnWidth('A'); // 20 or undefined
156
-
157
- // Set row height (0-based index)
158
- sheet.setRowHeight(0, 30); // First row
159
-
160
- // Get row height
161
- const height = sheet.getRowHeight(0); // 30 or undefined
162
- ```
163
-
164
- ## Freeze Panes
165
-
166
- ```typescript
167
- const sheet = wb.sheet(0);
168
-
169
- // Freeze first row (header)
170
- sheet.freezePane(1, 0);
171
-
172
- // Freeze first column
173
- sheet.freezePane(0, 1);
174
-
175
- // Freeze first row and first column
176
- sheet.freezePane(1, 1);
177
-
178
- // Unfreeze
179
- sheet.freezePane(0, 0);
180
-
181
- // Get current freeze pane configuration
182
- const frozen = sheet.getFrozenPane();
183
- // { row: 1, col: 0 } or null
184
- ```
185
-
186
142
  ## Sheet Operations
187
143
 
188
144
  ```typescript
@@ -209,56 +165,6 @@ wb.copySheet('RawData', 'RawData_Backup');
209
165
  wb.deleteSheet('Summary');
210
166
  ```
211
167
 
212
- ## Pivot Tables
213
-
214
- Create pivot tables with a fluent API:
215
-
216
- ```typescript
217
- const wb = await Workbook.fromFile('sales-data.xlsx');
218
-
219
- // Create a pivot table from source data
220
- const pivot = wb.createPivotTable({
221
- name: 'SalesPivot',
222
- source: 'Data!A1:E100', // Source range with headers
223
- target: 'Summary!A3', // Where to place the pivot table
224
- refreshOnLoad: true, // Refresh when file opens (default: true)
225
- });
226
-
227
- // Configure fields using fluent API
228
- pivot
229
- .addRowField('Region') // Group by region
230
- .addRowField('Product') // Then by product
231
- .addColumnField('Year') // Columns by year
232
- .addValueField('Sales', 'sum', 'Total Sales') // Sum of sales
233
- .addValueField('Quantity', 'count', 'Order Count') // Count of orders
234
- .addFilterField('Category'); // Page filter
235
-
236
- // Sort and filter fields
237
- pivot
238
- .sortField('Region', 'asc') // Sort ascending
239
- .filterField('Product', { include: ['Widget', 'Gadget'] }); // Include only these
240
-
241
- await wb.toFile('report.xlsx');
242
- ```
243
-
244
- ### Pivot Table API
245
-
246
- ```typescript
247
- // Add fields to different areas
248
- pivot.addRowField(fieldName: string): PivotTable
249
- pivot.addColumnField(fieldName: string): PivotTable
250
- pivot.addValueField(fieldName: string, aggregation?: AggregationType, displayName?: string): PivotTable
251
- pivot.addFilterField(fieldName: string): PivotTable
252
-
253
- // Aggregation types: 'sum' | 'count' | 'average' | 'min' | 'max'
254
-
255
- // Sort a row or column field
256
- pivot.sortField(fieldName: string, order: 'asc' | 'desc'): PivotTable
257
-
258
- // Filter field values
259
- pivot.filterField(fieldName: string, filter: { include?: string[] } | { exclude?: string[] }): PivotTable
260
- ```
261
-
262
168
  ## Creating Sheets from Data
263
169
 
264
170
  Create sheets directly from arrays of objects with `addSheetFromData`:
@@ -320,7 +226,7 @@ const data = sheet.toJson();
320
226
  // [{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }]
321
227
 
322
228
  // Using custom field names (first row is data, not headers)
323
- const data2 = sheet.toJson({
229
+ const data = sheet.toJson({
324
230
  fields: ['name', 'age', 'city'],
325
231
  });
326
232
 
@@ -332,26 +238,21 @@ interface Person {
332
238
  const people = sheet.toJson<Person>();
333
239
 
334
240
  // Starting from a specific position
335
- const data3 = sheet.toJson({
241
+ const data = sheet.toJson({
336
242
  startRow: 2, // Skip first 2 rows (0-based)
337
243
  startCol: 1, // Start from column B
338
244
  });
339
245
 
340
246
  // Limiting the range
341
- const data4 = sheet.toJson({
247
+ const data = sheet.toJson({
342
248
  endRow: 10, // Stop at row 11 (0-based, inclusive)
343
249
  endCol: 3, // Only read columns A-D
344
250
  });
345
251
 
346
252
  // Continue past empty rows
347
- const data5 = sheet.toJson({
253
+ const data = sheet.toJson({
348
254
  stopOnEmptyRow: false, // Default is true
349
255
  });
350
-
351
- // Control how dates are serialized
352
- const data6 = sheet.toJson({
353
- dateHandling: 'isoString', // 'jsDate' | 'excelSerial' | 'isoString'
354
- });
355
256
  ```
356
257
 
357
258
  ### Roundtrip Example
@@ -376,24 +277,11 @@ const readData = sheet.toJson();
376
277
  ## Saving
377
278
 
378
279
  ```typescript
379
- // Load from file
380
- const wb = await Workbook.fromFile('template.xlsx');
381
-
382
- // Or load from buffer
383
- const buffer = await fetch('https://example.com/file.xlsx').then((r) => r.arrayBuffer());
384
- const wb2 = await Workbook.fromBuffer(new Uint8Array(buffer));
385
-
386
- // Read data
387
- const sheet = wb.sheet('Sheet1');
388
- console.log(sheet.cell('A1').value); // The cell value
389
- console.log(sheet.cell('A1').formula); // The formula (if any)
390
- console.log(sheet.cell('A1').type); // 'string' | 'number' | 'boolean' | 'date' | 'error' | 'empty'
280
+ // Save to file
281
+ await wb.toFile('output.xlsx');
391
282
 
392
- // Check if a cell exists without creating it
393
- const existingCell = sheet.getCellIfExists('A1');
394
- if (existingCell) {
395
- console.log(existingCell.value);
396
- }
283
+ // Save to buffer (Uint8Array)
284
+ const buffer = await wb.toBuffer();
397
285
  ```
398
286
 
399
287
  ## Type Definitions
@@ -442,121 +330,9 @@ interface SheetToJsonConfig {
442
330
  endRow?: number;
443
331
  endCol?: number;
444
332
  stopOnEmptyRow?: boolean; // Default: true
445
- dateHandling?: 'jsDate' | 'excelSerial' | 'isoString'; // Default: 'jsDate'
446
- }
447
-
448
- // Pivot table configuration
449
- interface PivotTableConfig {
450
- name: string;
451
- source: string; // e.g., "Sheet1!A1:D100"
452
- target: string; // e.g., "Sheet2!A3"
453
- refreshOnLoad?: boolean; // Default: true
454
- }
455
-
456
- type AggregationType = 'sum' | 'count' | 'average' | 'min' | 'max';
457
- type PivotSortOrder = 'asc' | 'desc';
458
- interface PivotFieldFilter {
459
- include?: string[];
460
- exclude?: string[];
461
333
  }
462
334
  ```
463
335
 
464
- ## Address Utilities
465
-
466
- Helper functions for working with Excel cell addresses:
467
-
468
- ```typescript
469
- import {
470
- colToLetter,
471
- letterToCol,
472
- parseAddress,
473
- toAddress,
474
- parseRange,
475
- toRange,
476
- normalizeRange,
477
- isInRange,
478
- } from '@niicojs/excel';
479
-
480
- // Convert column index to letter (0-based)
481
- colToLetter(0); // 'A'
482
- colToLetter(25); // 'Z'
483
- colToLetter(26); // 'AA'
484
-
485
- // Convert column letter to index (0-based)
486
- letterToCol('A'); // 0
487
- letterToCol('Z'); // 25
488
- letterToCol('AA'); // 26
489
-
490
- // Parse cell address to row/col
491
- parseAddress('B3'); // { row: 2, col: 1 }
492
- parseAddress('$A$1'); // { row: 0, col: 0 } (absolute refs supported)
493
-
494
- // Convert row/col to address
495
- toAddress(0, 0); // 'A1'
496
- toAddress(9, 2); // 'C10'
497
-
498
- // Parse range string
499
- parseRange('A1:C10'); // { start: { row: 0, col: 0 }, end: { row: 9, col: 2 } }
500
-
501
- // Convert range object to string
502
- toRange({ start: { row: 0, col: 0 }, end: { row: 9, col: 2 } }); // 'A1:C10'
503
-
504
- // Normalize range (ensure start is top-left, end is bottom-right)
505
- normalizeRange({ start: { row: 5, col: 3 }, end: { row: 0, col: 0 } });
506
- // { start: { row: 0, col: 0 }, end: { row: 5, col: 3 } }
507
-
508
- // Check if address is within a range
509
- isInRange({ row: 2, col: 1 }, { start: { row: 0, col: 0 }, end: { row: 5, col: 5 } }); // true
510
- isInRange({ row: 10, col: 0 }, { start: { row: 0, col: 0 }, end: { row: 5, col: 5 } }); // false
511
- ```
512
-
513
- ## Style Schema
514
-
515
- Supported style properties (CellStyle):
516
-
517
- ```typescript
518
- interface CellStyle {
519
- bold?: boolean;
520
- italic?: boolean;
521
- underline?: boolean | 'single' | 'double';
522
- strike?: boolean;
523
- fontSize?: number;
524
- fontName?: string;
525
- fontColor?: string; // Hex (RGB/RRGGBB/AARRGGBB)
526
- fill?: string; // Hex (RGB/RRGGBB/AARRGGBB)
527
- border?: {
528
- top?: 'thin' | 'medium' | 'thick' | 'double' | 'dotted' | 'dashed';
529
- bottom?: 'thin' | 'medium' | 'thick' | 'double' | 'dotted' | 'dashed';
530
- left?: 'thin' | 'medium' | 'thick' | 'double' | 'dotted' | 'dashed';
531
- right?: 'thin' | 'medium' | 'thick' | 'double' | 'dotted' | 'dashed';
532
- };
533
- alignment?: {
534
- horizontal?: 'left' | 'center' | 'right' | 'justify';
535
- vertical?: 'top' | 'middle' | 'bottom';
536
- wrapText?: boolean;
537
- textRotation?: number;
538
- };
539
- numberFormat?: string; // Excel format code
540
- }
541
- ```
542
-
543
- ## Performance and Large Files
544
-
545
- Tips for large sheets and high-volume writes:
546
-
547
- - Prefer `addSheetFromData` for bulk writes when possible.
548
- - Use `range.getValues({ createMissing: false })` to avoid creating empty cells during reads.
549
- - Keep shared strings small: prefer numbers/booleans where applicable.
550
- - Avoid frequent `toBuffer()` calls in loops; batch writes and serialize once.
551
-
552
- ## Limitations
553
-
554
- The library focuses on preserving existing structure and editing common parts of workbooks.
555
-
556
- - Chart editing is not supported (charts are preserved only).
557
- - Conditional formatting and data validation are preserved but not editable yet.
558
- - Some advanced Excel features (sparklines, slicers, macros) are preserved only.
559
-
560
336
  ## Format Preservation
561
337
 
562
338
  When modifying existing Excel files, this library preserves: