han-excel-builder 1.1.0 → 1.1.1
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/README.md +290 -290
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
1
|
# Han Excel Builder
|
|
2
2
|
|
|
3
|
-
🚀 **
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## ✨
|
|
8
|
-
|
|
9
|
-
### 📊
|
|
10
|
-
- ✅ **
|
|
11
|
-
- ✅ **
|
|
12
|
-
- ✅ **Headers
|
|
13
|
-
- ✅ **
|
|
14
|
-
|
|
15
|
-
### 📈
|
|
16
|
-
- ✅ **STRING** -
|
|
17
|
-
- ✅ **NUMBER** -
|
|
18
|
-
- ✅ **BOOLEAN** -
|
|
19
|
-
- ✅ **DATE** -
|
|
20
|
-
- ✅ **PERCENTAGE** -
|
|
21
|
-
- ✅ **CURRENCY** -
|
|
22
|
-
- ✅ **LINK** -
|
|
23
|
-
- ✅ **FORMULA** -
|
|
24
|
-
|
|
25
|
-
### 🎨
|
|
26
|
-
- ✅ **API
|
|
27
|
-
- ✅ **
|
|
28
|
-
- ✅ **
|
|
29
|
-
- ✅ **
|
|
30
|
-
- ✅ **
|
|
31
|
-
- ✅ **
|
|
32
|
-
- ✅ **
|
|
33
|
-
- ✅ **
|
|
34
|
-
|
|
35
|
-
### 🔧
|
|
36
|
-
- ✅ **TypeScript First** -
|
|
37
|
-
- ✅ **
|
|
38
|
-
- ✅ **
|
|
39
|
-
- ✅ **Metadata** -
|
|
40
|
-
- ✅ **
|
|
41
|
-
- ✅ **
|
|
42
|
-
- ✅ **
|
|
43
|
-
- ✅ **
|
|
44
|
-
- ✅ **
|
|
45
|
-
|
|
46
|
-
## 📦
|
|
3
|
+
🚀 **Advanced Excel file generator with TypeScript support, comprehensive styling, and optimized performance**
|
|
4
|
+
|
|
5
|
+
A modern, fully-typed library for creating complex Excel reports with multiple worksheets, advanced styling, and high performance.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
### 📊 Data Structure
|
|
10
|
+
- ✅ **Multiple Worksheets** - Create complex workbooks with multiple sheets
|
|
11
|
+
- ✅ **Multiple Tables per Sheet** - Create multiple independent tables in a single sheet
|
|
12
|
+
- ✅ **Nested Headers** - Full support for headers with multiple nesting levels
|
|
13
|
+
- ✅ **Hierarchical Data** - Support for data with children structure (nested data)
|
|
14
|
+
|
|
15
|
+
### 📈 Data Types
|
|
16
|
+
- ✅ **STRING** - Text values
|
|
17
|
+
- ✅ **NUMBER** - Numeric values
|
|
18
|
+
- ✅ **BOOLEAN** - True/false values
|
|
19
|
+
- ✅ **DATE** - Date values
|
|
20
|
+
- ✅ **PERCENTAGE** - Percentage values
|
|
21
|
+
- ✅ **CURRENCY** - Currency values
|
|
22
|
+
- ✅ **LINK** - Hyperlinks with customizable text
|
|
23
|
+
- ✅ **FORMULA** - Excel formulas
|
|
24
|
+
|
|
25
|
+
### 🎨 Advanced Styling
|
|
26
|
+
- ✅ **Fluent API** - StyleBuilder with chainable methods
|
|
27
|
+
- ✅ **Fonts** - Full control over name, size, color, bold, italic, underline
|
|
28
|
+
- ✅ **Colors** - Backgrounds, text colors with support for hex, RGB and themes
|
|
29
|
+
- ✅ **Borders** - Customizable borders on all sides with multiple styles
|
|
30
|
+
- ✅ **Alignment** - Horizontal (left, center, right, justify) and vertical (top, middle, bottom)
|
|
31
|
+
- ✅ **Text** - Text wrapping, shrink to fit, text rotation
|
|
32
|
+
- ✅ **Number Formats** - Multiple predefined and custom formats
|
|
33
|
+
- ✅ **Alternating Rows** - Support for alternating stripes in tables
|
|
34
|
+
|
|
35
|
+
### 🔧 Advanced Features
|
|
36
|
+
- ✅ **TypeScript First** - Complete type safety with comprehensive interfaces
|
|
37
|
+
- ✅ **Event System** - EventEmitter to monitor the build process
|
|
38
|
+
- ✅ **Validation** - Robust data validation system
|
|
39
|
+
- ✅ **Metadata** - Full support for workbook metadata (author, title, description, etc.)
|
|
40
|
+
- ✅ **Multiple Export Formats** - Direct download, Buffer, Blob
|
|
41
|
+
- ✅ **Excel Reading** - Read Excel files and convert to JSON
|
|
42
|
+
- ✅ **Hyperlinks** - Create links with customizable text
|
|
43
|
+
- ✅ **Cell Merging** - Horizontal and vertical cell merging
|
|
44
|
+
- ✅ **Custom Dimensions** - Customizable column width and row height
|
|
45
|
+
|
|
46
|
+
## 📦 Installation
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
49
|
npm install han-excel-builder
|
|
50
|
-
#
|
|
50
|
+
# or
|
|
51
51
|
yarn add han-excel-builder
|
|
52
|
-
#
|
|
52
|
+
# or
|
|
53
53
|
pnpm add han-excel-builder
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
## 🚀
|
|
56
|
+
## 🚀 Quick Start
|
|
57
57
|
|
|
58
|
-
###
|
|
58
|
+
### Basic Example
|
|
59
59
|
|
|
60
60
|
```typescript
|
|
61
61
|
import { ExcelBuilder, CellType, NumberFormat, StyleBuilder, BorderStyle } from 'han-excel-builder';
|
|
62
62
|
|
|
63
|
-
//
|
|
63
|
+
// Create a simple report
|
|
64
64
|
const builder = new ExcelBuilder({
|
|
65
65
|
metadata: {
|
|
66
|
-
title: '
|
|
67
|
-
author: '
|
|
68
|
-
description: '
|
|
66
|
+
title: 'Sales Report',
|
|
67
|
+
author: 'My Company',
|
|
68
|
+
description: 'Monthly sales report'
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
-
const worksheet = builder.addWorksheet('
|
|
72
|
+
const worksheet = builder.addWorksheet('Sales');
|
|
73
73
|
|
|
74
|
-
//
|
|
74
|
+
// Add main header
|
|
75
75
|
worksheet.addHeader({
|
|
76
76
|
key: 'title',
|
|
77
|
-
value: '
|
|
77
|
+
value: 'Monthly Sales Report',
|
|
78
78
|
type: CellType.STRING,
|
|
79
79
|
mergeCell: true,
|
|
80
80
|
styles: new StyleBuilder()
|
|
@@ -88,11 +88,11 @@ worksheet.addHeader({
|
|
|
88
88
|
.build()
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
//
|
|
91
|
+
// Add sub-headers
|
|
92
92
|
worksheet.addSubHeaders([
|
|
93
93
|
{
|
|
94
|
-
key: '
|
|
95
|
-
value: '
|
|
94
|
+
key: 'product',
|
|
95
|
+
value: 'Product',
|
|
96
96
|
type: CellType.STRING,
|
|
97
97
|
colWidth: 20,
|
|
98
98
|
styles: new StyleBuilder()
|
|
@@ -104,8 +104,8 @@ worksheet.addSubHeaders([
|
|
|
104
104
|
.build()
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
|
-
key: '
|
|
108
|
-
value: '
|
|
107
|
+
key: 'sales',
|
|
108
|
+
value: 'Sales',
|
|
109
109
|
type: CellType.CURRENCY,
|
|
110
110
|
colWidth: 15,
|
|
111
111
|
numberFormat: '$#,##0',
|
|
@@ -119,43 +119,43 @@ worksheet.addSubHeaders([
|
|
|
119
119
|
}
|
|
120
120
|
]);
|
|
121
121
|
|
|
122
|
-
//
|
|
122
|
+
// Add data
|
|
123
123
|
worksheet.addRow([
|
|
124
124
|
{
|
|
125
|
-
key: '
|
|
126
|
-
value: '
|
|
125
|
+
key: 'product-1',
|
|
126
|
+
value: 'Product A',
|
|
127
127
|
type: CellType.STRING,
|
|
128
|
-
header: '
|
|
128
|
+
header: 'Product'
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
|
-
key: '
|
|
131
|
+
key: 'sales-1',
|
|
132
132
|
value: 1500.50,
|
|
133
133
|
type: CellType.CURRENCY,
|
|
134
|
-
header: '
|
|
134
|
+
header: 'Sales',
|
|
135
135
|
numberFormat: '$#,##0.00'
|
|
136
136
|
}
|
|
137
137
|
]);
|
|
138
138
|
|
|
139
|
-
//
|
|
140
|
-
await builder.generateAndDownload('
|
|
139
|
+
// Generate and download
|
|
140
|
+
await builder.generateAndDownload('sales-report.xlsx');
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
## 📚
|
|
143
|
+
## 📚 API Documentation
|
|
144
144
|
|
|
145
|
-
###
|
|
145
|
+
### Core Classes
|
|
146
146
|
|
|
147
147
|
#### `ExcelBuilder`
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
Main class for creating Excel workbooks.
|
|
150
150
|
|
|
151
151
|
```typescript
|
|
152
152
|
const builder = new ExcelBuilder({
|
|
153
153
|
metadata: {
|
|
154
|
-
title: '
|
|
155
|
-
author: '
|
|
156
|
-
company: '
|
|
157
|
-
description: '
|
|
158
|
-
keywords: 'excel,
|
|
154
|
+
title: 'My Report',
|
|
155
|
+
author: 'My Name',
|
|
156
|
+
company: 'My Company',
|
|
157
|
+
description: 'Report description',
|
|
158
|
+
keywords: 'excel, report, data',
|
|
159
159
|
created: new Date(),
|
|
160
160
|
modified: new Date()
|
|
161
161
|
},
|
|
@@ -166,20 +166,20 @@ const builder = new ExcelBuilder({
|
|
|
166
166
|
maxColumnsPerWorksheet: 16384
|
|
167
167
|
});
|
|
168
168
|
|
|
169
|
-
//
|
|
170
|
-
builder.addWorksheet(name, config); //
|
|
171
|
-
builder.getWorksheet(name); //
|
|
172
|
-
builder.removeWorksheet(name); //
|
|
173
|
-
builder.setCurrentWorksheet(name); //
|
|
174
|
-
builder.build(options); //
|
|
175
|
-
builder.generateAndDownload(fileName); //
|
|
176
|
-
builder.toBuffer(options); //
|
|
177
|
-
builder.toBlob(options); //
|
|
178
|
-
builder.validate(); //
|
|
179
|
-
builder.clear(); //
|
|
180
|
-
builder.getStats(); //
|
|
181
|
-
|
|
182
|
-
//
|
|
169
|
+
// Main methods
|
|
170
|
+
builder.addWorksheet(name, config); // Add a worksheet
|
|
171
|
+
builder.getWorksheet(name); // Get a worksheet
|
|
172
|
+
builder.removeWorksheet(name); // Remove a worksheet
|
|
173
|
+
builder.setCurrentWorksheet(name); // Set current worksheet
|
|
174
|
+
builder.build(options); // Build and get ArrayBuffer
|
|
175
|
+
builder.generateAndDownload(fileName); // Generate and download
|
|
176
|
+
builder.toBuffer(options); // Get as Buffer
|
|
177
|
+
builder.toBlob(options); // Get as Blob
|
|
178
|
+
builder.validate(); // Validate workbook
|
|
179
|
+
builder.clear(); // Clear all worksheets
|
|
180
|
+
builder.getStats(); // Get statistics
|
|
181
|
+
|
|
182
|
+
// Event system
|
|
183
183
|
builder.on(eventType, listener);
|
|
184
184
|
builder.off(eventType, listenerId);
|
|
185
185
|
builder.removeAllListeners(eventType);
|
|
@@ -187,77 +187,77 @@ builder.removeAllListeners(eventType);
|
|
|
187
187
|
|
|
188
188
|
#### `ExcelReader`
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
Class for reading Excel files and converting them to JSON with 3 different output formats.
|
|
191
191
|
|
|
192
|
-
**
|
|
193
|
-
- `worksheet` (
|
|
194
|
-
- `detailed` -
|
|
195
|
-
- `flat` -
|
|
192
|
+
**Available formats:**
|
|
193
|
+
- `worksheet` (default) - Complete structure with sheets, rows and cells
|
|
194
|
+
- `detailed` - Each cell with position information (text, column, row)
|
|
195
|
+
- `flat` - Just the data, without structure
|
|
196
196
|
|
|
197
197
|
```typescript
|
|
198
198
|
import { ExcelReader, OutputFormat } from 'han-excel-builder';
|
|
199
199
|
|
|
200
|
-
// =====
|
|
201
|
-
//
|
|
200
|
+
// ===== FORMAT 1: WORKSHEET (default) =====
|
|
201
|
+
// Complete structure organized by sheets
|
|
202
202
|
const result = await ExcelReader.fromFile(file, {
|
|
203
|
-
outputFormat: OutputFormat.WORKSHEET, //
|
|
203
|
+
outputFormat: OutputFormat.WORKSHEET, // or 'worksheet'
|
|
204
204
|
useFirstRowAsHeaders: true
|
|
205
205
|
});
|
|
206
206
|
|
|
207
207
|
if (result.success) {
|
|
208
208
|
const workbook = result.data;
|
|
209
|
-
// workbook.sheets[] - Array
|
|
210
|
-
// workbook.sheets[0].rows[] - Array
|
|
211
|
-
// workbook.sheets[0].rows[0].cells[] - Array
|
|
212
|
-
// workbook.sheets[0].rows[0].data -
|
|
209
|
+
// workbook.sheets[] - Array of sheets
|
|
210
|
+
// workbook.sheets[0].rows[] - Array of rows
|
|
211
|
+
// workbook.sheets[0].rows[0].cells[] - Array of cells
|
|
212
|
+
// workbook.sheets[0].rows[0].data - Object with data (if useFirstRowAsHeaders)
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
// =====
|
|
216
|
-
//
|
|
215
|
+
// ===== FORMAT 2: DETAILED =====
|
|
216
|
+
// Each cell with position information
|
|
217
217
|
const result = await ExcelReader.fromFile(file, {
|
|
218
|
-
outputFormat: OutputFormat.DETAILED, //
|
|
218
|
+
outputFormat: OutputFormat.DETAILED, // or 'detailed'
|
|
219
219
|
includeFormatting: true
|
|
220
220
|
});
|
|
221
221
|
|
|
222
222
|
if (result.success) {
|
|
223
223
|
const detailed = result.data;
|
|
224
|
-
// detailed.cells[] - Array
|
|
225
|
-
// - value:
|
|
226
|
-
// - text:
|
|
227
|
-
// - column:
|
|
228
|
-
// - columnLetter:
|
|
229
|
-
// - row:
|
|
230
|
-
// - reference:
|
|
231
|
-
// - sheet:
|
|
224
|
+
// detailed.cells[] - Array of all cells with:
|
|
225
|
+
// - value: cell value
|
|
226
|
+
// - text: cell text
|
|
227
|
+
// - column: column number (1-based)
|
|
228
|
+
// - columnLetter: column letter (A, B, C...)
|
|
229
|
+
// - row: row number (1-based)
|
|
230
|
+
// - reference: cell reference (A1, B2...)
|
|
231
|
+
// - sheet: sheet name
|
|
232
232
|
detailed.cells.forEach(cell => {
|
|
233
233
|
console.log(`${cell.sheet}!${cell.reference}: ${cell.text}`);
|
|
234
234
|
});
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
// =====
|
|
238
|
-
//
|
|
237
|
+
// ===== FORMAT 3: FLAT =====
|
|
238
|
+
// Just the data, without structure
|
|
239
239
|
const result = await ExcelReader.fromFile(file, {
|
|
240
|
-
outputFormat: OutputFormat.FLAT, //
|
|
240
|
+
outputFormat: OutputFormat.FLAT, // or 'flat'
|
|
241
241
|
useFirstRowAsHeaders: true
|
|
242
242
|
});
|
|
243
243
|
|
|
244
244
|
if (result.success) {
|
|
245
245
|
const flat = result.data;
|
|
246
246
|
|
|
247
|
-
//
|
|
247
|
+
// If single sheet:
|
|
248
248
|
if ('data' in flat) {
|
|
249
|
-
// flat.data[] - Array
|
|
250
|
-
// flat.headers[] - Headers (
|
|
249
|
+
// flat.data[] - Array of objects or arrays
|
|
250
|
+
// flat.headers[] - Headers (if useFirstRowAsHeaders)
|
|
251
251
|
flat.data.forEach(row => {
|
|
252
|
-
console.log(row); // {
|
|
252
|
+
console.log(row); // { Product: 'A', Price: 100 } or ['A', 100]
|
|
253
253
|
});
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
//
|
|
256
|
+
// If multiple sheets:
|
|
257
257
|
if ('sheets' in flat) {
|
|
258
|
-
// flat.sheets['
|
|
258
|
+
// flat.sheets['SheetName'].data[] - Data by sheet
|
|
259
259
|
Object.keys(flat.sheets).forEach(sheetName => {
|
|
260
|
-
console.log(`
|
|
260
|
+
console.log(`Sheet: ${sheetName}`);
|
|
261
261
|
flat.sheets[sheetName].data.forEach(row => {
|
|
262
262
|
console.log(row);
|
|
263
263
|
});
|
|
@@ -265,25 +265,25 @@ if (result.success) {
|
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
// =====
|
|
269
|
-
//
|
|
268
|
+
// ===== USING MAPPER TO TRANSFORM DATA =====
|
|
269
|
+
// The mapper allows transforming the response before returning it
|
|
270
270
|
const result = await ExcelReader.fromFile(file, {
|
|
271
271
|
outputFormat: OutputFormat.WORKSHEET,
|
|
272
272
|
useFirstRowAsHeaders: true,
|
|
273
|
-
// Mapper
|
|
273
|
+
// Mapper receives the payload and returns the transformation
|
|
274
274
|
mapper: (data) => {
|
|
275
|
-
//
|
|
275
|
+
// Transform data according to needs
|
|
276
276
|
const transformed = {
|
|
277
277
|
totalSheets: data.totalSheets,
|
|
278
278
|
sheets: data.sheets.map(sheet => ({
|
|
279
279
|
name: sheet.name,
|
|
280
|
-
//
|
|
280
|
+
// Convert rows to objects with transformed data
|
|
281
281
|
rows: sheet.rows.map(row => {
|
|
282
282
|
if (row.data) {
|
|
283
|
-
//
|
|
283
|
+
// Transform each field
|
|
284
284
|
return {
|
|
285
285
|
...row.data,
|
|
286
|
-
//
|
|
286
|
+
// Add calculated fields
|
|
287
287
|
total: Object.values(row.data).reduce((sum, val) => {
|
|
288
288
|
return sum + (typeof val === 'number' ? val : 0);
|
|
289
289
|
}, 0)
|
|
@@ -297,16 +297,16 @@ const result = await ExcelReader.fromFile(file, {
|
|
|
297
297
|
}
|
|
298
298
|
});
|
|
299
299
|
|
|
300
|
-
//
|
|
300
|
+
// Example with FLAT format and mapper
|
|
301
301
|
const result = await ExcelReader.fromFile(file, {
|
|
302
302
|
outputFormat: OutputFormat.FLAT,
|
|
303
303
|
useFirstRowAsHeaders: true,
|
|
304
304
|
mapper: (data) => {
|
|
305
|
-
//
|
|
305
|
+
// If flat format from single sheet
|
|
306
306
|
if ('data' in data && Array.isArray(data.data)) {
|
|
307
307
|
return data.data.map((row: any) => ({
|
|
308
308
|
...row,
|
|
309
|
-
//
|
|
309
|
+
// Add validations or transformations
|
|
310
310
|
isValid: Object.values(row).every(val => val !== null && val !== undefined)
|
|
311
311
|
}));
|
|
312
312
|
}
|
|
@@ -314,11 +314,11 @@ const result = await ExcelReader.fromFile(file, {
|
|
|
314
314
|
}
|
|
315
315
|
});
|
|
316
316
|
|
|
317
|
-
//
|
|
317
|
+
// Example with DETAILED format and mapper
|
|
318
318
|
const result = await ExcelReader.fromFile(file, {
|
|
319
319
|
outputFormat: OutputFormat.DETAILED,
|
|
320
320
|
mapper: (data) => {
|
|
321
|
-
//
|
|
321
|
+
// Group cells by sheet
|
|
322
322
|
const groupedBySheet: Record<string, typeof data.cells> = {};
|
|
323
323
|
data.cells.forEach(cell => {
|
|
324
324
|
if (!groupedBySheet[cell.sheet]) {
|
|
@@ -336,38 +336,38 @@ const result = await ExcelReader.fromFile(file, {
|
|
|
336
336
|
});
|
|
337
337
|
```
|
|
338
338
|
|
|
339
|
-
**
|
|
339
|
+
**Reading options:**
|
|
340
340
|
|
|
341
341
|
```typescript
|
|
342
342
|
interface IExcelReaderOptions {
|
|
343
|
-
outputFormat?: 'worksheet' | 'detailed' | 'flat' | OutputFormat; //
|
|
344
|
-
mapper?: (data: IJsonWorkbook | IDetailedFormat | IFlatFormat | IFlatFormatMultiSheet) => unknown; //
|
|
345
|
-
useFirstRowAsHeaders?: boolean; //
|
|
346
|
-
includeEmptyRows?: boolean; //
|
|
347
|
-
headers?: string[] | Record<number, string>; //
|
|
348
|
-
sheetName?: string | number; //
|
|
349
|
-
startRow?: number; //
|
|
350
|
-
endRow?: number; //
|
|
351
|
-
startColumn?: number; //
|
|
352
|
-
endColumn?: number; //
|
|
353
|
-
includeFormatting?: boolean; //
|
|
354
|
-
includeFormulas?: boolean; //
|
|
355
|
-
datesAsISO?: boolean; //
|
|
343
|
+
outputFormat?: 'worksheet' | 'detailed' | 'flat' | OutputFormat; // Output format
|
|
344
|
+
mapper?: (data: IJsonWorkbook | IDetailedFormat | IFlatFormat | IFlatFormatMultiSheet) => unknown; // Function to transform the response
|
|
345
|
+
useFirstRowAsHeaders?: boolean; // Use first row as headers
|
|
346
|
+
includeEmptyRows?: boolean; // Include empty rows
|
|
347
|
+
headers?: string[] | Record<number, string>; // Custom headers
|
|
348
|
+
sheetName?: string | number; // Sheet name or index
|
|
349
|
+
startRow?: number; // Starting row (1-based)
|
|
350
|
+
endRow?: number; // Ending row (1-based)
|
|
351
|
+
startColumn?: number; // Starting column (1-based)
|
|
352
|
+
endColumn?: number; // Ending column (1-based)
|
|
353
|
+
includeFormatting?: boolean; // Include formatting information
|
|
354
|
+
includeFormulas?: boolean; // Include formulas
|
|
355
|
+
datesAsISO?: boolean; // Convert dates to ISO string
|
|
356
356
|
}
|
|
357
357
|
```
|
|
358
358
|
|
|
359
|
-
**
|
|
359
|
+
**Output formats:**
|
|
360
360
|
|
|
361
|
-
- **`worksheet`** (
|
|
362
|
-
- **`detailed`**: Array
|
|
363
|
-
- **`flat`**:
|
|
361
|
+
- **`worksheet`** (default): Complete structure with sheets, rows and cells
|
|
362
|
+
- **`detailed`**: Array of cells with position information (text, column, row, reference)
|
|
363
|
+
- **`flat`**: Just the data, without structure (flat arrays or objects)
|
|
364
364
|
|
|
365
365
|
#### `Worksheet`
|
|
366
366
|
|
|
367
|
-
|
|
367
|
+
Represents an individual worksheet.
|
|
368
368
|
|
|
369
369
|
```typescript
|
|
370
|
-
const worksheet = builder.addWorksheet('
|
|
370
|
+
const worksheet = builder.addWorksheet('My Sheet', {
|
|
371
371
|
tabColor: '#FF0000',
|
|
372
372
|
defaultRowHeight: 20,
|
|
373
373
|
defaultColWidth: 15,
|
|
@@ -377,31 +377,31 @@ const worksheet = builder.addWorksheet('Mi Hoja', {
|
|
|
377
377
|
}
|
|
378
378
|
});
|
|
379
379
|
|
|
380
|
-
//
|
|
381
|
-
worksheet.addHeader(header); //
|
|
382
|
-
worksheet.addSubHeaders(headers); //
|
|
383
|
-
worksheet.addRow(row); //
|
|
384
|
-
worksheet.addFooter(footer); //
|
|
385
|
-
worksheet.addTable(config); //
|
|
386
|
-
worksheet.finalizeTable(); //
|
|
387
|
-
worksheet.getTable(name); //
|
|
388
|
-
worksheet.validate(); //
|
|
380
|
+
// Main methods
|
|
381
|
+
worksheet.addHeader(header); // Add main header
|
|
382
|
+
worksheet.addSubHeaders(headers); // Add sub-headers
|
|
383
|
+
worksheet.addRow(row); // Add data row
|
|
384
|
+
worksheet.addFooter(footer); // Add footer
|
|
385
|
+
worksheet.addTable(config); // Create new table
|
|
386
|
+
worksheet.finalizeTable(); // Finalize current table
|
|
387
|
+
worksheet.getTable(name); // Get table by name
|
|
388
|
+
worksheet.validate(); // Validate sheet
|
|
389
389
|
```
|
|
390
390
|
|
|
391
|
-
###
|
|
391
|
+
### Data Types
|
|
392
392
|
|
|
393
393
|
#### `CellType`
|
|
394
394
|
|
|
395
395
|
```typescript
|
|
396
396
|
enum CellType {
|
|
397
|
-
STRING = 'string', //
|
|
398
|
-
NUMBER = 'number', //
|
|
399
|
-
BOOLEAN = 'boolean', //
|
|
400
|
-
DATE = 'date', //
|
|
401
|
-
PERCENTAGE = 'percentage', //
|
|
402
|
-
CURRENCY = 'currency', //
|
|
403
|
-
LINK = 'link', //
|
|
404
|
-
FORMULA = 'formula' //
|
|
397
|
+
STRING = 'string', // Text
|
|
398
|
+
NUMBER = 'number', // Number
|
|
399
|
+
BOOLEAN = 'boolean', // True/False
|
|
400
|
+
DATE = 'date', // Date
|
|
401
|
+
PERCENTAGE = 'percentage', // Percentage
|
|
402
|
+
CURRENCY = 'currency', // Currency
|
|
403
|
+
LINK = 'link', // Hyperlink
|
|
404
|
+
FORMULA = 'formula' // Formula
|
|
405
405
|
}
|
|
406
406
|
```
|
|
407
407
|
|
|
@@ -423,15 +423,15 @@ enum NumberFormat {
|
|
|
423
423
|
}
|
|
424
424
|
```
|
|
425
425
|
|
|
426
|
-
###
|
|
426
|
+
### Styling
|
|
427
427
|
|
|
428
428
|
#### `StyleBuilder`
|
|
429
429
|
|
|
430
|
-
API
|
|
430
|
+
Fluent API for creating cell styles.
|
|
431
431
|
|
|
432
432
|
```typescript
|
|
433
433
|
const style = new StyleBuilder()
|
|
434
|
-
//
|
|
434
|
+
// Fonts
|
|
435
435
|
.fontName('Arial')
|
|
436
436
|
.fontSize(12)
|
|
437
437
|
.fontBold()
|
|
@@ -439,7 +439,7 @@ const style = new StyleBuilder()
|
|
|
439
439
|
.fontUnderline()
|
|
440
440
|
.fontColor('#FF0000')
|
|
441
441
|
|
|
442
|
-
//
|
|
442
|
+
// Backgrounds and borders
|
|
443
443
|
.backgroundColor('#FFFF00')
|
|
444
444
|
.border(BorderStyle.THIN, '#000000')
|
|
445
445
|
.borderTop(BorderStyle.MEDIUM, '#000000')
|
|
@@ -447,7 +447,7 @@ const style = new StyleBuilder()
|
|
|
447
447
|
.borderBottom(BorderStyle.THIN, '#000000')
|
|
448
448
|
.borderRight(BorderStyle.THIN, '#000000')
|
|
449
449
|
|
|
450
|
-
//
|
|
450
|
+
// Alignment
|
|
451
451
|
.centerAlign()
|
|
452
452
|
.leftAlign()
|
|
453
453
|
.rightAlign()
|
|
@@ -455,11 +455,11 @@ const style = new StyleBuilder()
|
|
|
455
455
|
.verticalAlign(VerticalAlignment.MIDDLE)
|
|
456
456
|
.wrapText()
|
|
457
457
|
|
|
458
|
-
//
|
|
458
|
+
// Formats
|
|
459
459
|
.numberFormat('$#,##0.00')
|
|
460
460
|
.striped()
|
|
461
461
|
|
|
462
|
-
//
|
|
462
|
+
// Conditional formatting
|
|
463
463
|
.conditionalFormat({
|
|
464
464
|
type: 'cellIs',
|
|
465
465
|
operator: 'greaterThan',
|
|
@@ -472,7 +472,7 @@ const style = new StyleBuilder()
|
|
|
472
472
|
|
|
473
473
|
.build();
|
|
474
474
|
|
|
475
|
-
//
|
|
475
|
+
// Alternative static method
|
|
476
476
|
const style2 = StyleBuilder.create()
|
|
477
477
|
.fontBold()
|
|
478
478
|
.fontSize(14)
|
|
@@ -499,28 +499,28 @@ enum BorderStyle {
|
|
|
499
499
|
}
|
|
500
500
|
```
|
|
501
501
|
|
|
502
|
-
## 🎯
|
|
502
|
+
## 🎯 Advanced Examples
|
|
503
503
|
|
|
504
|
-
###
|
|
504
|
+
### Multiple Tables in a Sheet
|
|
505
505
|
|
|
506
506
|
```typescript
|
|
507
507
|
import { ExcelBuilder, CellType, StyleBuilder, BorderStyle } from 'han-excel-builder';
|
|
508
508
|
|
|
509
509
|
const builder = new ExcelBuilder();
|
|
510
|
-
const worksheet = builder.addWorksheet('
|
|
510
|
+
const worksheet = builder.addWorksheet('Complete Report');
|
|
511
511
|
|
|
512
|
-
// =====
|
|
512
|
+
// ===== FIRST TABLE =====
|
|
513
513
|
worksheet.addTable({
|
|
514
|
-
name: '
|
|
514
|
+
name: 'Sales',
|
|
515
515
|
showBorders: true,
|
|
516
516
|
showStripes: true,
|
|
517
517
|
style: 'TableStyleLight1'
|
|
518
518
|
});
|
|
519
519
|
|
|
520
520
|
worksheet.addHeader({
|
|
521
|
-
key: 'header-
|
|
521
|
+
key: 'header-sales',
|
|
522
522
|
type: CellType.STRING,
|
|
523
|
-
value: '
|
|
523
|
+
value: 'SALES SUMMARY',
|
|
524
524
|
mergeCell: true,
|
|
525
525
|
styles: new StyleBuilder()
|
|
526
526
|
.fontBold()
|
|
@@ -532,29 +532,29 @@ worksheet.addHeader({
|
|
|
532
532
|
});
|
|
533
533
|
|
|
534
534
|
worksheet.addSubHeaders([
|
|
535
|
-
{ key: '
|
|
536
|
-
{ key: '
|
|
535
|
+
{ key: 'product', type: CellType.STRING, value: 'Product' },
|
|
536
|
+
{ key: 'sales', type: CellType.CURRENCY, value: 'Sales' }
|
|
537
537
|
]);
|
|
538
538
|
|
|
539
539
|
worksheet.addRow([
|
|
540
|
-
{ key: 'p1', type: CellType.STRING, value: '
|
|
541
|
-
{ key: 'v1', type: CellType.CURRENCY, value: 1500, header: '
|
|
540
|
+
{ key: 'p1', type: CellType.STRING, value: 'Product A', header: 'Product' },
|
|
541
|
+
{ key: 'v1', type: CellType.CURRENCY, value: 1500, header: 'Sales' }
|
|
542
542
|
]);
|
|
543
543
|
|
|
544
544
|
worksheet.finalizeTable();
|
|
545
545
|
|
|
546
|
-
// =====
|
|
546
|
+
// ===== SECOND TABLE =====
|
|
547
547
|
worksheet.addTable({
|
|
548
|
-
name: '
|
|
548
|
+
name: 'Employees',
|
|
549
549
|
showBorders: true,
|
|
550
550
|
showStripes: true,
|
|
551
551
|
style: 'TableStyleMedium1'
|
|
552
552
|
});
|
|
553
553
|
|
|
554
554
|
worksheet.addHeader({
|
|
555
|
-
key: 'header-
|
|
555
|
+
key: 'header-employees',
|
|
556
556
|
type: CellType.STRING,
|
|
557
|
-
value: 'TOP
|
|
557
|
+
value: 'TOP EMPLOYEES',
|
|
558
558
|
mergeCell: true,
|
|
559
559
|
styles: new StyleBuilder()
|
|
560
560
|
.fontBold()
|
|
@@ -566,13 +566,13 @@ worksheet.addHeader({
|
|
|
566
566
|
});
|
|
567
567
|
|
|
568
568
|
worksheet.addSubHeaders([
|
|
569
|
-
{ key: '
|
|
570
|
-
{ key: '
|
|
569
|
+
{ key: 'name', type: CellType.STRING, value: 'Name' },
|
|
570
|
+
{ key: 'sales', type: CellType.CURRENCY, value: 'Sales' }
|
|
571
571
|
]);
|
|
572
572
|
|
|
573
573
|
worksheet.addRow([
|
|
574
|
-
{ key: 'e1', type: CellType.STRING, value: '
|
|
575
|
-
{ key: 've1', type: CellType.CURRENCY, value: 150000, header: '
|
|
574
|
+
{ key: 'e1', type: CellType.STRING, value: 'John Doe', header: 'Name' },
|
|
575
|
+
{ key: 've1', type: CellType.CURRENCY, value: 150000, header: 'Sales' }
|
|
576
576
|
]);
|
|
577
577
|
|
|
578
578
|
worksheet.finalizeTable();
|
|
@@ -580,39 +580,39 @@ worksheet.finalizeTable();
|
|
|
580
580
|
await builder.generateAndDownload('multiple-tables.xlsx');
|
|
581
581
|
```
|
|
582
582
|
|
|
583
|
-
### Headers
|
|
583
|
+
### Nested Headers
|
|
584
584
|
|
|
585
585
|
```typescript
|
|
586
586
|
worksheet.addSubHeaders([
|
|
587
587
|
{
|
|
588
|
-
key: '
|
|
589
|
-
value: '
|
|
588
|
+
key: 'sales',
|
|
589
|
+
value: 'Sales',
|
|
590
590
|
type: CellType.STRING,
|
|
591
591
|
children: [
|
|
592
592
|
{
|
|
593
|
-
key: '
|
|
593
|
+
key: 'sales-q1',
|
|
594
594
|
value: 'Q1',
|
|
595
595
|
type: CellType.STRING
|
|
596
596
|
},
|
|
597
597
|
{
|
|
598
|
-
key: '
|
|
598
|
+
key: 'sales-q2',
|
|
599
599
|
value: 'Q2',
|
|
600
600
|
type: CellType.STRING
|
|
601
601
|
}
|
|
602
602
|
]
|
|
603
603
|
},
|
|
604
604
|
{
|
|
605
|
-
key: '
|
|
606
|
-
value: '
|
|
605
|
+
key: 'expenses',
|
|
606
|
+
value: 'Expenses',
|
|
607
607
|
type: CellType.STRING,
|
|
608
608
|
children: [
|
|
609
609
|
{
|
|
610
|
-
key: '
|
|
610
|
+
key: 'expenses-q1',
|
|
611
611
|
value: 'Q1',
|
|
612
612
|
type: CellType.STRING
|
|
613
613
|
},
|
|
614
614
|
{
|
|
615
|
-
key: '
|
|
615
|
+
key: 'expenses-q2',
|
|
616
616
|
value: 'Q2',
|
|
617
617
|
type: CellType.STRING
|
|
618
618
|
}
|
|
@@ -621,57 +621,57 @@ worksheet.addSubHeaders([
|
|
|
621
621
|
]);
|
|
622
622
|
```
|
|
623
623
|
|
|
624
|
-
###
|
|
624
|
+
### Hyperlinks
|
|
625
625
|
|
|
626
626
|
```typescript
|
|
627
627
|
worksheet.addRow([
|
|
628
628
|
{
|
|
629
629
|
key: 'link-1',
|
|
630
630
|
type: CellType.LINK,
|
|
631
|
-
value: '
|
|
631
|
+
value: 'Visit site',
|
|
632
632
|
link: 'https://example.com',
|
|
633
|
-
mask: '
|
|
634
|
-
header: '
|
|
633
|
+
mask: 'Click here', // Visible text
|
|
634
|
+
header: 'Link'
|
|
635
635
|
}
|
|
636
636
|
]);
|
|
637
637
|
```
|
|
638
638
|
|
|
639
|
-
###
|
|
639
|
+
### Data with Children (Hierarchical Structure)
|
|
640
640
|
|
|
641
641
|
```typescript
|
|
642
642
|
worksheet.addRow([
|
|
643
643
|
{
|
|
644
644
|
key: 'row-1',
|
|
645
645
|
type: CellType.STRING,
|
|
646
|
-
value: '
|
|
647
|
-
header: '
|
|
646
|
+
value: 'Main Category',
|
|
647
|
+
header: 'Category',
|
|
648
648
|
children: [
|
|
649
649
|
{
|
|
650
650
|
key: 'child-1',
|
|
651
651
|
type: CellType.STRING,
|
|
652
|
-
value: '
|
|
653
|
-
header: '
|
|
652
|
+
value: 'Subcategory 1',
|
|
653
|
+
header: 'Subcategory'
|
|
654
654
|
},
|
|
655
655
|
{
|
|
656
656
|
key: 'child-2',
|
|
657
657
|
type: CellType.NUMBER,
|
|
658
658
|
value: 100,
|
|
659
|
-
header: '
|
|
659
|
+
header: 'Value'
|
|
660
660
|
}
|
|
661
661
|
]
|
|
662
662
|
}
|
|
663
663
|
]);
|
|
664
664
|
```
|
|
665
665
|
|
|
666
|
-
###
|
|
666
|
+
### Conditional Formatting
|
|
667
667
|
|
|
668
668
|
```typescript
|
|
669
669
|
worksheet.addRow([
|
|
670
670
|
{
|
|
671
|
-
key: '
|
|
671
|
+
key: 'sales-1',
|
|
672
672
|
type: CellType.NUMBER,
|
|
673
673
|
value: 1500,
|
|
674
|
-
header: '
|
|
674
|
+
header: 'Sales',
|
|
675
675
|
styles: new StyleBuilder()
|
|
676
676
|
.conditionalFormat({
|
|
677
677
|
type: 'cellIs',
|
|
@@ -687,77 +687,77 @@ worksheet.addRow([
|
|
|
687
687
|
]);
|
|
688
688
|
```
|
|
689
689
|
|
|
690
|
-
###
|
|
690
|
+
### Multiple Worksheets
|
|
691
691
|
|
|
692
692
|
```typescript
|
|
693
693
|
const builder = new ExcelBuilder();
|
|
694
694
|
|
|
695
|
-
//
|
|
696
|
-
const summarySheet = builder.addWorksheet('
|
|
695
|
+
// Sheet 1: Summary
|
|
696
|
+
const summarySheet = builder.addWorksheet('Summary');
|
|
697
697
|
summarySheet.addHeader({
|
|
698
698
|
key: 'title',
|
|
699
|
-
value: '
|
|
699
|
+
value: 'Executive Summary',
|
|
700
700
|
type: CellType.STRING,
|
|
701
701
|
mergeCell: true
|
|
702
702
|
});
|
|
703
703
|
|
|
704
|
-
//
|
|
705
|
-
const detailsSheet = builder.addWorksheet('
|
|
704
|
+
// Sheet 2: Details
|
|
705
|
+
const detailsSheet = builder.addWorksheet('Details');
|
|
706
706
|
detailsSheet.addSubHeaders([
|
|
707
|
-
{ key: '
|
|
708
|
-
{ key: '
|
|
707
|
+
{ key: 'date', value: 'Date', type: CellType.DATE },
|
|
708
|
+
{ key: 'amount', value: 'Amount', type: CellType.CURRENCY }
|
|
709
709
|
]);
|
|
710
710
|
|
|
711
711
|
await builder.generateAndDownload('multi-sheet-report.xlsx');
|
|
712
712
|
```
|
|
713
713
|
|
|
714
|
-
###
|
|
714
|
+
### Export in Different Formats
|
|
715
715
|
|
|
716
716
|
```typescript
|
|
717
|
-
//
|
|
718
|
-
await builder.generateAndDownload('
|
|
717
|
+
// Direct download (browser)
|
|
718
|
+
await builder.generateAndDownload('report.xlsx');
|
|
719
719
|
|
|
720
|
-
//
|
|
720
|
+
// Get as Buffer
|
|
721
721
|
const bufferResult = await builder.toBuffer();
|
|
722
722
|
if (bufferResult.success) {
|
|
723
723
|
const buffer = bufferResult.data;
|
|
724
|
-
//
|
|
724
|
+
// Use buffer...
|
|
725
725
|
}
|
|
726
726
|
|
|
727
|
-
//
|
|
727
|
+
// Get as Blob
|
|
728
728
|
const blobResult = await builder.toBlob();
|
|
729
729
|
if (blobResult.success) {
|
|
730
730
|
const blob = blobResult.data;
|
|
731
|
-
//
|
|
731
|
+
// Use blob...
|
|
732
732
|
}
|
|
733
733
|
```
|
|
734
734
|
|
|
735
|
-
###
|
|
735
|
+
### Event System
|
|
736
736
|
|
|
737
737
|
```typescript
|
|
738
738
|
builder.on('build:started', (event) => {
|
|
739
|
-
console.log('
|
|
739
|
+
console.log('Build started');
|
|
740
740
|
});
|
|
741
741
|
|
|
742
742
|
builder.on('build:completed', (event) => {
|
|
743
|
-
console.log('
|
|
743
|
+
console.log('Build completed', event.data);
|
|
744
744
|
});
|
|
745
745
|
|
|
746
746
|
builder.on('build:error', (event) => {
|
|
747
|
-
console.error('
|
|
747
|
+
console.error('Build error', event.data.error);
|
|
748
748
|
});
|
|
749
749
|
|
|
750
|
-
//
|
|
750
|
+
// Remove listener
|
|
751
751
|
const listenerId = builder.on('build:started', handler);
|
|
752
752
|
builder.off('build:started', listenerId);
|
|
753
753
|
```
|
|
754
754
|
|
|
755
|
-
###
|
|
755
|
+
### Read Excel and Convert to JSON
|
|
756
756
|
|
|
757
757
|
```typescript
|
|
758
758
|
import { ExcelReader } from 'han-excel-builder';
|
|
759
759
|
|
|
760
|
-
//
|
|
760
|
+
// Read from a file (browser)
|
|
761
761
|
const fileInput = document.querySelector('input[type="file"]');
|
|
762
762
|
fileInput.addEventListener('change', async (e) => {
|
|
763
763
|
const file = (e.target as HTMLInputElement).files?.[0];
|
|
@@ -772,44 +772,44 @@ fileInput.addEventListener('change', async (e) => {
|
|
|
772
772
|
if (result.success) {
|
|
773
773
|
const workbook = result.data;
|
|
774
774
|
|
|
775
|
-
//
|
|
775
|
+
// Process each sheet
|
|
776
776
|
workbook.sheets.forEach(sheet => {
|
|
777
|
-
console.log(`
|
|
777
|
+
console.log(`Processing sheet: ${sheet.name}`);
|
|
778
778
|
|
|
779
|
-
//
|
|
779
|
+
// Convert to array of objects (if using headers)
|
|
780
780
|
const data = sheet.rows.map(row => row.data || {});
|
|
781
|
-
console.log('
|
|
781
|
+
console.log('Data:', data);
|
|
782
782
|
});
|
|
783
783
|
}
|
|
784
784
|
});
|
|
785
785
|
|
|
786
|
-
//
|
|
786
|
+
// Read from ArrayBuffer (from API)
|
|
787
787
|
async function readExcelFromAPI() {
|
|
788
788
|
const response = await fetch('/api/excel-file');
|
|
789
789
|
const buffer = await response.arrayBuffer();
|
|
790
790
|
|
|
791
791
|
const result = await ExcelReader.fromBuffer(buffer, {
|
|
792
792
|
useFirstRowAsHeaders: true,
|
|
793
|
-
sheetName: '
|
|
793
|
+
sheetName: 'Sales' // Read only 'Sales' sheet
|
|
794
794
|
});
|
|
795
795
|
|
|
796
796
|
if (result.success) {
|
|
797
797
|
const sheet = result.data.sheets[0];
|
|
798
|
-
const
|
|
799
|
-
return
|
|
798
|
+
const sales = sheet.rows.map(row => row.data);
|
|
799
|
+
return sales;
|
|
800
800
|
}
|
|
801
801
|
}
|
|
802
802
|
|
|
803
|
-
//
|
|
803
|
+
// Read from path (Node.js)
|
|
804
804
|
async function readExcelFromPath() {
|
|
805
|
-
const result = await ExcelReader.fromPath('./
|
|
805
|
+
const result = await ExcelReader.fromPath('./report.xlsx', {
|
|
806
806
|
useFirstRowAsHeaders: true,
|
|
807
|
-
startRow: 2, //
|
|
807
|
+
startRow: 2, // Skip header
|
|
808
808
|
includeFormulas: true
|
|
809
809
|
});
|
|
810
810
|
|
|
811
811
|
if (result.success) {
|
|
812
|
-
console.log(`
|
|
812
|
+
console.log(`Processing time: ${result.processingTime}ms`);
|
|
813
813
|
return result.data;
|
|
814
814
|
}
|
|
815
815
|
}
|
|
@@ -818,49 +818,49 @@ async function readExcelFromPath() {
|
|
|
818
818
|
## 🧪 Testing
|
|
819
819
|
|
|
820
820
|
```bash
|
|
821
|
-
#
|
|
821
|
+
# Run tests
|
|
822
822
|
npm test
|
|
823
823
|
|
|
824
|
-
#
|
|
824
|
+
# Run tests with coverage
|
|
825
825
|
npm run test:coverage
|
|
826
826
|
|
|
827
|
-
#
|
|
827
|
+
# Run tests in watch mode
|
|
828
828
|
npm run test:watch
|
|
829
829
|
```
|
|
830
830
|
|
|
831
|
-
## 🛠️
|
|
831
|
+
## 🛠️ Development
|
|
832
832
|
|
|
833
833
|
```bash
|
|
834
|
-
#
|
|
834
|
+
# Install dependencies
|
|
835
835
|
npm install
|
|
836
836
|
|
|
837
|
-
#
|
|
837
|
+
# Start development server
|
|
838
838
|
npm run dev
|
|
839
839
|
|
|
840
|
-
#
|
|
840
|
+
# Build for production
|
|
841
841
|
npm run build
|
|
842
842
|
|
|
843
|
-
#
|
|
843
|
+
# Run linting
|
|
844
844
|
npm run lint
|
|
845
845
|
|
|
846
|
-
#
|
|
846
|
+
# Format code
|
|
847
847
|
npm run format
|
|
848
848
|
|
|
849
|
-
#
|
|
849
|
+
# Type checking
|
|
850
850
|
npm run type-check
|
|
851
851
|
|
|
852
|
-
#
|
|
852
|
+
# Generate documentation
|
|
853
853
|
npm run docs
|
|
854
854
|
```
|
|
855
855
|
|
|
856
|
-
## 📋
|
|
856
|
+
## 📋 Migration from legacy-excel
|
|
857
857
|
|
|
858
|
-
|
|
858
|
+
If you're migrating from the legacy version, here's a quick comparison:
|
|
859
859
|
|
|
860
860
|
```typescript
|
|
861
|
-
//
|
|
861
|
+
// Legacy way
|
|
862
862
|
const worksheets: IWorksheets[] = [{
|
|
863
|
-
name: "
|
|
863
|
+
name: "Report",
|
|
864
864
|
tables: [{
|
|
865
865
|
headers: [...],
|
|
866
866
|
subHeaders: [...],
|
|
@@ -868,42 +868,42 @@ const worksheets: IWorksheets[] = [{
|
|
|
868
868
|
footers: [...]
|
|
869
869
|
}]
|
|
870
870
|
}];
|
|
871
|
-
await fileBuilder(worksheets, "
|
|
871
|
+
await fileBuilder(worksheets, "report");
|
|
872
872
|
|
|
873
|
-
//
|
|
873
|
+
// New way
|
|
874
874
|
const builder = new ExcelBuilder();
|
|
875
|
-
const worksheet = builder.addWorksheet('
|
|
875
|
+
const worksheet = builder.addWorksheet('Report');
|
|
876
876
|
worksheet.addHeader({...});
|
|
877
877
|
worksheet.addSubHeaders([...]);
|
|
878
878
|
worksheet.addRow([...]);
|
|
879
879
|
worksheet.addFooter([...]);
|
|
880
|
-
await builder.generateAndDownload('
|
|
880
|
+
await builder.generateAndDownload('report');
|
|
881
881
|
```
|
|
882
882
|
|
|
883
|
-
## 📚
|
|
883
|
+
## 📚 Additional Resources
|
|
884
884
|
|
|
885
|
-
- 📖 [
|
|
886
|
-
- 📖 [
|
|
887
|
-
- 📖 [
|
|
885
|
+
- 📖 [Multiple Tables Guide](./MULTIPLE-TABLES-GUIDE.md)
|
|
886
|
+
- 📖 [Implemented Improvements](./IMPROVEMENTS.md)
|
|
887
|
+
- 📖 [Test Results](./TEST-RESULTS.md)
|
|
888
888
|
|
|
889
|
-
## 🤝
|
|
889
|
+
## 🤝 Contributing
|
|
890
890
|
|
|
891
|
-
1. Fork
|
|
892
|
-
2.
|
|
893
|
-
3. Commit
|
|
894
|
-
4. Push
|
|
895
|
-
5.
|
|
891
|
+
1. Fork the repository
|
|
892
|
+
2. Create a feature branch (`git checkout -b feature/my-feature`)
|
|
893
|
+
3. Commit your changes (`git commit -m 'Add my feature'`)
|
|
894
|
+
4. Push to the branch (`git push origin feature/my-feature`)
|
|
895
|
+
5. Open a Pull Request
|
|
896
896
|
|
|
897
|
-
## 📄
|
|
897
|
+
## 📄 License
|
|
898
898
|
|
|
899
|
-
|
|
899
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
900
900
|
|
|
901
|
-
## 🆘
|
|
901
|
+
## 🆘 Support
|
|
902
902
|
|
|
903
|
-
- 📖 [
|
|
903
|
+
- 📖 [Documentation](https://github.com/hannndler/-han-excel)
|
|
904
904
|
- 🐛 [Issues](https://github.com/hannndler/-han-excel/issues)
|
|
905
905
|
- 💬 [Discussions](https://github.com/hannndler/-han-excel/discussions)
|
|
906
906
|
|
|
907
907
|
---
|
|
908
908
|
|
|
909
|
-
|
|
909
|
+
Made with ❤️ by the Han Excel Team
|
package/package.json
CHANGED