@harbortouch/skytab-analytics-report-utils 0.17.0 → 0.19.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 +88 -5
- package/dist/{csv → exporters/csv}/index.cjs +1 -1
- package/dist/{csv → exporters/csv}/index.js +1 -1
- package/dist/exporters/excel/index.cjs +101 -0
- package/dist/exporters/excel/index.d.cts +15 -0
- package/dist/exporters/excel/index.d.ts +15 -0
- package/dist/exporters/excel/index.js +66 -0
- package/dist/{pdf → exporters/pdf}/index.cjs +4 -4
- package/dist/exporters/pdf/index.d.cts +18 -0
- package/dist/exporters/pdf/index.d.ts +18 -0
- package/dist/{pdf → exporters/pdf}/index.js +4 -4
- package/dist/index.cjs +1416 -3
- package/dist/index.d.cts +520 -531
- package/dist/index.d.ts +520 -531
- package/dist/index.js +1415 -3
- package/dist/types-BzLsgnfc.d.cts +15 -0
- package/dist/types-BzLsgnfc.d.ts +15 -0
- package/package.json +15 -8
- package/dist/pdf/index.d.cts +0 -29
- package/dist/pdf/index.d.ts +0 -29
- /package/dist/{csv → exporters/csv}/index.d.cts +0 -0
- /package/dist/{csv → exporters/csv}/index.d.ts +0 -0
package/README.md
CHANGED
|
@@ -111,6 +111,85 @@ fs.writeFileSync('report.pdf', buffer);
|
|
|
111
111
|
|
|
112
112
|
---
|
|
113
113
|
|
|
114
|
+
### Exporting report data to Excel
|
|
115
|
+
|
|
116
|
+
Import from the `/excel` sub-path. This keeps `exceljs` out of frontend bundles — it is only included when this import is actually used.
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { ExcelExporter } from '@harbortouch/skytab-analytics-report-utils/excel';
|
|
120
|
+
|
|
121
|
+
const exporter = new ExcelExporter();
|
|
122
|
+
|
|
123
|
+
const buffer = await exporter.generate({
|
|
124
|
+
sheets: [
|
|
125
|
+
{
|
|
126
|
+
sheetName: 'Sales Summary',
|
|
127
|
+
filters: [
|
|
128
|
+
{ label: 'Date Range', value: 'Jan 1 – Jan 31' },
|
|
129
|
+
{ label: 'Location', value: 'Downtown' },
|
|
130
|
+
],
|
|
131
|
+
table: {
|
|
132
|
+
columns: [
|
|
133
|
+
{ header: 'Item', key: 'name' },
|
|
134
|
+
{ header: 'Net Sales', key: 'netSales' },
|
|
135
|
+
{ header: 'Qty', key: 'qty' },
|
|
136
|
+
],
|
|
137
|
+
rows: reportRows,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// buffer is a Node.js Buffer containing the .xlsx binary
|
|
144
|
+
fs.writeFileSync('report.xlsx', buffer);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`ExcelExporter.generate()` returns a `Promise<Buffer>`. Each entry in `sheets` produces one worksheet tab in the workbook.
|
|
148
|
+
|
|
149
|
+
**`ExcelSheet`**
|
|
150
|
+
|
|
151
|
+
| Field | Type | Description |
|
|
152
|
+
| ----------- | --------------- | ------------------------------------------------------- |
|
|
153
|
+
| `sheetName` | `string` | Optional worksheet name (defaults to `'Report'`) |
|
|
154
|
+
| `filters` | `ExcelFilter[]` | Optional applied-filters block rendered above the table |
|
|
155
|
+
| `table` | `ExcelTable` | Optional table to render on the sheet |
|
|
156
|
+
|
|
157
|
+
**`ExcelTable`**
|
|
158
|
+
|
|
159
|
+
| Field | Type | Description |
|
|
160
|
+
| --------- | --------------------------- | ------------------------------------------ |
|
|
161
|
+
| `columns` | `ExcelTableColumn[]` | Column definitions (order preserved) |
|
|
162
|
+
| `rows` | `Record<string, unknown>[]` | Row data — keyed by `ExcelTableColumn.key` |
|
|
163
|
+
|
|
164
|
+
**`ExcelTableColumn`**
|
|
165
|
+
|
|
166
|
+
| Field | Type | Description |
|
|
167
|
+
| -------- | -------- | ------------------------------------------------------- |
|
|
168
|
+
| `header` | `string` | Column header label |
|
|
169
|
+
| `key` | `string` | Field name used to look up the value in each row object |
|
|
170
|
+
| `width` | `number` | Optional hint — auto-sized from content if omitted |
|
|
171
|
+
|
|
172
|
+
**`ExcelFilter`**
|
|
173
|
+
|
|
174
|
+
| Field | Type | Description |
|
|
175
|
+
| ------- | -------- | ------------ |
|
|
176
|
+
| `label` | `string` | Filter label |
|
|
177
|
+
| `value` | `string` | Filter value |
|
|
178
|
+
|
|
179
|
+
**Behaviour notes**
|
|
180
|
+
|
|
181
|
+
- Each `ExcelSheet` entry produces one worksheet tab in the workbook.
|
|
182
|
+
- Applied filters are rendered as `Label: value` rows above the table, separated from it by a blank row.
|
|
183
|
+
- The header row is bold with a grey fill (`#D3D3D3`) and has Excel auto-filter enabled.
|
|
184
|
+
- Alternating data rows use a light grey background (`#F5F5F5`).
|
|
185
|
+
- Numeric cell values are right-aligned; all other values are left-aligned.
|
|
186
|
+
- Column widths are auto-calculated from header and cell content; the optional `width` field overrides the auto-calculation for a specific column.
|
|
187
|
+
- `null` and `undefined` cell values are rendered as empty cells.
|
|
188
|
+
|
|
189
|
+
> **Note:** `exceljs` is a dependency of this library — consuming projects do not need to install it separately.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
114
193
|
### Exporting report data to CSV
|
|
115
194
|
|
|
116
195
|
Import from the `/csv` sub-path. This keeps `csv-stringify` out of frontend bundles — it is only included when this import is actually used.
|
|
@@ -161,11 +240,15 @@ src/
|
|
|
161
240
|
├── types.ts — Core interfaces (FieldType, ColumnPresentationConfig, ReportConfig, …)
|
|
162
241
|
├── columns/
|
|
163
242
|
│ └── index.ts — ReportColumnKey union type + COLUMN_REGISTRY (i18n keys)
|
|
164
|
-
├──
|
|
165
|
-
│
|
|
166
|
-
├──
|
|
167
|
-
│
|
|
168
|
-
│
|
|
243
|
+
├── exporters/
|
|
244
|
+
│ ├── types.ts — Shared ExportTableColumn / ExportTable / ExportFilter interfaces
|
|
245
|
+
│ ├── csv/
|
|
246
|
+
│ │ └── index.ts — CsvExporter — published as the ./csv sub-path export
|
|
247
|
+
│ ├── excel/
|
|
248
|
+
│ │ └── index.ts — ExcelExporter — published as the ./excel sub-path export
|
|
249
|
+
│ └── pdf/
|
|
250
|
+
│ ├── index.ts — PdfExporter — published as the ./pdf sub-path export
|
|
251
|
+
│ └── pdf.utils.ts — stripEmojis() helper
|
|
169
252
|
├── reports/
|
|
170
253
|
│ ├── salesSummary.ts
|
|
171
254
|
│ ├── ticketSummary.ts
|
|
@@ -17,7 +17,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
|
-
// src/csv/index.ts
|
|
20
|
+
// src/exporters/csv/index.ts
|
|
21
21
|
var csv_exports = {};
|
|
22
22
|
__export(csv_exports, {
|
|
23
23
|
CsvExporter: () => CsvExporter
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/exporters/excel/index.ts
|
|
31
|
+
var excel_exports = {};
|
|
32
|
+
__export(excel_exports, {
|
|
33
|
+
ExcelExporter: () => ExcelExporter
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(excel_exports);
|
|
36
|
+
var import_exceljs = __toESM(require("exceljs"), 1);
|
|
37
|
+
var GRAY_FILL = {
|
|
38
|
+
type: "pattern",
|
|
39
|
+
pattern: "solid",
|
|
40
|
+
fgColor: { argb: "FFD9D9D9" }
|
|
41
|
+
};
|
|
42
|
+
var toCell = (value) => {
|
|
43
|
+
if (value === null || value === void 0) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
};
|
|
51
|
+
var ExcelExporter = class {
|
|
52
|
+
async generate(content) {
|
|
53
|
+
const workbook = new import_exceljs.default.Workbook();
|
|
54
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
55
|
+
for (const section of content.sections) {
|
|
56
|
+
let sheetName = section.sheetName.slice(0, 31);
|
|
57
|
+
if (usedNames.has(sheetName.toLowerCase())) {
|
|
58
|
+
let suffix = 2;
|
|
59
|
+
let candidate = `${sheetName.slice(0, 28)}_${suffix}`;
|
|
60
|
+
while (usedNames.has(candidate.toLowerCase())) {
|
|
61
|
+
suffix++;
|
|
62
|
+
candidate = `${sheetName.slice(0, 28)}_${suffix}`;
|
|
63
|
+
}
|
|
64
|
+
sheetName = candidate;
|
|
65
|
+
}
|
|
66
|
+
usedNames.add(sheetName.toLowerCase());
|
|
67
|
+
const sheet = workbook.addWorksheet(sheetName);
|
|
68
|
+
if (section.filters && section.filters.length > 0) {
|
|
69
|
+
const titleRow = sheet.addRow(["Applied Filters"]);
|
|
70
|
+
titleRow.getCell(1).font = { bold: true };
|
|
71
|
+
titleRow.getCell(1).fill = GRAY_FILL;
|
|
72
|
+
for (const filter of section.filters) {
|
|
73
|
+
const row = sheet.addRow([filter.label, filter.value]);
|
|
74
|
+
row.getCell(1).font = { bold: true };
|
|
75
|
+
}
|
|
76
|
+
sheet.addRow([]);
|
|
77
|
+
}
|
|
78
|
+
if (section.table) {
|
|
79
|
+
const headerRow = sheet.addRow(section.table.columns.map((col) => col.header));
|
|
80
|
+
headerRow.font = { bold: true };
|
|
81
|
+
headerRow.eachCell((cell) => {
|
|
82
|
+
cell.fill = GRAY_FILL;
|
|
83
|
+
});
|
|
84
|
+
section.table.columns.forEach((col, i) => {
|
|
85
|
+
if (col.width) {
|
|
86
|
+
sheet.getColumn(i + 1).width = col.width / 7;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
for (const row of section.table.rows) {
|
|
90
|
+
sheet.addRow(section.table.columns.map((col) => toCell(row[col.key])));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const buf = await workbook.xlsx.writeBuffer();
|
|
95
|
+
return Buffer.from(buf);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
99
|
+
0 && (module.exports = {
|
|
100
|
+
ExcelExporter
|
|
101
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { E as ExportTable, a as ExportFilter } from '../../types-BzLsgnfc.cjs';
|
|
2
|
+
export { b as XlsxTableColumn } from '../../types-BzLsgnfc.cjs';
|
|
3
|
+
|
|
4
|
+
interface XlsxDocumentSection {
|
|
5
|
+
sheetName: string;
|
|
6
|
+
table?: ExportTable;
|
|
7
|
+
filters?: ExportFilter[];
|
|
8
|
+
}
|
|
9
|
+
declare class ExcelExporter {
|
|
10
|
+
generate(content: {
|
|
11
|
+
sections: XlsxDocumentSection[];
|
|
12
|
+
}): Promise<Buffer>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { ExcelExporter, type XlsxDocumentSection, ExportFilter as XlsxFilter, ExportTable as XlsxTable };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { E as ExportTable, a as ExportFilter } from '../../types-BzLsgnfc.js';
|
|
2
|
+
export { b as XlsxTableColumn } from '../../types-BzLsgnfc.js';
|
|
3
|
+
|
|
4
|
+
interface XlsxDocumentSection {
|
|
5
|
+
sheetName: string;
|
|
6
|
+
table?: ExportTable;
|
|
7
|
+
filters?: ExportFilter[];
|
|
8
|
+
}
|
|
9
|
+
declare class ExcelExporter {
|
|
10
|
+
generate(content: {
|
|
11
|
+
sections: XlsxDocumentSection[];
|
|
12
|
+
}): Promise<Buffer>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { ExcelExporter, type XlsxDocumentSection, ExportFilter as XlsxFilter, ExportTable as XlsxTable };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// src/exporters/excel/index.ts
|
|
2
|
+
import ExcelJS from "exceljs";
|
|
3
|
+
var GRAY_FILL = {
|
|
4
|
+
type: "pattern",
|
|
5
|
+
pattern: "solid",
|
|
6
|
+
fgColor: { argb: "FFD9D9D9" }
|
|
7
|
+
};
|
|
8
|
+
var toCell = (value) => {
|
|
9
|
+
if (value === null || value === void 0) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
};
|
|
17
|
+
var ExcelExporter = class {
|
|
18
|
+
async generate(content) {
|
|
19
|
+
const workbook = new ExcelJS.Workbook();
|
|
20
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
21
|
+
for (const section of content.sections) {
|
|
22
|
+
let sheetName = section.sheetName.slice(0, 31);
|
|
23
|
+
if (usedNames.has(sheetName.toLowerCase())) {
|
|
24
|
+
let suffix = 2;
|
|
25
|
+
let candidate = `${sheetName.slice(0, 28)}_${suffix}`;
|
|
26
|
+
while (usedNames.has(candidate.toLowerCase())) {
|
|
27
|
+
suffix++;
|
|
28
|
+
candidate = `${sheetName.slice(0, 28)}_${suffix}`;
|
|
29
|
+
}
|
|
30
|
+
sheetName = candidate;
|
|
31
|
+
}
|
|
32
|
+
usedNames.add(sheetName.toLowerCase());
|
|
33
|
+
const sheet = workbook.addWorksheet(sheetName);
|
|
34
|
+
if (section.filters && section.filters.length > 0) {
|
|
35
|
+
const titleRow = sheet.addRow(["Applied Filters"]);
|
|
36
|
+
titleRow.getCell(1).font = { bold: true };
|
|
37
|
+
titleRow.getCell(1).fill = GRAY_FILL;
|
|
38
|
+
for (const filter of section.filters) {
|
|
39
|
+
const row = sheet.addRow([filter.label, filter.value]);
|
|
40
|
+
row.getCell(1).font = { bold: true };
|
|
41
|
+
}
|
|
42
|
+
sheet.addRow([]);
|
|
43
|
+
}
|
|
44
|
+
if (section.table) {
|
|
45
|
+
const headerRow = sheet.addRow(section.table.columns.map((col) => col.header));
|
|
46
|
+
headerRow.font = { bold: true };
|
|
47
|
+
headerRow.eachCell((cell) => {
|
|
48
|
+
cell.fill = GRAY_FILL;
|
|
49
|
+
});
|
|
50
|
+
section.table.columns.forEach((col, i) => {
|
|
51
|
+
if (col.width) {
|
|
52
|
+
sheet.getColumn(i + 1).width = col.width / 7;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
for (const row of section.table.rows) {
|
|
56
|
+
sheet.addRow(section.table.columns.map((col) => toCell(row[col.key])));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const buf = await workbook.xlsx.writeBuffer();
|
|
61
|
+
return Buffer.from(buf);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
export {
|
|
65
|
+
ExcelExporter
|
|
66
|
+
};
|
|
@@ -27,7 +27,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
));
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
|
|
30
|
-
// src/pdf/index.ts
|
|
30
|
+
// src/exporters/pdf/index.ts
|
|
31
31
|
var pdf_exports = {};
|
|
32
32
|
__export(pdf_exports, {
|
|
33
33
|
PdfExporter: () => PdfExporter
|
|
@@ -35,7 +35,7 @@ __export(pdf_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(pdf_exports);
|
|
36
36
|
var import_pdfkit = __toESM(require("pdfkit"), 1);
|
|
37
37
|
|
|
38
|
-
// src/pdf/pdf.utils.ts
|
|
38
|
+
// src/exporters/pdf/pdf.utils.ts
|
|
39
39
|
var stripEmojis = (text) => {
|
|
40
40
|
if (!text) {
|
|
41
41
|
return text;
|
|
@@ -46,7 +46,7 @@ var stripEmojis = (text) => {
|
|
|
46
46
|
).replace(/\s+/g, " ").trim();
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
// src/pdf/index.ts
|
|
49
|
+
// src/exporters/pdf/index.ts
|
|
50
50
|
var FONT_BOLD = "Helvetica-Bold";
|
|
51
51
|
var FONT_REGULAR = "Helvetica";
|
|
52
52
|
var COLOR_BLACK = "#000000";
|
|
@@ -61,7 +61,7 @@ var PdfExporter = class {
|
|
|
61
61
|
doc.on("end", () => resolve(Buffer.concat(buffers)));
|
|
62
62
|
doc.on("error", reject);
|
|
63
63
|
try {
|
|
64
|
-
content.
|
|
64
|
+
content.sections.forEach((section, index) => {
|
|
65
65
|
const sanitizedSections = this.sanitizeSections(section);
|
|
66
66
|
if (index > 0) {
|
|
67
67
|
doc.addPage();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { E as ExportTable, a as ExportFilter, b as ExportTableColumn } from '../../types-BzLsgnfc.cjs';
|
|
2
|
+
|
|
3
|
+
interface PdfSection {
|
|
4
|
+
table?: ExportTable;
|
|
5
|
+
filters?: ExportFilter[];
|
|
6
|
+
}
|
|
7
|
+
declare class PdfExporter {
|
|
8
|
+
generate(content: {
|
|
9
|
+
sections: PdfSection[];
|
|
10
|
+
}): Promise<Buffer>;
|
|
11
|
+
private sanitizeSections;
|
|
12
|
+
drawFilters(doc: PDFKit.PDFDocument, filters: ExportFilter[]): number;
|
|
13
|
+
drawTable(doc: PDFKit.PDFDocument, table: ExportTable, startY?: number): void;
|
|
14
|
+
drawHeader(doc: PDFKit.PDFDocument, columns: ExportTableColumn[], startY: number, tableWidth: number, headerHeight: number, cellPadding: number, headerFontSize: number, minColumnWidth: number): number;
|
|
15
|
+
drawRow(doc: PDFKit.PDFDocument, row: Record<string, unknown>, rowIndex: number, columns: ExportTableColumn[], currentY: number, tableWidth: number, rowHeight: number, cellPadding: number, dataFontSize: number, minColumnWidth: number): number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { PdfExporter, ExportFilter as PdfFilter, type PdfSection, ExportTable as PdfTable, ExportTableColumn as PdfTableColumn };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { E as ExportTable, a as ExportFilter, b as ExportTableColumn } from '../../types-BzLsgnfc.js';
|
|
2
|
+
|
|
3
|
+
interface PdfSection {
|
|
4
|
+
table?: ExportTable;
|
|
5
|
+
filters?: ExportFilter[];
|
|
6
|
+
}
|
|
7
|
+
declare class PdfExporter {
|
|
8
|
+
generate(content: {
|
|
9
|
+
sections: PdfSection[];
|
|
10
|
+
}): Promise<Buffer>;
|
|
11
|
+
private sanitizeSections;
|
|
12
|
+
drawFilters(doc: PDFKit.PDFDocument, filters: ExportFilter[]): number;
|
|
13
|
+
drawTable(doc: PDFKit.PDFDocument, table: ExportTable, startY?: number): void;
|
|
14
|
+
drawHeader(doc: PDFKit.PDFDocument, columns: ExportTableColumn[], startY: number, tableWidth: number, headerHeight: number, cellPadding: number, headerFontSize: number, minColumnWidth: number): number;
|
|
15
|
+
drawRow(doc: PDFKit.PDFDocument, row: Record<string, unknown>, rowIndex: number, columns: ExportTableColumn[], currentY: number, tableWidth: number, rowHeight: number, cellPadding: number, dataFontSize: number, minColumnWidth: number): number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { PdfExporter, ExportFilter as PdfFilter, type PdfSection, ExportTable as PdfTable, ExportTableColumn as PdfTableColumn };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// src/pdf/index.ts
|
|
1
|
+
// src/exporters/pdf/index.ts
|
|
2
2
|
import PDFDocument from "pdfkit";
|
|
3
3
|
|
|
4
|
-
// src/pdf/pdf.utils.ts
|
|
4
|
+
// src/exporters/pdf/pdf.utils.ts
|
|
5
5
|
var stripEmojis = (text) => {
|
|
6
6
|
if (!text) {
|
|
7
7
|
return text;
|
|
@@ -12,7 +12,7 @@ var stripEmojis = (text) => {
|
|
|
12
12
|
).replace(/\s+/g, " ").trim();
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
// src/pdf/index.ts
|
|
15
|
+
// src/exporters/pdf/index.ts
|
|
16
16
|
var FONT_BOLD = "Helvetica-Bold";
|
|
17
17
|
var FONT_REGULAR = "Helvetica";
|
|
18
18
|
var COLOR_BLACK = "#000000";
|
|
@@ -27,7 +27,7 @@ var PdfExporter = class {
|
|
|
27
27
|
doc.on("end", () => resolve(Buffer.concat(buffers)));
|
|
28
28
|
doc.on("error", reject);
|
|
29
29
|
try {
|
|
30
|
-
content.
|
|
30
|
+
content.sections.forEach((section, index) => {
|
|
31
31
|
const sanitizedSections = this.sanitizeSections(section);
|
|
32
32
|
if (index > 0) {
|
|
33
33
|
doc.addPage();
|