@cj-tech-master/excelts 6.2.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +45 -17
  2. package/README_zh.md +43 -15
  3. package/dist/browser/index.browser.d.ts +1 -1
  4. package/dist/browser/index.browser.js +1 -1
  5. package/dist/browser/index.d.ts +2 -2
  6. package/dist/browser/index.js +1 -1
  7. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +0 -2
  8. package/dist/browser/modules/excel/stream/workbook-writer.d.ts +2 -2
  9. package/dist/browser/modules/excel/types.d.ts +0 -2
  10. package/dist/browser/modules/pdf/excel-bridge.d.ts +29 -0
  11. package/dist/browser/modules/pdf/excel-bridge.js +423 -0
  12. package/dist/browser/modules/pdf/index.d.ts +22 -24
  13. package/dist/browser/modules/pdf/index.js +22 -25
  14. package/dist/browser/modules/pdf/pdf.d.ts +121 -0
  15. package/dist/browser/modules/pdf/pdf.js +255 -0
  16. package/dist/browser/modules/pdf/render/layout-engine.d.ts +10 -8
  17. package/dist/browser/modules/pdf/render/layout-engine.js +115 -209
  18. package/dist/browser/modules/pdf/render/pdf-exporter.d.ts +9 -62
  19. package/dist/browser/modules/pdf/render/pdf-exporter.js +38 -78
  20. package/dist/browser/modules/pdf/render/style-converter.d.ts +20 -18
  21. package/dist/browser/modules/pdf/render/style-converter.js +24 -23
  22. package/dist/browser/modules/pdf/types.d.ts +193 -11
  23. package/dist/browser/modules/pdf/types.js +22 -1
  24. package/dist/cjs/index.js +3 -3
  25. package/dist/cjs/modules/pdf/excel-bridge.js +426 -0
  26. package/dist/cjs/modules/pdf/index.js +25 -28
  27. package/dist/cjs/modules/pdf/pdf.js +258 -0
  28. package/dist/cjs/modules/pdf/render/layout-engine.js +116 -210
  29. package/dist/cjs/modules/pdf/render/pdf-exporter.js +37 -79
  30. package/dist/cjs/modules/pdf/render/style-converter.js +24 -23
  31. package/dist/cjs/modules/pdf/types.js +23 -2
  32. package/dist/esm/index.browser.js +1 -1
  33. package/dist/esm/index.js +1 -1
  34. package/dist/esm/modules/pdf/excel-bridge.js +423 -0
  35. package/dist/esm/modules/pdf/index.js +22 -25
  36. package/dist/esm/modules/pdf/pdf.js +255 -0
  37. package/dist/esm/modules/pdf/render/layout-engine.js +115 -209
  38. package/dist/esm/modules/pdf/render/pdf-exporter.js +38 -78
  39. package/dist/esm/modules/pdf/render/style-converter.js +24 -23
  40. package/dist/esm/modules/pdf/types.js +22 -1
  41. package/dist/iife/excelts.iife.js +728 -251
  42. package/dist/iife/excelts.iife.js.map +1 -1
  43. package/dist/iife/excelts.iife.min.js +34 -34
  44. package/dist/types/index.browser.d.ts +1 -1
  45. package/dist/types/index.d.ts +2 -2
  46. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +0 -2
  47. package/dist/types/modules/excel/stream/workbook-writer.d.ts +2 -2
  48. package/dist/types/modules/excel/types.d.ts +0 -2
  49. package/dist/types/modules/pdf/excel-bridge.d.ts +29 -0
  50. package/dist/types/modules/pdf/index.d.ts +22 -24
  51. package/dist/types/modules/pdf/pdf.d.ts +121 -0
  52. package/dist/types/modules/pdf/render/layout-engine.d.ts +10 -8
  53. package/dist/types/modules/pdf/render/pdf-exporter.d.ts +9 -62
  54. package/dist/types/modules/pdf/render/style-converter.d.ts +20 -18
  55. package/dist/types/modules/pdf/types.d.ts +193 -11
  56. package/package.json +1 -1
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ /**
3
+ * Simplified PDF generation API.
4
+ *
5
+ * Provides a concise way to create PDFs from plain data — no need to manually
6
+ * construct Map objects, compute bounds, or specify cell types.
7
+ *
8
+ * @example Simplest — pass a 2D array:
9
+ * ```typescript
10
+ * import { pdf } from "@cj-tech-master/excelts/pdf";
11
+ *
12
+ * const bytes = pdf([
13
+ * ["Product", "Revenue"],
14
+ * ["Widget", 1000],
15
+ * ["Gadget", 2500]
16
+ * ]);
17
+ * ```
18
+ *
19
+ * @example With options:
20
+ * ```typescript
21
+ * const bytes = pdf([
22
+ * ["Name", "Score"],
23
+ * ["Alice", 95],
24
+ * ["Bob", 87]
25
+ * ], { showGridLines: true, title: "Scores" });
26
+ * ```
27
+ *
28
+ * @example Multiple sheets:
29
+ * ```typescript
30
+ * const bytes = pdf({
31
+ * sheets: [
32
+ * { name: "Sales", data: [["Product", "Revenue"], ["Widget", 1000]] },
33
+ * { name: "Costs", data: [["Item", "Amount"], ["Rent", 500]] }
34
+ * ]
35
+ * });
36
+ * ```
37
+ *
38
+ * @example With column widths and styles:
39
+ * ```typescript
40
+ * const bytes = pdf({
41
+ * name: "Report",
42
+ * columns: [{ width: 25 }, { width: 15 }],
43
+ * data: [
44
+ * ["Product", "Revenue"],
45
+ * ["Widget", "$1,000"]
46
+ * ]
47
+ * });
48
+ * ```
49
+ */
50
+ Object.defineProperty(exports, "__esModule", { value: true });
51
+ exports.pdf = pdf;
52
+ const types_1 = require("./types");
53
+ const pdf_exporter_1 = require("./render/pdf-exporter");
54
+ // =============================================================================
55
+ // Public API
56
+ // =============================================================================
57
+ /**
58
+ * Generate a PDF.
59
+ *
60
+ * Accepts anything from a plain 2D array to a multi-sheet workbook.
61
+ *
62
+ * @param input - 2D array, sheet object, or workbook object
63
+ * @param options - PDF export options (page size, margins, etc.)
64
+ * @returns PDF file as Uint8Array
65
+ */
66
+ function pdf(input, options) {
67
+ const workbook = normalizeInput(input);
68
+ return (0, pdf_exporter_1.exportPdf)(workbook, options);
69
+ }
70
+ // =============================================================================
71
+ // Normalization
72
+ // =============================================================================
73
+ function normalizeInput(input) {
74
+ // 2D array → single sheet
75
+ if (Array.isArray(input)) {
76
+ return {
77
+ sheets: [normalizeSheet({ data: input })]
78
+ };
79
+ }
80
+ // Workbook with sheets array
81
+ if ("sheets" in input) {
82
+ return {
83
+ title: input.title,
84
+ creator: input.author,
85
+ sheets: input.sheets.map((s, i) => normalizeSheet(s, i))
86
+ };
87
+ }
88
+ // Single sheet object
89
+ return {
90
+ sheets: [normalizeSheet(input)]
91
+ };
92
+ }
93
+ function normalizeSheet(sheet, index) {
94
+ const data = sheet.data;
95
+ const sheetName = sheet.name ?? `Sheet${(index ?? 0) + 1}`;
96
+ // Check if columns have headers
97
+ const columnHeaders = sheet.columns?.map(c => (typeof c === "number" ? undefined : c.header));
98
+ const hasHeaders = columnHeaders?.some(h => h !== undefined) ?? false;
99
+ // Determine dimensions — consider data rows, column definitions, and images
100
+ let maxCols = 0;
101
+ for (const row of data) {
102
+ if (row.length > maxCols) {
103
+ maxCols = row.length;
104
+ }
105
+ }
106
+ let colCount = Math.max(maxCols, sheet.columns?.length ?? 0);
107
+ let totalRows = data.length + (hasHeaders ? 1 : 0);
108
+ // Pre-scan images to extend bounds before the empty check
109
+ if (sheet.images) {
110
+ for (const img of sheet.images) {
111
+ const imgCol = img.col + 1; // 0-indexed → 1-indexed
112
+ const imgRow = img.row + 1;
113
+ if (imgCol > colCount) {
114
+ colCount = imgCol;
115
+ }
116
+ if (imgRow > totalRows) {
117
+ totalRows = imgRow;
118
+ }
119
+ }
120
+ }
121
+ if (colCount === 0) {
122
+ return {
123
+ name: sheetName,
124
+ bounds: { top: 0, left: 0, bottom: 0, right: 0 },
125
+ columns: new Map(),
126
+ rows: new Map()
127
+ };
128
+ }
129
+ // Build columns
130
+ const columns = new Map();
131
+ if (sheet.columns) {
132
+ for (let i = 0; i < sheet.columns.length; i++) {
133
+ const col = sheet.columns[i];
134
+ const width = typeof col === "number" ? col : col.width;
135
+ columns.set(i + 1, { width: width ?? 12 });
136
+ }
137
+ }
138
+ // Fill missing columns with default width
139
+ for (let c = 1; c <= colCount; c++) {
140
+ if (!columns.has(c)) {
141
+ columns.set(c, { width: 12 });
142
+ }
143
+ }
144
+ // Build rows
145
+ const rows = new Map();
146
+ let rowOffset = 1;
147
+ // Insert column headers as the first row if provided
148
+ if (hasHeaders && columnHeaders) {
149
+ const cells = new Map();
150
+ for (let c = 0; c < columnHeaders.length; c++) {
151
+ const text = columnHeaders[c];
152
+ if (text === undefined) {
153
+ continue;
154
+ }
155
+ cells.set(c + 1, {
156
+ type: types_1.PdfCellType.String,
157
+ value: text,
158
+ text,
159
+ col: c + 1,
160
+ style: { font: { bold: true } }
161
+ });
162
+ }
163
+ rows.set(1, { cells });
164
+ rowOffset = 2;
165
+ }
166
+ // Insert data rows
167
+ for (let r = 0; r < data.length; r++) {
168
+ const rowNum = r + rowOffset;
169
+ const row = data[r];
170
+ const cells = new Map();
171
+ for (let c = 0; c < row.length; c++) {
172
+ const cell = normalizeCell(row[c], c + 1);
173
+ if (cell) {
174
+ cells.set(c + 1, cell);
175
+ }
176
+ }
177
+ rows.set(rowNum, { cells });
178
+ }
179
+ // Normalize images
180
+ let images;
181
+ if (sheet.images && sheet.images.length > 0) {
182
+ images = sheet.images.map(img => ({
183
+ data: img.data,
184
+ format: img.format,
185
+ range: {
186
+ tl: { col: img.col, row: img.row },
187
+ ext: { width: img.width, height: img.height }
188
+ }
189
+ }));
190
+ // Ensure columns and rows exist for the image-extended bounds
191
+ for (let c = 1; c <= colCount; c++) {
192
+ if (!columns.has(c)) {
193
+ columns.set(c, { width: 12 });
194
+ }
195
+ }
196
+ for (let r = 1; r <= totalRows; r++) {
197
+ if (!rows.has(r)) {
198
+ rows.set(r, { cells: new Map() });
199
+ }
200
+ }
201
+ }
202
+ return {
203
+ name: sheetName,
204
+ bounds: { top: 1, left: 1, bottom: totalRows, right: colCount },
205
+ columns,
206
+ rows,
207
+ images
208
+ };
209
+ }
210
+ function normalizeCell(value, col) {
211
+ if (value === null || value === undefined) {
212
+ return null;
213
+ }
214
+ // Styled cell object
215
+ if (typeof value === "object" && !(value instanceof Date) && "value" in value) {
216
+ const cell = value;
217
+ const inner = normalizeCell(cell.value, col);
218
+ if (!inner) {
219
+ return null;
220
+ }
221
+ // Apply style overrides
222
+ const style = {};
223
+ if (cell.bold || cell.italic || cell.fontSize || cell.fontColor) {
224
+ style.font = {
225
+ bold: cell.bold,
226
+ italic: cell.italic,
227
+ size: cell.fontSize,
228
+ color: cell.fontColor ? { argb: cell.fontColor } : undefined
229
+ };
230
+ }
231
+ if (cell.fillColor) {
232
+ style.fill = {
233
+ type: "pattern",
234
+ pattern: "solid",
235
+ fgColor: { argb: cell.fillColor }
236
+ };
237
+ }
238
+ if (cell.align) {
239
+ style.alignment = { horizontal: cell.align };
240
+ }
241
+ inner.style = style;
242
+ return inner;
243
+ }
244
+ // Primitive values
245
+ if (typeof value === "string") {
246
+ return { type: types_1.PdfCellType.String, value, text: value, col };
247
+ }
248
+ if (typeof value === "number") {
249
+ return { type: types_1.PdfCellType.Number, value, text: String(value), col };
250
+ }
251
+ if (typeof value === "boolean") {
252
+ return { type: types_1.PdfCellType.Boolean, value, text: value ? "TRUE" : "FALSE", col };
253
+ }
254
+ if (value instanceof Date) {
255
+ return { type: types_1.PdfCellType.Date, value, text: value.toLocaleDateString(), col };
256
+ }
257
+ return null;
258
+ }