@sme.up/doc-alchemist 1.2.0-SNAPSHOT-20250702130625 → 1.2.0-SNAPSHOT-20250704074443
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 +280 -28
- package/dist/converters/excel/commons.d.ts +2 -1
- package/dist/converters/excel/commons.js +54 -4
- package/dist/converters/excel/commons.js.map +1 -1
- package/dist/converters/excel/matrix-converter.js +12 -10
- package/dist/converters/excel/matrix-converter.js.map +1 -1
- package/dist/converters/pdf/autotable-renderer.d.ts +3 -0
- package/dist/converters/pdf/autotable-renderer.js +89 -0
- package/dist/converters/pdf/autotable-renderer.js.map +1 -0
- package/dist/converters/pdf/cover-renderer.d.ts +1 -0
- package/dist/converters/pdf/cover-renderer.js +26 -0
- package/dist/converters/pdf/cover-renderer.js.map +1 -0
- package/dist/converters/pdf/formulas-helper.d.ts +4 -0
- package/dist/converters/pdf/formulas-helper.js +55 -19
- package/dist/converters/pdf/formulas-helper.js.map +1 -1
- package/dist/converters/pdf/matrix-converter.d.ts +12 -0
- package/dist/converters/pdf/matrix-converter.js +36 -129
- package/dist/converters/pdf/matrix-converter.js.map +1 -1
- package/dist/converters/pdf/pdf-converter.types.d.ts +3 -2
- package/dist/converters/pdf/pdf-converter.types.js.map +1 -1
- package/dist/converters/pdf-converter.js +23 -1
- package/dist/converters/pdf-converter.js.map +1 -1
- package/dist/utils/commons-utility.d.ts +21 -1
- package/dist/utils/commons-utility.js +31 -8
- package/dist/utils/commons-utility.js.map +1 -1
- package/dist/utils/datastructure-utility.js +2 -2
- package/dist/utils/datastructure-utility.js.map +1 -1
- package/dist/utils/math-utility.d.ts +1 -0
- package/dist/utils/math-utility.js +9 -0
- package/dist/utils/math-utility.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# Doc Alchemist
|
|
2
2
|
|
|
3
|
-
A TypeScript library for generating
|
|
3
|
+
A comprehensive TypeScript library for generating documents from SmeupDataTable and SmeupDataTree structures. This library provides powerful data transformation and export capabilities with support for multiple formats including Excel, PDF, and charts.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Excel Export**: Generate `.xlsx
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
7
|
+
- **Excel Export**: Generate `.xlsx`, `.csv` and `.txt` files with full formatting support
|
|
8
|
+
- **PDF Export**: Generate PDF documents with professional styling and automatic formatting
|
|
9
|
+
- **Chart Generation**: Create interactive charts (bar, line, pie, scatter) from data tables
|
|
10
|
+
- **Data Table Support**: Convert SmeupDataTable structures to multiple formats
|
|
11
|
+
- **Data Tree Support**: Convert SmeupDataTree structures with hierarchical representation
|
|
12
|
+
- **Scheda PDF Export**: Generate complex PDF documents with charts and structured layouts
|
|
10
13
|
|
|
11
14
|
## Installation
|
|
12
15
|
|
|
@@ -20,6 +23,9 @@ npm install @sme.up/doc-alchemist
|
|
|
20
23
|
import {
|
|
21
24
|
dataTableToExcelData,
|
|
22
25
|
dataTreeToExcelData,
|
|
26
|
+
dataTableToPdfData,
|
|
27
|
+
schedaToPdfData,
|
|
28
|
+
dataTableToChart,
|
|
23
29
|
} from "@sme.up/doc-alchemist";
|
|
24
30
|
import { SupportedExportFormats } from "@sme.up/doc-alchemist";
|
|
25
31
|
|
|
@@ -98,6 +104,27 @@ const outputPath = path.resolve("./output/sample-export-debug.xlsx");
|
|
|
98
104
|
|
|
99
105
|
// Save to file
|
|
100
106
|
await fs.writeFile(outputPath, excelBuffer);
|
|
107
|
+
|
|
108
|
+
// Generate PDF from the same data
|
|
109
|
+
const pdfBuffer = await dataTableToPdfData(data, {
|
|
110
|
+
mathLocale: "it-IT",
|
|
111
|
+
datesLocale: "it-IT",
|
|
112
|
+
themeBackground: "",
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const pdfOutputPath = path.resolve("./output/sample-export.pdf");
|
|
116
|
+
await fs.writeFile(pdfOutputPath, pdfBuffer);
|
|
117
|
+
|
|
118
|
+
// Generate a chart from data
|
|
119
|
+
const chartBuffer = await dataTableToChart(data.smeupDataTable, "line", {
|
|
120
|
+
Width: "800",
|
|
121
|
+
Height: "600",
|
|
122
|
+
Name: "Default",
|
|
123
|
+
Series: "COL2", // Specify which columns to use for series
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const chartOutputPath = path.resolve("./output/sample-chart.png");
|
|
127
|
+
await fs.writeFile(chartOutputPath, chartBuffer);
|
|
101
128
|
```
|
|
102
129
|
|
|
103
130
|
## API Reference
|
|
@@ -111,10 +138,10 @@ Converts SmeupDataTable to Excel binary data.
|
|
|
111
138
|
**Parameters:**
|
|
112
139
|
|
|
113
140
|
- `data`: Object containing `smeupDataTable` and `props`
|
|
114
|
-
- `format`: Export format (`SupportedExportFormats.XLSX`)
|
|
141
|
+
- `format`: Export format (`SupportedExportFormats.XLSX`, `CSV`, or `TXT`)
|
|
115
142
|
- `managerData`: Configuration object with locale and theme settings
|
|
116
143
|
|
|
117
|
-
**Returns:** `Promise<Buffer | Uint8Array>`
|
|
144
|
+
**Returns:** `Promise<Buffer | Uint8Array>`
|
|
118
145
|
|
|
119
146
|
#### `dataTreeToExcelData(data, format, managerData)`
|
|
120
147
|
|
|
@@ -123,10 +150,44 @@ Converts SmeupDataTree to Excel binary data with hierarchical representation.
|
|
|
123
150
|
**Parameters:**
|
|
124
151
|
|
|
125
152
|
- `data`: Object containing `smeupDataTree` and `props`
|
|
126
|
-
- `format`: Export format (`SupportedExportFormats.XLSX`)
|
|
153
|
+
- `format`: Export format (`SupportedExportFormats.XLSX`, `CSV`, or `TXT`)
|
|
154
|
+
- `managerData`: Configuration object with locale and theme settings
|
|
155
|
+
|
|
156
|
+
**Returns:** `Promise<Buffer | Uint8Array>`
|
|
157
|
+
|
|
158
|
+
#### `dataTableToPdfData(data, managerData)`
|
|
159
|
+
|
|
160
|
+
Converts SmeupDataTable to PDF binary data with professional formatting.
|
|
161
|
+
|
|
162
|
+
**Parameters:**
|
|
163
|
+
|
|
164
|
+
- `data`: Object containing `smeupDataTable` and `props`
|
|
165
|
+
- `managerData`: Configuration object with locale and theme settings
|
|
166
|
+
|
|
167
|
+
**Returns:** `Promise<Buffer | Uint8Array>`
|
|
168
|
+
|
|
169
|
+
#### `schedaToPdfData(sch, managerData)`
|
|
170
|
+
|
|
171
|
+
Converts SmeupSch (scheda) structure to PDF with charts and structured layouts.
|
|
172
|
+
|
|
173
|
+
**Parameters:**
|
|
174
|
+
|
|
175
|
+
- `sch`: SmeupSch object containing sections and components
|
|
127
176
|
- `managerData`: Configuration object with locale and theme settings
|
|
128
177
|
|
|
129
|
-
**Returns:** `Promise<Buffer
|
|
178
|
+
**Returns:** `Promise<Buffer>`
|
|
179
|
+
|
|
180
|
+
#### `dataTableToChart(dataTable, chartType, chartOptions)`
|
|
181
|
+
|
|
182
|
+
Generates chart images from SmeupDataTable data.
|
|
183
|
+
|
|
184
|
+
**Parameters:**
|
|
185
|
+
|
|
186
|
+
- `dataTable`: SmeupDataTable containing the chart data
|
|
187
|
+
- `chartType`: Chart type (`"bar"`, `"line"`, `"pie"`, `"scatter"`)
|
|
188
|
+
- `chartOptions`: Chart configuration object with `Width`, `Height`, `Name`, and `Series`
|
|
189
|
+
|
|
190
|
+
**Returns:** `Promise<Buffer>` (JPEG image data)
|
|
130
191
|
|
|
131
192
|
**Features:**
|
|
132
193
|
|
|
@@ -135,6 +196,51 @@ Converts SmeupDataTree to Excel binary data with hierarchical representation.
|
|
|
135
196
|
- Support for splitting nodes into separate columns or keeping them in a single column
|
|
136
197
|
- Full styling and formatting support
|
|
137
198
|
|
|
199
|
+
### Supported Export Formats
|
|
200
|
+
|
|
201
|
+
The library supports the following export formats:
|
|
202
|
+
|
|
203
|
+
- **XLSX**: Full Excel format with styling, formulas, and formatting
|
|
204
|
+
- **CSV**: Comma-separated values with semicolon delimiter
|
|
205
|
+
- **TXT**: Plain text format
|
|
206
|
+
- **PDF**: Professional PDF documents with styling and charts
|
|
207
|
+
|
|
208
|
+
### Chart Types
|
|
209
|
+
|
|
210
|
+
The chart generation supports:
|
|
211
|
+
|
|
212
|
+
- **Bar Charts**: Vertical bar charts for comparing values
|
|
213
|
+
- **Line Charts**: Time series and trend visualization
|
|
214
|
+
- **Pie Charts**: Proportional data representation
|
|
215
|
+
- **Scatter Charts**: Correlation and distribution analysis
|
|
216
|
+
|
|
217
|
+
### Configuration Options
|
|
218
|
+
|
|
219
|
+
#### WebupManagerData
|
|
220
|
+
|
|
221
|
+
Configuration object for formatting and localization:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
interface WebupManagerData {
|
|
225
|
+
mathLocale?: string; // e.g., "it-IT", "en-US"
|
|
226
|
+
datesLocale?: string; // e.g., "it-IT", "en-US"
|
|
227
|
+
themeBackground?: string; // Theme background color
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### ChartOptions
|
|
232
|
+
|
|
233
|
+
Configuration for chart generation:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
interface ChartOptions {
|
|
237
|
+
Width: string; // Chart width in pixels
|
|
238
|
+
Height: string; // Chart height in pixels
|
|
239
|
+
Name: string; // Chart name/title
|
|
240
|
+
Series: string; // Column names separated by "|" (e.g., "COL1|COL2")
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
138
244
|
### Setup
|
|
139
245
|
|
|
140
246
|
```bash
|
|
@@ -146,13 +252,18 @@ cd doc-alchemist
|
|
|
146
252
|
npm install
|
|
147
253
|
```
|
|
148
254
|
|
|
149
|
-
### Running
|
|
255
|
+
### Running Examples
|
|
150
256
|
|
|
151
257
|
```bash
|
|
152
|
-
# Run the main
|
|
258
|
+
# Run the main Excel/PDF example
|
|
153
259
|
npm start
|
|
154
260
|
|
|
155
|
-
#
|
|
261
|
+
# Run specific debug examples
|
|
262
|
+
npx tsx debug-charts.ts # Generate chart examples
|
|
263
|
+
npx tsx debug-pdf.ts # Generate PDF examples
|
|
264
|
+
npx tsx debug-sch.ts # Generate scheda PDF examples
|
|
265
|
+
|
|
266
|
+
# Output files will be saved to ./output/ directory
|
|
156
267
|
```
|
|
157
268
|
|
|
158
269
|
### Testing
|
|
@@ -162,28 +273,169 @@ npm start
|
|
|
162
273
|
npm test
|
|
163
274
|
```
|
|
164
275
|
|
|
165
|
-
|
|
276
|
+
### Code Style
|
|
166
277
|
|
|
167
|
-
|
|
278
|
+
- Use TypeScript strict mode
|
|
279
|
+
- Follow existing code formatting
|
|
280
|
+
- Write tests for new features
|
|
281
|
+
- Use meaningful variable and function names
|
|
168
282
|
|
|
169
|
-
|
|
283
|
+
## Advanced Usage Examples
|
|
170
284
|
|
|
171
|
-
|
|
285
|
+
### Excel Export with Custom Formatting
|
|
172
286
|
|
|
173
|
-
|
|
174
|
-
|
|
287
|
+
```typescript
|
|
288
|
+
import {
|
|
289
|
+
dataTableToExcelData,
|
|
290
|
+
SupportedExportFormats,
|
|
291
|
+
} from "@sme.up/doc-alchemist";
|
|
175
292
|
|
|
176
|
-
|
|
293
|
+
const data = {
|
|
294
|
+
smeupDataTable: {
|
|
295
|
+
columns: [
|
|
296
|
+
{
|
|
297
|
+
name: "DATE",
|
|
298
|
+
title: "Date",
|
|
299
|
+
visible: true,
|
|
300
|
+
obj: { t: "D8", p: "*YYMD" },
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "AMOUNT",
|
|
304
|
+
title: "Amount",
|
|
305
|
+
visible: true,
|
|
306
|
+
obj: { t: "NR", p: "" },
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
rows: [
|
|
310
|
+
{
|
|
311
|
+
cells: {
|
|
312
|
+
DATE: {
|
|
313
|
+
value: "20240704",
|
|
314
|
+
obj: { t: "D8", p: "*YYMD", k: "20240704" },
|
|
315
|
+
},
|
|
316
|
+
AMOUNT: { value: "1250.50", obj: { t: "NR", p: "", k: "1250.50" } },
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
},
|
|
321
|
+
props: {
|
|
322
|
+
totals: { AMOUNT: "Sum" }, // Add sum totals for amount column
|
|
323
|
+
groups: [{ column: "DATE", visible: true }], // Group by date
|
|
324
|
+
filter: [],
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const excelBuffer = await dataTableToExcelData(
|
|
329
|
+
data,
|
|
330
|
+
SupportedExportFormats.XLSX,
|
|
331
|
+
{
|
|
332
|
+
mathLocale: "it-IT",
|
|
333
|
+
datesLocale: "it-IT",
|
|
334
|
+
themeBackground: "#ffffff",
|
|
335
|
+
},
|
|
336
|
+
);
|
|
337
|
+
```
|
|
177
338
|
|
|
178
|
-
|
|
179
|
-
2. **Open Debug Panel** (Ctrl+Shift+D)
|
|
180
|
-
3. **Select configuration** from dropdown
|
|
181
|
-
4. **Set breakpoints** in your TypeScript files
|
|
182
|
-
5. **Press F5** to start debugging
|
|
339
|
+
### PDF Generation with Custom Styling
|
|
183
340
|
|
|
184
|
-
|
|
341
|
+
```typescript
|
|
342
|
+
import { dataTableToPdfData } from "@sme.up/doc-alchemist";
|
|
343
|
+
|
|
344
|
+
const pdfBuffer = await dataTableToPdfData(data, {
|
|
345
|
+
mathLocale: "it-IT",
|
|
346
|
+
datesLocale: "it-IT",
|
|
347
|
+
themeBackground: "",
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
// The PDF will include:
|
|
351
|
+
// - Professional header with company logo
|
|
352
|
+
// - Automatic font size optimization
|
|
353
|
+
// - Cell styling preservation from Excel
|
|
354
|
+
// - Proper number and date formatting
|
|
355
|
+
```
|
|
185
356
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
357
|
+
### Chart Generation from Data
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
import { dataTableToChart } from "@sme.up/doc-alchemist";
|
|
361
|
+
|
|
362
|
+
// Generate different chart types
|
|
363
|
+
const lineChart = await dataTableToChart(dataTable, "line", {
|
|
364
|
+
Width: "1200",
|
|
365
|
+
Height: "800",
|
|
366
|
+
Name: "Trend Analysis",
|
|
367
|
+
Series: "SALES|PROFIT",
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const pieChart = await dataTableToChart(dataTable, "pie", {
|
|
371
|
+
Width: "800",
|
|
372
|
+
Height: "600",
|
|
373
|
+
Name: "Market Share",
|
|
374
|
+
Series: "PERCENTAGE",
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
const barChart = await dataTableToChart(dataTable, "bar", {
|
|
378
|
+
Width: "1000",
|
|
379
|
+
Height: "600",
|
|
380
|
+
Name: "Comparison",
|
|
381
|
+
Series: "Q1|Q2|Q3|Q4",
|
|
382
|
+
});
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Scheda PDF with Multiple Charts
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
import { schedaToPdfData } from "@sme.up/doc-alchemist";
|
|
389
|
+
|
|
390
|
+
const scheda = {
|
|
391
|
+
layout: "column",
|
|
392
|
+
sections: [
|
|
393
|
+
{
|
|
394
|
+
layout: "row",
|
|
395
|
+
dim: "50",
|
|
396
|
+
components: [
|
|
397
|
+
{
|
|
398
|
+
type: "EXA",
|
|
399
|
+
title: "Sales Trend",
|
|
400
|
+
data: salesDataTable,
|
|
401
|
+
options: {
|
|
402
|
+
EXA: [
|
|
403
|
+
{
|
|
404
|
+
Width: "800",
|
|
405
|
+
Height: "400",
|
|
406
|
+
Series: "SALES",
|
|
407
|
+
},
|
|
408
|
+
],
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
],
|
|
412
|
+
},
|
|
413
|
+
// Additional sections...
|
|
414
|
+
],
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
const schedaPdfBuffer = await schedaToPdfData(scheda, {
|
|
418
|
+
mathLocale: "it-IT",
|
|
419
|
+
datesLocale: "it-IT",
|
|
420
|
+
themeBackground: "",
|
|
421
|
+
});
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## Dependencies
|
|
425
|
+
|
|
426
|
+
This library includes the following key dependencies:
|
|
427
|
+
|
|
428
|
+
- **ExcelJS**: For Excel file generation and manipulation
|
|
429
|
+
- **jsPDF**: For PDF document creation
|
|
430
|
+
- **jsPDF-AutoTable**: For advanced table formatting in PDFs
|
|
431
|
+
- **ECharts**: For chart generation
|
|
432
|
+
- **Canvas**: For server-side image rendering
|
|
433
|
+
- **PDF-lib**: For PDF manipulation and merging
|
|
434
|
+
|
|
435
|
+
## Browser vs Node.js Support
|
|
436
|
+
|
|
437
|
+
The library is designed to work in both environments:
|
|
438
|
+
|
|
439
|
+
- **Node.js**: Full functionality including chart generation using Canvas
|
|
440
|
+
- **Browser**: Full functionality with DOM-based chart rendering
|
|
441
|
+
- **Chart Generation**: Automatically detects environment and uses appropriate rendering method
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ExcelJS, { Worksheet } from "exceljs";
|
|
2
2
|
import { GenericObject, WebupManagerData } from "../../types/index.js";
|
|
3
|
-
import { SmeupDataColumn } from "../../types/data-structures/smeupDataTable.js";
|
|
3
|
+
import { SmeupDataCell, SmeupDataColumn } from "../../types/data-structures/smeupDataTable.js";
|
|
4
4
|
/**
|
|
5
5
|
* Adds creator, creation date to the workbook and creates a sheet
|
|
6
6
|
* @param workbook
|
|
@@ -19,6 +19,7 @@ export declare const getExcelColumnLetter: (index: number) => string;
|
|
|
19
19
|
*/
|
|
20
20
|
export declare const getTotalFormula: (worksheet: ExcelJS.Worksheet, totalOperation: string, colIndex: number, rowNumber: number, filteredColumns: SmeupDataColumn[], isSmeupFormula: boolean) => string;
|
|
21
21
|
export declare const smeupFormulaToExcelFormula: (formula: string, rowNumber: number, filteredColumns: SmeupDataColumn[]) => string;
|
|
22
|
+
export declare const smeupFormulaToExcelValue: (column: SmeupDataColumn, filteredColumns: SmeupDataColumn[], cells: Record<string, SmeupDataCell>) => string;
|
|
22
23
|
export declare const getDistinctCount: (range: string, worksheet: ExcelJS.Worksheet) => string;
|
|
23
24
|
/**
|
|
24
25
|
* Estrae tutte le celle (ExcelJS.Cell) da un intervallo rettangolare specificato in un worksheet ExcelJS.
|
|
@@ -2,6 +2,7 @@ import ExcelJS from "exceljs";
|
|
|
2
2
|
import { allowedTotals, footerStyleFill, headerStyleFill, } from "./excel-converter.types.js";
|
|
3
3
|
import { objectsIsDate } from "../../utils/objects-utility.js";
|
|
4
4
|
import { getExcelNumFormatForGroupedRow } from "./matrix-converter.js";
|
|
5
|
+
import { calculateExpression } from "../../utils/math-utility.js";
|
|
5
6
|
const { ValueType } = ExcelJS;
|
|
6
7
|
/**
|
|
7
8
|
* Adds creator, creation date to the workbook and creates a sheet
|
|
@@ -95,16 +96,65 @@ export const getTotalFormula = (worksheet, totalOperation, colIndex, rowNumber,
|
|
|
95
96
|
}
|
|
96
97
|
};
|
|
97
98
|
export const smeupFormulaToExcelFormula = (formula, rowNumber, filteredColumns) => {
|
|
98
|
-
|
|
99
|
+
const result = formula
|
|
99
100
|
.replace("MATH", "")
|
|
100
|
-
.replace(/\[(
|
|
101
|
-
const columnIndex = filteredColumns.findIndex(col => col.name === key) + 1;
|
|
101
|
+
.replace(/\[([^\]]+)\]/g, (_, key) => {
|
|
102
|
+
const columnIndex = filteredColumns.findIndex(col => col.name === key) + 1;
|
|
102
103
|
const columnLetter = getExcelColumnLetter(columnIndex);
|
|
103
104
|
return columnLetter && columnIndex
|
|
104
105
|
? `${columnLetter}${rowNumber + 1}`
|
|
105
|
-
: key;
|
|
106
|
+
: key;
|
|
106
107
|
})
|
|
107
108
|
.replaceAll(",", "."); // Replace eventual , to . => The excel accepted decimal separator
|
|
109
|
+
return result;
|
|
110
|
+
};
|
|
111
|
+
export const smeupFormulaToExcelValue = (column, filteredColumns, cells) => {
|
|
112
|
+
let resultValue = "";
|
|
113
|
+
if (!column.formula) {
|
|
114
|
+
return "";
|
|
115
|
+
}
|
|
116
|
+
const result = column.formula
|
|
117
|
+
.replace("MATH", "")
|
|
118
|
+
.replace(/\[([^\]]+)\]/g, (match, key) => {
|
|
119
|
+
const columnIndex = filteredColumns.findIndex(col => col.name === key);
|
|
120
|
+
return columnIndex >= 0
|
|
121
|
+
? (cells[key]?.value ?? "")
|
|
122
|
+
: match === "[SUM]"
|
|
123
|
+
? match
|
|
124
|
+
: key;
|
|
125
|
+
});
|
|
126
|
+
try {
|
|
127
|
+
if (result === "[SUM]") {
|
|
128
|
+
resultValue = applySUMFormula(column, filteredColumns, cells);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
resultValue = calculateExpression(result);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
resultValue = result; // If the formula fails, return the original formula
|
|
136
|
+
}
|
|
137
|
+
return resultValue.toString();
|
|
138
|
+
};
|
|
139
|
+
const applySUMFormula = (column, filteredColumns, cells) => {
|
|
140
|
+
let resultValue = 0;
|
|
141
|
+
resultValue = 0;
|
|
142
|
+
const index = filteredColumns.findIndex(col => col.name === column.name);
|
|
143
|
+
filteredColumns.slice(0, index).forEach(col => {
|
|
144
|
+
if (col.obj && col.obj.t === "NR") {
|
|
145
|
+
let cellValue = 0;
|
|
146
|
+
if (col.formula) {
|
|
147
|
+
cellValue = Number(smeupFormulaToExcelValue(col, filteredColumns, cells));
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
cellValue = Number(cells[col.name]?.value);
|
|
151
|
+
}
|
|
152
|
+
if (!isNaN(cellValue)) {
|
|
153
|
+
resultValue = resultValue + cellValue;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
return resultValue;
|
|
108
158
|
};
|
|
109
159
|
export const getDistinctCount = (range, worksheet) => {
|
|
110
160
|
const column = range.split(":")[0].replace(/[0-9]/g, ""); // Extract column letter
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commons.js","sourceRoot":"","sources":["../../../src/converters/excel/commons.ts"],"names":[],"mappings":"AAAA,OAAO,OAAsB,MAAM,SAAS,CAAC;AAC7C,OAAO,EACL,aAAa,EACb,eAAe,EACf,eAAe,GAChB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAEvE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;AAE9B;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAA0B,EAAE,EAAE;IAChE,QAAQ,CAAC,OAAO,GAAG,4CAA4C,CAAC;IAChE,QAAQ,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;IAE9B,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAClD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,SAAoB,EACpB,UAAU,GAAG,KAAK,EACZ,EAAE;IACR,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtC,SAAS,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAChC,SAAS,CAAC,SAAS,GAAG;QACpB,UAAU,EAAE,QAAQ;QACpB,QAAQ,EAAE,QAAQ;QAClB,QAAQ,EAAE,IAAI;KACf,CAAC;IAEF,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;YACzD,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC9B,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,SAA4B,EAC5B,OAA0B,EAC1B,KAAoB,EACpB,gBAAkC,EAClC,EAAE;IACF,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACvD,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAAgC,CAAC;IAEtD,4BAA4B;IAC5B,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;QACxD,MAAM,cAAc,GAAW,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,cAAc;YAAE,OAAO;QAE5B,MAAM,OAAO,GAAG,eAAe,CAC7B,SAAS,EACT,cAAc,EACd,WAAW,GAAG,CAAC,EAAE,wBAAwB;QACzC,SAAS,CAAC,QAAQ,EAClB,OAAO,EACP,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAClC,CAAC;QAEF,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IACvE,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAElD,4BAA4B;IAC5B,SAAS,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAChC,SAAS,CAAC,SAAS,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAC5B,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,iCAAiC;QACnF,WAAW,CAAC,IAAI,GAAG,eAAe,CAAC;QAEnC,IACE,MAAM,CAAC,GAAG;YACV,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC;YACzB,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC;gBACjD,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EACrD,CAAC;YACD,MAAM,UAAU,GACd,gBAAgB,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;YACtE,WAAW,CAAC,MAAM,GAAG,UAAU,CAAC;YAChC,OAAO;QACT,CAAC;QAED,WAAW,CAAC,MAAM,GAAG,8BAA8B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAU,EAAE;IAC5D,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,OAAO,KAAK,GAAG,CAAC,EAAE,CAAC;QACjB,KAAK,EAAE,CAAC,CAAC,uEAAuE;QAChF,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,YAAY,CAAC;QACrE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,SAA4B,EAC5B,cAAsB,EACtB,QAAgB,EAChB,SAAiB,EACjB,eAAkC,EAClC,cAAuB,EACf,EAAE;IACV,MAAM,QAAQ,GAAG,CAAC,CAAC;IACnB,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAEzD,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,0BAA0B,CAC/B,cAAc,EACd,SAAS,EACT,eAAe,CAChB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,IAAI,CACV,sBAAsB,cAAc,sBAAsB,EAC1D,gBAAgB,CACjB,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,cAAc,KAAK,UAAU,EAAE,CAAC;QAClC,OAAO,gBAAgB,CACrB,GAAG,iBAAiB,GAAG,QAAQ,IAAI,iBAAiB,GAAG,SAAS,EAAE,EAClE,SAAS,CACV,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,aAAa,CAAC,cAAc,CAAC,GAAG,iBAAiB,GAAG,QAAQ,IAAI,iBAAiB,GAAG,SAAS,GAAG,CAAC;IAC7G,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,OAAe,EACf,SAAiB,EACjB,eAAkC,EAC1B,EAAE;IACV,OAAO,OAAO;SACX,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;SACnB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;QAChC,MAAM,WAAW,GACf,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,0BAA0B;QACpF,MAAM,YAAY,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;QACvD,OAAO,YAAY,IAAI,WAAW;YAChC,CAAC,CAAC,GAAG,YAAY,GAAG,SAAS,GAAG,CAAC,EAAE;YACnC,CAAC,CAAC,GAAG,CAAC,CAAC,oEAAoE;IAC/E,CAAC,CAAC;SACD,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,kEAAkE;AAC7F,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAAa,EACb,SAA4B,EACpB,EAAE;IACV,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,wBAAwB;IAClF,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEpE,sCAAsC;IACtC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAEvC,KAAK,IAAI,QAAQ,GAAG,QAAQ,EAAE,QAAQ,IAAI,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;QAC7D,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,QAAQ,EAAE,CAAC,CAAC;QACvD,IAAI,IAAI,CAAC,OAAO;YAAE,SAAS;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7B,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAClD,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;AACtC,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,SAA4B,EAC5B,QAAgB,EAChB,MAAc,EACE,EAAE;IAClB,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,EAAE;QACnC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACtB,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE;QACjC,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,KAAK,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAClE,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["import ExcelJS, { Worksheet } from \"exceljs\";\nimport {\n allowedTotals,\n footerStyleFill,\n headerStyleFill,\n} from \"./excel-converter.types.js\";\nimport { GenericObject, WebupManagerData } from \"../../types/index.js\";\nimport { objectsIsDate } from \"../../utils/objects-utility.js\";\nimport { getExcelNumFormatForGroupedRow } from \"./matrix-converter.js\";\nimport { SmeupDataColumn } from \"../../types/data-structures/smeupDataTable.js\";\nconst { ValueType } = ExcelJS;\n\n/**\n * Adds creator, creation date to the workbook and creates a sheet\n * @param workbook\n * @returns void\n */\nexport const initializeWorksheet = (workbook: ExcelJS.Workbook) => {\n workbook.creator = \"/doc-alchemist - dataTable excel generator\";\n workbook.created = new Date();\n\n const worksheet = workbook.addWorksheet(\"Export\");\n return worksheet;\n};\n\nexport const setHeaderStyling = (\n worksheet: Worksheet,\n background = false,\n): void => {\n const headerRow = worksheet.getRow(1);\n headerRow.font = { bold: true };\n headerRow.alignment = {\n horizontal: \"center\",\n vertical: \"middle\",\n wrapText: true,\n };\n\n if (background) {\n for (let col = 1; col <= worksheet.columns.length; col++) {\n const cell = headerRow.getCell(col);\n cell.fill = headerStyleFill;\n }\n }\n};\n\nexport const addFooterTotalsRow = (\n worksheet: ExcelJS.Worksheet,\n columns: SmeupDataColumn[],\n props: GenericObject,\n webupManagerData: WebupManagerData,\n) => {\n if (!props?.totals || typeof props.totals !== \"object\") {\n return;\n }\n\n const totals = props.totals as Record<string, string>;\n\n // Set footer total formulas\n const footerRowData = columns.map((column, columnIndex) => {\n const totalOperation: string = totals[column.name];\n if (!totalOperation) return;\n\n const formula = getTotalFormula(\n worksheet,\n totalOperation,\n columnIndex + 1, // from base 0 to base 1\n worksheet.rowCount,\n columns,\n totalOperation.startsWith(\"MATH\"),\n );\n\n return formula ? { formula: formula, type: ValueType.Formula } : \" \";\n });\n const footerRow = worksheet.addRow(footerRowData);\n\n // Format excel footer cells\n footerRow.font = { bold: true };\n footerRow.alignment = { horizontal: \"right\" };\n columns.map((column, index) => {\n const exceljsCell = footerRow.getCell(index + 1); // Convert base 0 index to base 1\n exceljsCell.fill = footerStyleFill;\n\n if (\n column.obj &&\n objectsIsDate(column.obj) &&\n (exceljsCell.formula?.startsWith(allowedTotals.Min) ||\n exceljsCell.formula?.startsWith(allowedTotals.Max))\n ) {\n const dateFormat =\n webupManagerData.datesLocale === \"it\" ? \"dd/mm/yyyy\" : \"mm/dd/yyyy\";\n exceljsCell.numFmt = dateFormat;\n return;\n }\n\n exceljsCell.numFmt = getExcelNumFormatForGroupedRow(column, totals);\n });\n};\n\nexport const getExcelColumnLetter = (index: number): string => {\n let columnLetter = \"\";\n while (index > 0) {\n index--; // Excel columns are 1-based, but calculations work better with 0-based\n columnLetter = String.fromCharCode((index % 26) + 65) + columnLetter;\n index = Math.floor(index / 26);\n }\n return columnLetter;\n};\n\n/**\n * Returns the formula used in the footer to add Totals at the end of the table\n * @param totalOperation string\n * @param colIndex string\n * @param rowNumber number\n * @returns\n */\nexport const getTotalFormula = (\n worksheet: ExcelJS.Worksheet,\n totalOperation: string,\n colIndex: number,\n rowNumber: number,\n filteredColumns: SmeupDataColumn[],\n isSmeupFormula: boolean,\n): string => {\n const startRow = 2;\n const columnExcelLetter = getExcelColumnLetter(colIndex);\n\n if (isSmeupFormula) {\n return smeupFormulaToExcelFormula(\n totalOperation,\n rowNumber,\n filteredColumns,\n );\n }\n\n if (!allowedTotals[totalOperation]) {\n console.warn(\n `Total operation [' ${totalOperation} '] is not supported`,\n \"exportUtils.ts\",\n );\n return \"\";\n }\n\n if (totalOperation === \"Distinct\") {\n return getDistinctCount(\n `${columnExcelLetter}${startRow}:${columnExcelLetter}${rowNumber}`,\n worksheet,\n );\n } else {\n return `${allowedTotals[totalOperation]}${columnExcelLetter}${startRow}:${columnExcelLetter}${rowNumber})`;\n }\n};\n\nexport const smeupFormulaToExcelFormula = (\n formula: string,\n rowNumber: number,\n filteredColumns: SmeupDataColumn[],\n): string => {\n return formula\n .replace(\"MATH\", \"\")\n .replace(/\\[(\\w+)\\]/g, (_, key) => {\n const columnIndex =\n filteredColumns.findIndex(col => col.name === key) + 1; // Convert to base 1 index\n const columnLetter = getExcelColumnLetter(columnIndex);\n return columnLetter && columnIndex\n ? `${columnLetter}${rowNumber + 1}`\n : key; // Return column letter with row number or original key if not found\n })\n .replaceAll(\",\", \".\"); // Replace eventual , to . => The excel accepted decimal separator\n};\n\nexport const getDistinctCount = (\n range: string,\n worksheet: ExcelJS.Worksheet,\n): string => {\n const column = range.split(\":\")[0].replace(/[0-9]/g, \"\"); // Extract column letter\n const startRow = parseInt(range.split(\":\")[0].replace(/\\D/g, \"\"), 10);\n const endRow = parseInt(range.split(\":\")[1].replace(/\\D/g, \"\"), 10);\n\n // Create a set to store unique values\n const uniqueValues = new Set<string>();\n\n for (let rowIndex = startRow; rowIndex <= endRow; rowIndex++) {\n const cell = worksheet.getCell(`${column}${rowIndex}`);\n if (cell.formula) continue;\n const cellValue = cell.value;\n if (cellValue !== null && cellValue !== undefined) {\n uniqueValues.add(cellValue.toString());\n }\n }\n\n return uniqueValues.size.toString();\n};\n\n/**\n * Estrae tutte le celle (ExcelJS.Cell) da un intervallo rettangolare specificato in un worksheet ExcelJS.\n *\n * L'intervallo è definito dai riferimenti di cella iniziale e finale (es. \"A1\" a \"C3\").\n * Restituisce le celle in ordine riga-major.\n *\n * @param worksheet - Il worksheet ExcelJS da cui estrarre le celle.\n * @param startRef - Il riferimento della cella iniziale (es. \"A1\").\n * @param endRef - Il riferimento della cella finale (es. \"C3\").\n * @returns Un array di ExcelJS.Cell dall'intervallo specificato, in ordine riga-major.\n */\nexport const getCellsFromRange = (\n worksheet: ExcelJS.Worksheet,\n startRef: string,\n endRef: string,\n): ExcelJS.Cell[] => {\n const parseCellRef = (ref: string) => {\n const match = ref.match(/^([A-Z]+)(\\d+)$/i);\n if (!match) return null;\n const col = match[1].toUpperCase();\n const row = parseInt(match[2], 10);\n return { col, row };\n };\n const colToIndex = (col: string) => {\n let idx = 0;\n for (let i = 0; i < col.length; i++) {\n idx = idx * 26 + (col.charCodeAt(i) - 64);\n }\n return idx;\n };\n const start = parseCellRef(startRef);\n const end = parseCellRef(endRef);\n if (!start || !end) return [];\n const cells: ExcelJS.Cell[] = [];\n for (let r = start.row; r <= end.row; r++) {\n for (let c = colToIndex(start.col); c <= colToIndex(end.col); c++) {\n const cell = worksheet.getRow(r).getCell(c);\n cells.push(cell);\n }\n }\n return cells;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"commons.js","sourceRoot":"","sources":["../../../src/converters/excel/commons.ts"],"names":[],"mappings":"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","sourcesContent":["import ExcelJS, { Worksheet } from \"exceljs\";\nimport {\n allowedTotals,\n footerStyleFill,\n headerStyleFill,\n} from \"./excel-converter.types.js\";\nimport { GenericObject, WebupManagerData } from \"../../types/index.js\";\nimport { objectsIsDate } from \"../../utils/objects-utility.js\";\nimport { getExcelNumFormatForGroupedRow } from \"./matrix-converter.js\";\nimport {\n SmeupDataCell,\n SmeupDataColumn,\n} from \"../../types/data-structures/smeupDataTable.js\";\nimport { calculateExpression } from \"../../utils/math-utility.js\";\nconst { ValueType } = ExcelJS;\n\n/**\n * Adds creator, creation date to the workbook and creates a sheet\n * @param workbook\n * @returns void\n */\nexport const initializeWorksheet = (workbook: ExcelJS.Workbook) => {\n workbook.creator = \"/doc-alchemist - dataTable excel generator\";\n workbook.created = new Date();\n\n const worksheet = workbook.addWorksheet(\"Export\");\n return worksheet;\n};\n\nexport const setHeaderStyling = (\n worksheet: Worksheet,\n background = false,\n): void => {\n const headerRow = worksheet.getRow(1);\n headerRow.font = { bold: true };\n headerRow.alignment = {\n horizontal: \"center\",\n vertical: \"middle\",\n wrapText: true,\n };\n\n if (background) {\n for (let col = 1; col <= worksheet.columns.length; col++) {\n const cell = headerRow.getCell(col);\n cell.fill = headerStyleFill;\n }\n }\n};\n\nexport const addFooterTotalsRow = (\n worksheet: ExcelJS.Worksheet,\n columns: SmeupDataColumn[],\n props: GenericObject,\n webupManagerData: WebupManagerData,\n) => {\n if (!props?.totals || typeof props.totals !== \"object\") {\n return;\n }\n\n const totals = props.totals as Record<string, string>;\n\n // Set footer total formulas\n const footerRowData = columns.map((column, columnIndex) => {\n const totalOperation: string = totals[column.name];\n if (!totalOperation) return;\n\n const formula = getTotalFormula(\n worksheet,\n totalOperation,\n columnIndex + 1, // from base 0 to base 1\n worksheet.rowCount,\n columns,\n totalOperation.startsWith(\"MATH\"),\n );\n\n return formula ? { formula: formula, type: ValueType.Formula } : \" \";\n });\n const footerRow = worksheet.addRow(footerRowData);\n\n // Format excel footer cells\n footerRow.font = { bold: true };\n footerRow.alignment = { horizontal: \"right\" };\n columns.map((column, index) => {\n const exceljsCell = footerRow.getCell(index + 1); // Convert base 0 index to base 1\n exceljsCell.fill = footerStyleFill;\n\n if (\n column.obj &&\n objectsIsDate(column.obj) &&\n (exceljsCell.formula?.startsWith(allowedTotals.Min) ||\n exceljsCell.formula?.startsWith(allowedTotals.Max))\n ) {\n const dateFormat =\n webupManagerData.datesLocale === \"it\" ? \"dd/mm/yyyy\" : \"mm/dd/yyyy\";\n exceljsCell.numFmt = dateFormat;\n return;\n }\n\n exceljsCell.numFmt = getExcelNumFormatForGroupedRow(column, totals);\n });\n};\n\nexport const getExcelColumnLetter = (index: number): string => {\n let columnLetter = \"\";\n while (index > 0) {\n index--; // Excel columns are 1-based, but calculations work better with 0-based\n columnLetter = String.fromCharCode((index % 26) + 65) + columnLetter;\n index = Math.floor(index / 26);\n }\n return columnLetter;\n};\n\n/**\n * Returns the formula used in the footer to add Totals at the end of the table\n * @param totalOperation string\n * @param colIndex string\n * @param rowNumber number\n * @returns\n */\nexport const getTotalFormula = (\n worksheet: ExcelJS.Worksheet,\n totalOperation: string,\n colIndex: number,\n rowNumber: number,\n filteredColumns: SmeupDataColumn[],\n isSmeupFormula: boolean,\n): string => {\n const startRow = 2;\n const columnExcelLetter = getExcelColumnLetter(colIndex);\n\n if (isSmeupFormula) {\n return smeupFormulaToExcelFormula(\n totalOperation,\n rowNumber,\n filteredColumns,\n );\n }\n\n if (!allowedTotals[totalOperation]) {\n console.warn(\n `Total operation [' ${totalOperation} '] is not supported`,\n \"exportUtils.ts\",\n );\n return \"\";\n }\n\n if (totalOperation === \"Distinct\") {\n return getDistinctCount(\n `${columnExcelLetter}${startRow}:${columnExcelLetter}${rowNumber}`,\n worksheet,\n );\n } else {\n return `${allowedTotals[totalOperation]}${columnExcelLetter}${startRow}:${columnExcelLetter}${rowNumber})`;\n }\n};\n\nexport const smeupFormulaToExcelFormula = (\n formula: string,\n rowNumber: number,\n filteredColumns: SmeupDataColumn[],\n): string => {\n const result = formula\n .replace(\"MATH\", \"\")\n .replace(/\\[([^\\]]+)\\]/g, (_, key) => {\n const columnIndex =\n filteredColumns.findIndex(col => col.name === key) + 1;\n const columnLetter = getExcelColumnLetter(columnIndex);\n return columnLetter && columnIndex\n ? `${columnLetter}${rowNumber + 1}`\n : key;\n })\n .replaceAll(\",\", \".\"); // Replace eventual , to . => The excel accepted decimal separator\n return result;\n};\n\nexport const smeupFormulaToExcelValue = (\n column: SmeupDataColumn,\n filteredColumns: SmeupDataColumn[],\n cells: Record<string, SmeupDataCell>,\n): string => {\n let resultValue: string | number = \"\";\n if (!column.formula) {\n return \"\";\n }\n const result = column.formula\n .replace(\"MATH\", \"\")\n .replace(/\\[([^\\]]+)\\]/g, (match, key) => {\n const columnIndex = filteredColumns.findIndex(col => col.name === key);\n return columnIndex >= 0\n ? (cells[key]?.value ?? \"\")\n : match === \"[SUM]\"\n ? match\n : key;\n });\n try {\n if (result === \"[SUM]\") {\n resultValue = applySUMFormula(column, filteredColumns, cells);\n } else {\n resultValue = calculateExpression(result);\n }\n } catch {\n resultValue = result; // If the formula fails, return the original formula\n }\n return resultValue.toString();\n};\n\nconst applySUMFormula = (\n column: SmeupDataColumn,\n filteredColumns: SmeupDataColumn[],\n cells: Record<string, SmeupDataCell>,\n): number => {\n let resultValue: number = 0;\n resultValue = 0;\n const index = filteredColumns.findIndex(col => col.name === column.name);\n filteredColumns.slice(0, index).forEach(col => {\n if (col.obj && col.obj.t === \"NR\") {\n let cellValue = 0;\n if (col.formula) {\n cellValue = Number(\n smeupFormulaToExcelValue(col, filteredColumns, cells),\n );\n } else {\n cellValue = Number(cells[col.name]?.value);\n }\n if (!isNaN(cellValue)) {\n resultValue = (resultValue as number) + cellValue;\n }\n }\n });\n return resultValue;\n};\n\nexport const getDistinctCount = (\n range: string,\n worksheet: ExcelJS.Worksheet,\n): string => {\n const column = range.split(\":\")[0].replace(/[0-9]/g, \"\"); // Extract column letter\n const startRow = parseInt(range.split(\":\")[0].replace(/\\D/g, \"\"), 10);\n const endRow = parseInt(range.split(\":\")[1].replace(/\\D/g, \"\"), 10);\n\n // Create a set to store unique values\n const uniqueValues = new Set<string>();\n\n for (let rowIndex = startRow; rowIndex <= endRow; rowIndex++) {\n const cell = worksheet.getCell(`${column}${rowIndex}`);\n if (cell.formula) continue;\n const cellValue = cell.value;\n if (cellValue !== null && cellValue !== undefined) {\n uniqueValues.add(cellValue.toString());\n }\n }\n\n return uniqueValues.size.toString();\n};\n\n/**\n * Estrae tutte le celle (ExcelJS.Cell) da un intervallo rettangolare specificato in un worksheet ExcelJS.\n *\n * L'intervallo è definito dai riferimenti di cella iniziale e finale (es. \"A1\" a \"C3\").\n * Restituisce le celle in ordine riga-major.\n *\n * @param worksheet - Il worksheet ExcelJS da cui estrarre le celle.\n * @param startRef - Il riferimento della cella iniziale (es. \"A1\").\n * @param endRef - Il riferimento della cella finale (es. \"C3\").\n * @returns Un array di ExcelJS.Cell dall'intervallo specificato, in ordine riga-major.\n */\nexport const getCellsFromRange = (\n worksheet: ExcelJS.Worksheet,\n startRef: string,\n endRef: string,\n): ExcelJS.Cell[] => {\n const parseCellRef = (ref: string) => {\n const match = ref.match(/^([A-Z]+)(\\d+)$/i);\n if (!match) return null;\n const col = match[1].toUpperCase();\n const row = parseInt(match[2], 10);\n return { col, row };\n };\n const colToIndex = (col: string) => {\n let idx = 0;\n for (let i = 0; i < col.length; i++) {\n idx = idx * 26 + (col.charCodeAt(i) - 64);\n }\n return idx;\n };\n const start = parseCellRef(startRef);\n const end = parseCellRef(endRef);\n if (!start || !end) return [];\n const cells: ExcelJS.Cell[] = [];\n for (let r = start.row; r <= end.row; r++) {\n for (let c = colToIndex(start.col); c <= colToIndex(end.col); c++) {\n const cell = worksheet.getRow(r).getCell(c);\n cells.push(cell);\n }\n }\n return cells;\n};\n"]}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import ExcelJS from "exceljs";
|
|
2
|
-
|
|
3
|
-
import { getFilteredColumns, filterRows, updateMaxValueLength, calculateCellValue, hexToArgb, } from "../../utils/commons-utility.js";
|
|
2
|
+
import { getFilteredColumns, filterRows, updateMaxValueLength, calculateCellValue, hexToArgb, calculateValue, } from "../../utils/commons-utility.js";
|
|
4
3
|
import { exportTypeSupportsFormatting, allowedTotals, } from "./excel-converter.types.js";
|
|
5
4
|
import { isColumnHidden } from "../../utils/datastructure-utility.js";
|
|
6
|
-
import { addFooterTotalsRow, getDistinctCount, getExcelColumnLetter, initializeWorksheet, setHeaderStyling, smeupFormulaToExcelFormula, } from "./commons.js";
|
|
5
|
+
import { addFooterTotalsRow, getDistinctCount, getExcelColumnLetter, initializeWorksheet, setHeaderStyling, smeupFormulaToExcelFormula, smeupFormulaToExcelValue, } from "./commons.js";
|
|
7
6
|
export const dataTableToExcelWorkbook = (component, fileFormat, webupManagerData) => {
|
|
8
7
|
// Create a new ExcelJS.Workbook and return it as a resolved Promise
|
|
9
8
|
const { smeupDataTable: smeupDataTable, props } = component;
|
|
@@ -150,10 +149,7 @@ const insertDataTableRows = (worksheet, rows, filteredColumns, rowNumber, fileFo
|
|
|
150
149
|
const cell = (row?.cells ?? {})[column.name];
|
|
151
150
|
updateMaxValueLength(maxColumnValueLenght, cell?.value, column.name);
|
|
152
151
|
return column.formula
|
|
153
|
-
? {
|
|
154
|
-
formula: `${smeupFormulaToExcelFormula(column.formula, rowNumber, filteredColumns)}`,
|
|
155
|
-
type: ValueType.Formula,
|
|
156
|
-
}
|
|
152
|
+
? calculateValue(smeupFormulaToExcelValue(column, filteredColumns, row?.cells ?? {}), cell.obj ?? { t: "", p: "", k: "" }, fileFormat, webupManagerData)
|
|
157
153
|
: calculateCellValue(cell, fileFormat, webupManagerData);
|
|
158
154
|
});
|
|
159
155
|
const newRow = worksheet.addRow(rowData);
|
|
@@ -178,8 +174,16 @@ export const addStyleToExceljsRow = (exceljsRow, columns, row) => {
|
|
|
178
174
|
Object.keys(row.style ?? {}).length > 0) {
|
|
179
175
|
cellToXlsxStyleConverter(smeupCellWithStyle, cell, row.style);
|
|
180
176
|
}
|
|
177
|
+
else if (smeupCell) {
|
|
178
|
+
applyDefaultXlsxCellStyle(smeupCell, cell);
|
|
179
|
+
}
|
|
181
180
|
});
|
|
182
181
|
};
|
|
182
|
+
const applyDefaultXlsxCellStyle = (cell, xlsxCell) => {
|
|
183
|
+
if (typeof xlsxCell.value === "number" || xlsxCell.formula) {
|
|
184
|
+
xlsxCell.numFmt = getExcelNumFormat(cell.data?.decimals ?? 0, cell.data?.integers ?? 0);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
183
187
|
/**
|
|
184
188
|
* Converts SmeupDataCell.style attributes to ExcelJS styles
|
|
185
189
|
* @param cell SmeupDataCell - The TBL cell containing styless
|
|
@@ -187,6 +191,7 @@ export const addStyleToExceljsRow = (exceljsRow, columns, row) => {
|
|
|
187
191
|
* @returns any
|
|
188
192
|
*/
|
|
189
193
|
const cellToXlsxStyleConverter = (cell, xlsxCell, optionalRowStyles) => {
|
|
194
|
+
applyDefaultXlsxCellStyle(cell, xlsxCell);
|
|
190
195
|
const cellStyle = optionalRowStyles ?? cell?.style;
|
|
191
196
|
if (!cellStyle)
|
|
192
197
|
return;
|
|
@@ -214,9 +219,6 @@ const cellToXlsxStyleConverter = (cell, xlsxCell, optionalRowStyles) => {
|
|
|
214
219
|
color: { argb: hexToArgb(cellStyle.color) },
|
|
215
220
|
};
|
|
216
221
|
}
|
|
217
|
-
if (typeof xlsxCell.value === "number" || xlsxCell.formula) {
|
|
218
|
-
xlsxCell.numFmt = getExcelNumFormat(cell.data?.decimals ?? 0, cell.data?.integers ?? 0);
|
|
219
|
-
}
|
|
220
222
|
};
|
|
221
223
|
export const getExcelNumFormatForGroupedRow = (column, totals) => {
|
|
222
224
|
const totalOperation = totals?.[column.name];
|