@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.
- package/README.md +45 -17
- package/README_zh.md +43 -15
- package/dist/browser/index.browser.d.ts +1 -1
- package/dist/browser/index.browser.js +1 -1
- package/dist/browser/index.d.ts +2 -2
- package/dist/browser/index.js +1 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +0 -2
- package/dist/browser/modules/excel/stream/workbook-writer.d.ts +2 -2
- package/dist/browser/modules/excel/types.d.ts +0 -2
- package/dist/browser/modules/pdf/excel-bridge.d.ts +29 -0
- package/dist/browser/modules/pdf/excel-bridge.js +423 -0
- package/dist/browser/modules/pdf/index.d.ts +22 -24
- package/dist/browser/modules/pdf/index.js +22 -25
- package/dist/browser/modules/pdf/pdf.d.ts +121 -0
- package/dist/browser/modules/pdf/pdf.js +255 -0
- package/dist/browser/modules/pdf/render/layout-engine.d.ts +10 -8
- package/dist/browser/modules/pdf/render/layout-engine.js +115 -209
- package/dist/browser/modules/pdf/render/pdf-exporter.d.ts +9 -62
- package/dist/browser/modules/pdf/render/pdf-exporter.js +38 -78
- package/dist/browser/modules/pdf/render/style-converter.d.ts +20 -18
- package/dist/browser/modules/pdf/render/style-converter.js +24 -23
- package/dist/browser/modules/pdf/types.d.ts +193 -11
- package/dist/browser/modules/pdf/types.js +22 -1
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/modules/pdf/excel-bridge.js +426 -0
- package/dist/cjs/modules/pdf/index.js +25 -28
- package/dist/cjs/modules/pdf/pdf.js +258 -0
- package/dist/cjs/modules/pdf/render/layout-engine.js +116 -210
- package/dist/cjs/modules/pdf/render/pdf-exporter.js +37 -79
- package/dist/cjs/modules/pdf/render/style-converter.js +24 -23
- package/dist/cjs/modules/pdf/types.js +23 -2
- package/dist/esm/index.browser.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/modules/pdf/excel-bridge.js +423 -0
- package/dist/esm/modules/pdf/index.js +22 -25
- package/dist/esm/modules/pdf/pdf.js +255 -0
- package/dist/esm/modules/pdf/render/layout-engine.js +115 -209
- package/dist/esm/modules/pdf/render/pdf-exporter.js +38 -78
- package/dist/esm/modules/pdf/render/style-converter.js +24 -23
- package/dist/esm/modules/pdf/types.js +22 -1
- package/dist/iife/excelts.iife.js +728 -251
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +34 -34
- package/dist/types/index.browser.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +0 -2
- package/dist/types/modules/excel/stream/workbook-writer.d.ts +2 -2
- package/dist/types/modules/excel/types.d.ts +0 -2
- package/dist/types/modules/pdf/excel-bridge.d.ts +29 -0
- package/dist/types/modules/pdf/index.d.ts +22 -24
- package/dist/types/modules/pdf/pdf.d.ts +121 -0
- package/dist/types/modules/pdf/render/layout-engine.d.ts +10 -8
- package/dist/types/modules/pdf/render/pdf-exporter.d.ts +9 -62
- package/dist/types/modules/pdf/render/style-converter.d.ts +20 -18
- package/dist/types/modules/pdf/types.d.ts +193 -11
- package/package.json +1 -1
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Excel-to-PDF Bridge
|
|
3
|
+
*
|
|
4
|
+
* Converts Excel Workbook data into the PDF module's independent data model.
|
|
5
|
+
* This is the ONLY file in the PDF module that imports from @excel.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { Workbook } from "excelts";
|
|
10
|
+
* import { excelToPdf } from "excelts/pdf";
|
|
11
|
+
*
|
|
12
|
+
* const workbook = new Workbook();
|
|
13
|
+
* // ... build workbook ...
|
|
14
|
+
* const pdf = excelToPdf(workbook);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import { ValueType } from "../excel/enums.js";
|
|
18
|
+
import { formatCellValue } from "../excel/utils/cell-format.js";
|
|
19
|
+
import { base64ToUint8Array } from "../../utils/utils.base.js";
|
|
20
|
+
import { exportPdf } from "./render/pdf-exporter.js";
|
|
21
|
+
import { PdfCellType } from "./types.js";
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// Public API
|
|
24
|
+
// =============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* Export an Excel Workbook directly to PDF.
|
|
27
|
+
*
|
|
28
|
+
* This is a convenience function that converts the Workbook to the PDF module's
|
|
29
|
+
* data model and then generates the PDF.
|
|
30
|
+
*
|
|
31
|
+
* @param workbook - An Excel Workbook instance
|
|
32
|
+
* @param options - PDF export options
|
|
33
|
+
* @returns PDF file as a Uint8Array
|
|
34
|
+
*/
|
|
35
|
+
export function excelToPdf(workbook, options) {
|
|
36
|
+
const pdfWorkbook = excelWorkbookToPdf(workbook);
|
|
37
|
+
return exportPdf(pdfWorkbook, options);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Convert an Excel Workbook to the internal PdfWorkbook data structure.
|
|
41
|
+
*/
|
|
42
|
+
function excelWorkbookToPdf(workbook) {
|
|
43
|
+
return {
|
|
44
|
+
title: workbook.title || undefined,
|
|
45
|
+
creator: workbook.creator || undefined,
|
|
46
|
+
subject: workbook.subject || undefined,
|
|
47
|
+
sheets: workbook.worksheets.map(ws => convertSheet(ws, workbook))
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// =============================================================================
|
|
51
|
+
// Sheet Conversion
|
|
52
|
+
// =============================================================================
|
|
53
|
+
function convertSheet(ws, workbook) {
|
|
54
|
+
const dimensions = ws.dimensions;
|
|
55
|
+
const hasData = dimensions && dimensions.model.top > 0 && dimensions.model.left > 0;
|
|
56
|
+
const bounds = hasData
|
|
57
|
+
? {
|
|
58
|
+
top: dimensions.model.top,
|
|
59
|
+
left: dimensions.model.left,
|
|
60
|
+
bottom: dimensions.model.bottom,
|
|
61
|
+
right: dimensions.model.right
|
|
62
|
+
}
|
|
63
|
+
: { top: 0, left: 0, bottom: 0, right: 0 };
|
|
64
|
+
// Convert columns
|
|
65
|
+
const columns = new Map();
|
|
66
|
+
if (hasData) {
|
|
67
|
+
for (let c = bounds.left; c <= bounds.right; c++) {
|
|
68
|
+
const col = ws.getColumn(c);
|
|
69
|
+
columns.set(c, {
|
|
70
|
+
hidden: col.hidden || undefined,
|
|
71
|
+
width: col.width ?? undefined
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Convert rows
|
|
76
|
+
const rows = new Map();
|
|
77
|
+
if (hasData) {
|
|
78
|
+
for (let r = bounds.top; r <= bounds.bottom; r++) {
|
|
79
|
+
const row = ws.findRow(r);
|
|
80
|
+
if (!row) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const cells = new Map();
|
|
84
|
+
row.eachCell({ includeEmpty: false }, cell => {
|
|
85
|
+
cells.set(cell.col, convertCell(cell));
|
|
86
|
+
});
|
|
87
|
+
rows.set(r, {
|
|
88
|
+
hidden: row.hidden || undefined,
|
|
89
|
+
height: row.height ?? undefined,
|
|
90
|
+
cells
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Convert merges
|
|
95
|
+
const merges = ws.hasMerges && ws.model.mergeCells ? [...ws.model.mergeCells] : undefined;
|
|
96
|
+
// Convert pageSetup
|
|
97
|
+
const ps = ws.pageSetup;
|
|
98
|
+
const pageSetup = ps
|
|
99
|
+
? {
|
|
100
|
+
orientation: ps.orientation,
|
|
101
|
+
paperSize: ps.paperSize,
|
|
102
|
+
margins: ps.margins
|
|
103
|
+
? {
|
|
104
|
+
left: ps.margins.left,
|
|
105
|
+
right: ps.margins.right,
|
|
106
|
+
top: ps.margins.top,
|
|
107
|
+
bottom: ps.margins.bottom
|
|
108
|
+
}
|
|
109
|
+
: undefined,
|
|
110
|
+
scale: ps.scale,
|
|
111
|
+
printTitlesRow: ps.printTitlesRow,
|
|
112
|
+
showGridLines: ps.showGridLines,
|
|
113
|
+
printArea: ps.printArea
|
|
114
|
+
}
|
|
115
|
+
: undefined;
|
|
116
|
+
// Convert row/col breaks
|
|
117
|
+
const rowBreaks = ws.rowBreaks?.map((b) => b.id);
|
|
118
|
+
const colBreaks = ws.colBreaks?.map((b) => b.id);
|
|
119
|
+
// Convert images
|
|
120
|
+
const images = collectImages(ws, workbook);
|
|
121
|
+
// Extend bounds to cover image anchors (so layout engine includes them)
|
|
122
|
+
if (images) {
|
|
123
|
+
for (const img of images) {
|
|
124
|
+
const tl = img.range.tl;
|
|
125
|
+
const tlCol = (tl.nativeCol ?? tl.col ?? 0) + 1; // 0-indexed → 1-indexed
|
|
126
|
+
const tlRow = (tl.nativeRow ?? tl.row ?? 0) + 1;
|
|
127
|
+
if (bounds.top === 0 && bounds.left === 0) {
|
|
128
|
+
bounds.top = 1;
|
|
129
|
+
bounds.left = 1;
|
|
130
|
+
}
|
|
131
|
+
if (tlCol > bounds.right) {
|
|
132
|
+
bounds.right = tlCol;
|
|
133
|
+
}
|
|
134
|
+
if (tlRow > bounds.bottom) {
|
|
135
|
+
bounds.bottom = tlRow;
|
|
136
|
+
}
|
|
137
|
+
// Also extend to bottom-right anchor if present
|
|
138
|
+
if (img.range.br) {
|
|
139
|
+
const br = img.range.br;
|
|
140
|
+
const brCol = (br.nativeCol ?? br.col ?? 0) + 1;
|
|
141
|
+
const brRow = (br.nativeRow ?? br.row ?? 0) + 1;
|
|
142
|
+
if (brCol > bounds.right) {
|
|
143
|
+
bounds.right = brCol;
|
|
144
|
+
}
|
|
145
|
+
if (brRow > bounds.bottom) {
|
|
146
|
+
bounds.bottom = brRow;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Ensure columns/rows exist for extended bounds
|
|
151
|
+
for (let c = bounds.left; c <= bounds.right; c++) {
|
|
152
|
+
if (!columns.has(c)) {
|
|
153
|
+
const col = ws.getColumn(c);
|
|
154
|
+
columns.set(c, {
|
|
155
|
+
hidden: col.hidden || undefined,
|
|
156
|
+
width: col.width ?? undefined
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
for (let r = bounds.top; r <= bounds.bottom; r++) {
|
|
161
|
+
if (!rows.has(r)) {
|
|
162
|
+
rows.set(r, { cells: new Map() });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
name: ws.name,
|
|
168
|
+
state: ws.state ?? "visible",
|
|
169
|
+
bounds,
|
|
170
|
+
columns,
|
|
171
|
+
rows,
|
|
172
|
+
merges,
|
|
173
|
+
pageSetup,
|
|
174
|
+
rowBreaks,
|
|
175
|
+
colBreaks,
|
|
176
|
+
images
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
// =============================================================================
|
|
180
|
+
// Cell Conversion
|
|
181
|
+
// =============================================================================
|
|
182
|
+
// Use any-typed cell to avoid importing the Cell class directly
|
|
183
|
+
// (Worksheet.eachCell provides it)
|
|
184
|
+
function convertCell(cell) {
|
|
185
|
+
const type = mapValueType(cell.type);
|
|
186
|
+
const text = getCellDisplayText(cell);
|
|
187
|
+
const style = convertCellStyle(cell.style);
|
|
188
|
+
return {
|
|
189
|
+
type,
|
|
190
|
+
value: convertCellValue(cell),
|
|
191
|
+
text,
|
|
192
|
+
style,
|
|
193
|
+
hyperlink: cell.hyperlink || undefined,
|
|
194
|
+
result: cell.result ?? undefined,
|
|
195
|
+
col: cell.col
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function mapValueType(vt) {
|
|
199
|
+
switch (vt) {
|
|
200
|
+
case ValueType.Null:
|
|
201
|
+
return PdfCellType.Empty;
|
|
202
|
+
case ValueType.Merge:
|
|
203
|
+
return PdfCellType.Merge;
|
|
204
|
+
case ValueType.Number:
|
|
205
|
+
return PdfCellType.Number;
|
|
206
|
+
case ValueType.String:
|
|
207
|
+
case ValueType.SharedString:
|
|
208
|
+
return PdfCellType.String;
|
|
209
|
+
case ValueType.Date:
|
|
210
|
+
return PdfCellType.Date;
|
|
211
|
+
case ValueType.Hyperlink:
|
|
212
|
+
return PdfCellType.Hyperlink;
|
|
213
|
+
case ValueType.Formula:
|
|
214
|
+
return PdfCellType.Formula;
|
|
215
|
+
case ValueType.RichText:
|
|
216
|
+
return PdfCellType.RichText;
|
|
217
|
+
case ValueType.Boolean:
|
|
218
|
+
return PdfCellType.Boolean;
|
|
219
|
+
case ValueType.Error:
|
|
220
|
+
return PdfCellType.Error;
|
|
221
|
+
default:
|
|
222
|
+
return PdfCellType.String;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get display text for a cell, applying numFmt formatting.
|
|
227
|
+
*/
|
|
228
|
+
function getCellDisplayText(cell) {
|
|
229
|
+
if (!cell) {
|
|
230
|
+
return "";
|
|
231
|
+
}
|
|
232
|
+
switch (cell.type) {
|
|
233
|
+
case ValueType.Null:
|
|
234
|
+
case ValueType.Merge:
|
|
235
|
+
return "";
|
|
236
|
+
case ValueType.RichText:
|
|
237
|
+
case ValueType.Hyperlink:
|
|
238
|
+
return cell.text ?? "";
|
|
239
|
+
case ValueType.Error: {
|
|
240
|
+
const errValue = cell.value;
|
|
241
|
+
return errValue?.error ?? cell.text ?? "";
|
|
242
|
+
}
|
|
243
|
+
case ValueType.Formula: {
|
|
244
|
+
const result = cell.result;
|
|
245
|
+
if (result !== undefined && result !== null) {
|
|
246
|
+
if (typeof result === "object" && "error" in result) {
|
|
247
|
+
return result.error;
|
|
248
|
+
}
|
|
249
|
+
return formatCellValueSafe(result, cell.style?.numFmt);
|
|
250
|
+
}
|
|
251
|
+
return cell.text ?? "";
|
|
252
|
+
}
|
|
253
|
+
default: {
|
|
254
|
+
const value = cell.value;
|
|
255
|
+
if (value === null || value === undefined) {
|
|
256
|
+
return "";
|
|
257
|
+
}
|
|
258
|
+
return formatCellValueSafe(value, cell.style?.numFmt);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function formatCellValueSafe(value, numFmt) {
|
|
263
|
+
const fmt = typeof numFmt === "string" ? numFmt : numFmt?.formatCode;
|
|
264
|
+
if (fmt && (typeof value === "number" || value instanceof Date || typeof value === "boolean")) {
|
|
265
|
+
try {
|
|
266
|
+
return formatCellValue(value, fmt);
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
// Fall through to default
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (value instanceof Date) {
|
|
273
|
+
return value.toLocaleDateString();
|
|
274
|
+
}
|
|
275
|
+
return String(value);
|
|
276
|
+
}
|
|
277
|
+
function convertCellValue(cell) {
|
|
278
|
+
if (cell.type === ValueType.RichText) {
|
|
279
|
+
// Preserve richText structure for the PDF engine
|
|
280
|
+
const rtValue = cell.value;
|
|
281
|
+
if (rtValue?.richText) {
|
|
282
|
+
return {
|
|
283
|
+
richText: rtValue.richText.map((run) => ({
|
|
284
|
+
text: run.text,
|
|
285
|
+
font: run.font ? convertFontStyle(run.font) : undefined
|
|
286
|
+
}))
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return cell.value;
|
|
291
|
+
}
|
|
292
|
+
// =============================================================================
|
|
293
|
+
// Style Conversion
|
|
294
|
+
// =============================================================================
|
|
295
|
+
function convertCellStyle(style) {
|
|
296
|
+
if (!style) {
|
|
297
|
+
return undefined;
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
font: style.font ? convertFontStyle(style.font) : undefined,
|
|
301
|
+
numFmt: style.numFmt,
|
|
302
|
+
fill: style.fill ? convertFill(style.fill) : undefined,
|
|
303
|
+
border: style.border ? convertBorders(style.border) : undefined,
|
|
304
|
+
alignment: style.alignment ? convertAlignment(style.alignment) : undefined
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function convertFontStyle(font) {
|
|
308
|
+
return {
|
|
309
|
+
name: font.name,
|
|
310
|
+
size: font.size,
|
|
311
|
+
bold: font.bold,
|
|
312
|
+
italic: font.italic,
|
|
313
|
+
strike: font.strike,
|
|
314
|
+
underline: font.underline,
|
|
315
|
+
color: font.color ? convertColor(font.color) : undefined
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function convertColor(color) {
|
|
319
|
+
return {
|
|
320
|
+
argb: color.argb,
|
|
321
|
+
theme: color.theme,
|
|
322
|
+
tint: color.tint
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
function convertFill(fill) {
|
|
326
|
+
const result = {
|
|
327
|
+
type: fill.type ?? "pattern",
|
|
328
|
+
pattern: fill.pattern,
|
|
329
|
+
fgColor: fill.fgColor ? convertColor(fill.fgColor) : undefined
|
|
330
|
+
};
|
|
331
|
+
if (fill.stops) {
|
|
332
|
+
result.stops = fill.stops.map((s) => ({
|
|
333
|
+
color: convertColor(s.color)
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
338
|
+
function convertBorderSide(border) {
|
|
339
|
+
return {
|
|
340
|
+
style: border.style,
|
|
341
|
+
color: border.color ? convertColor(border.color) : undefined
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
function convertBorders(borders) {
|
|
345
|
+
return {
|
|
346
|
+
top: borders.top ? convertBorderSide(borders.top) : undefined,
|
|
347
|
+
right: borders.right ? convertBorderSide(borders.right) : undefined,
|
|
348
|
+
bottom: borders.bottom ? convertBorderSide(borders.bottom) : undefined,
|
|
349
|
+
left: borders.left ? convertBorderSide(borders.left) : undefined
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function convertAlignment(alignment) {
|
|
353
|
+
return {
|
|
354
|
+
horizontal: alignment.horizontal,
|
|
355
|
+
vertical: alignment.vertical,
|
|
356
|
+
wrapText: alignment.wrapText,
|
|
357
|
+
indent: alignment.indent,
|
|
358
|
+
textRotation: alignment.textRotation
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
// =============================================================================
|
|
362
|
+
// Image Collection
|
|
363
|
+
// =============================================================================
|
|
364
|
+
function collectImages(ws, workbook) {
|
|
365
|
+
const wsImages = ws.getImages?.();
|
|
366
|
+
if (!wsImages || !Array.isArray(wsImages) || wsImages.length === 0) {
|
|
367
|
+
return undefined;
|
|
368
|
+
}
|
|
369
|
+
const images = [];
|
|
370
|
+
for (const wsImage of wsImages) {
|
|
371
|
+
if (!wsImage.range?.tl) {
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
const imageId = wsImage.imageId;
|
|
375
|
+
const mediaItem = workbook.getImage?.(Number(imageId));
|
|
376
|
+
if (!mediaItem) {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
// Get image data
|
|
380
|
+
let data;
|
|
381
|
+
if (mediaItem.buffer instanceof Uint8Array) {
|
|
382
|
+
data = mediaItem.buffer;
|
|
383
|
+
}
|
|
384
|
+
else if (mediaItem.base64) {
|
|
385
|
+
data = base64ToUint8Array(mediaItem.base64);
|
|
386
|
+
}
|
|
387
|
+
if (!data || data.length === 0) {
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
const format = mediaItem.extension;
|
|
391
|
+
if (format !== "jpeg" && format !== "png") {
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
images.push({
|
|
395
|
+
data,
|
|
396
|
+
format: format,
|
|
397
|
+
range: {
|
|
398
|
+
tl: {
|
|
399
|
+
col: wsImage.range.tl.col ?? 0,
|
|
400
|
+
row: wsImage.range.tl.row ?? 0,
|
|
401
|
+
nativeCol: wsImage.range.tl.nativeCol,
|
|
402
|
+
nativeRow: wsImage.range.tl.nativeRow,
|
|
403
|
+
nativeColOff: wsImage.range.tl.nativeColOff,
|
|
404
|
+
nativeRowOff: wsImage.range.tl.nativeRowOff
|
|
405
|
+
},
|
|
406
|
+
br: wsImage.range.br
|
|
407
|
+
? {
|
|
408
|
+
col: wsImage.range.br.col ?? 0,
|
|
409
|
+
row: wsImage.range.br.row ?? 0,
|
|
410
|
+
nativeCol: wsImage.range.br.nativeCol,
|
|
411
|
+
nativeRow: wsImage.range.br.nativeRow,
|
|
412
|
+
nativeColOff: wsImage.range.br.nativeColOff,
|
|
413
|
+
nativeRowOff: wsImage.range.br.nativeRowOff
|
|
414
|
+
}
|
|
415
|
+
: undefined,
|
|
416
|
+
ext: wsImage.range.ext
|
|
417
|
+
? { width: wsImage.range.ext.width, height: wsImage.range.ext.height }
|
|
418
|
+
: undefined
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
return images.length > 0 ? images : undefined;
|
|
423
|
+
}
|
|
@@ -1,42 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* PDF module for excelts.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* Supports cell values, fonts, colors, borders, fills, alignment,
|
|
6
|
-
* merged cells, pagination, and customizable page layout.
|
|
4
|
+
* A full-featured, zero-dependency PDF engine.
|
|
7
5
|
*
|
|
8
|
-
* @example
|
|
6
|
+
* @example Standalone:
|
|
9
7
|
* ```typescript
|
|
10
|
-
* import {
|
|
8
|
+
* import { pdf } from "excelts/pdf";
|
|
11
9
|
*
|
|
12
|
-
* const
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* sheet.addRow({ product: "Widget", revenue: 1000 });
|
|
10
|
+
* const bytes = pdf([
|
|
11
|
+
* ["Product", "Revenue"],
|
|
12
|
+
* ["Widget", 1000],
|
|
13
|
+
* ["Gadget", 2500]
|
|
14
|
+
* ]);
|
|
15
|
+
* ```
|
|
19
16
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* fitToPage: true,
|
|
25
|
-
* showGridLines: true,
|
|
26
|
-
* showPageNumbers: true
|
|
27
|
-
* });
|
|
17
|
+
* @example From Excel Workbook:
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { Workbook } from "excelts";
|
|
20
|
+
* import { excelToPdf } from "excelts/pdf";
|
|
28
21
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
22
|
+
* const workbook = new Workbook();
|
|
23
|
+
* const sheet = workbook.addWorksheet("Sales");
|
|
24
|
+
* sheet.addRow(["Product", "Revenue"]);
|
|
25
|
+
* const bytes = excelToPdf(workbook);
|
|
32
26
|
* ```
|
|
33
27
|
*
|
|
34
28
|
* @module pdf
|
|
35
29
|
*/
|
|
36
30
|
// =============================================================================
|
|
37
|
-
//
|
|
31
|
+
// Public API
|
|
38
32
|
// =============================================================================
|
|
39
|
-
|
|
33
|
+
/** Standalone PDF generation — accepts plain arrays, sheet objects, or workbooks. */
|
|
34
|
+
export { pdf } from "./pdf.js";
|
|
35
|
+
/** Excel-to-PDF conversion — accepts an Excel Workbook instance. */
|
|
36
|
+
export { excelToPdf } from "./excel-bridge.js";
|
|
40
37
|
export { PageSizes } from "./types.js";
|
|
41
38
|
// =============================================================================
|
|
42
39
|
// Errors
|