jspdf-utils 0.1.7 → 0.1.9
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/dist/html-to-pdf.d.ts +60 -3
- package/dist/html-to-pdf.js +399 -166
- package/package.json +1 -1
package/dist/html-to-pdf.d.ts
CHANGED
|
@@ -58,7 +58,11 @@ declare function splitOversizedTables(container: HTMLElement, pageContentPx: num
|
|
|
58
58
|
* into word-boundary chunks using binary search.
|
|
59
59
|
*/
|
|
60
60
|
declare function splitOversizedText(container: HTMLElement, pageContentPx: number): void;
|
|
61
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* Insert spacer divs so that no direct child straddles a page boundary.
|
|
63
|
+
* For tables and text elements, attempts to split at the boundary first
|
|
64
|
+
* so content fills the current page before flowing to the next.
|
|
65
|
+
*/
|
|
62
66
|
declare function insertPageBreakSpacers(container: HTMLElement, pageContentPx: number): void;
|
|
63
67
|
/**
|
|
64
68
|
* Prepare an HTML element for doc.html() rendering.
|
|
@@ -70,11 +74,55 @@ declare function prepare(source: HTMLElement, opts?: Partial<PageOptions>): Prep
|
|
|
70
74
|
/**
|
|
71
75
|
* Render an HTML element to PDF using doc.html().
|
|
72
76
|
*/
|
|
73
|
-
declare function renderHTML(doc: jsPDF, source: HTMLElement, opts?: Partial<PageOptions>): Promise<jsPDF>;
|
|
77
|
+
declare function renderHTML(doc: jsPDF, source: HTMLElement, opts?: Partial<PageOptions> & Pick<ImagePDFOptions, "marginContent">): Promise<jsPDF>;
|
|
78
|
+
type MarginFactory = (page: number, totalPages: number) => HTMLElement;
|
|
79
|
+
export interface ContentBorder {
|
|
80
|
+
/** Stroke color (default: "#000000") */
|
|
81
|
+
color?: string;
|
|
82
|
+
/** Line width in mm (default: 0.3) */
|
|
83
|
+
width?: number;
|
|
84
|
+
/** Distance in mm from the page edge to the border (default: uses page margins). */
|
|
85
|
+
margin?: number | {
|
|
86
|
+
top?: number;
|
|
87
|
+
right?: number;
|
|
88
|
+
bottom?: number;
|
|
89
|
+
left?: number;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export interface TextBorder {
|
|
93
|
+
/** The text to repeat along all four edges. */
|
|
94
|
+
text: string;
|
|
95
|
+
/** Text color (default: "#000000") */
|
|
96
|
+
color?: string;
|
|
97
|
+
/** Font size in mm (default: 2.5) */
|
|
98
|
+
fontSize?: number;
|
|
99
|
+
/** Font family (default: "Arial, sans-serif") */
|
|
100
|
+
fontFamily?: string;
|
|
101
|
+
/** Gap between repetitions in mm (default: fontSize * 0.5) */
|
|
102
|
+
gap?: number;
|
|
103
|
+
/** Distance in mm from the page edge to the text border (default: uses page margins). */
|
|
104
|
+
margin?: number | {
|
|
105
|
+
top?: number;
|
|
106
|
+
right?: number;
|
|
107
|
+
bottom?: number;
|
|
108
|
+
left?: number;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export interface MarginContentInput {
|
|
112
|
+
top?: HTMLElement | MarginFactory;
|
|
113
|
+
right?: HTMLElement | MarginFactory;
|
|
114
|
+
bottom?: HTMLElement | MarginFactory;
|
|
115
|
+
left?: HTMLElement | MarginFactory;
|
|
116
|
+
/** Draw a rectangle border around the content area. */
|
|
117
|
+
contentBorder?: ContentBorder;
|
|
118
|
+
/** Draw a repeated-text border around the content area. */
|
|
119
|
+
textBorder?: TextBorder;
|
|
120
|
+
}
|
|
74
121
|
export interface ImagePDFOptions {
|
|
75
122
|
imageFormat?: "JPEG" | "PNG";
|
|
76
123
|
imageQuality?: number;
|
|
77
124
|
scale?: number;
|
|
125
|
+
marginContent?: MarginContentInput;
|
|
78
126
|
}
|
|
79
127
|
/**
|
|
80
128
|
* Render an HTML element as an image-based PDF. Each page is a rasterized
|
|
@@ -92,4 +140,13 @@ declare function renderPageImages(source: HTMLElement, opts?: Partial<PageOption
|
|
|
92
140
|
* container. Each image is sized to match the page format dimensions.
|
|
93
141
|
*/
|
|
94
142
|
declare function previewPageImages(source: HTMLElement, container: HTMLElement, opts?: Partial<PageOptions> & ImagePDFOptions): Promise<void>;
|
|
95
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Add HTML content to the margin areas of each page in a jsPDF document.
|
|
145
|
+
*
|
|
146
|
+
* Each slot (top, right, bottom, left) accepts either a static HTMLElement
|
|
147
|
+
* (rendered once and reused on every page) or a factory function that
|
|
148
|
+
* receives `(page, totalPages)` and returns an HTMLElement per page
|
|
149
|
+
* (useful for page numbers or dynamic content).
|
|
150
|
+
*/
|
|
151
|
+
declare function addMarginContent(doc: jsPDF, content: MarginContentInput, opts?: Partial<PageOptions>): Promise<jsPDF>;
|
|
152
|
+
export { PAGE_SIZES, PAGE_MARGINS, computeLayout, createPrintClone, normalizeTableAttributes, splitOversizedTables, splitOversizedText, insertPageBreakSpacers, prepare, renderHTML, renderImagePDF, renderPageImages, previewPageImages, addMarginContent, };
|
package/dist/html-to-pdf.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
const
|
|
1
|
+
import W from "html2canvas";
|
|
2
|
+
const q = {
|
|
3
3
|
a0: [841, 1189],
|
|
4
4
|
a1: [594, 841],
|
|
5
5
|
a2: [420, 594],
|
|
@@ -10,7 +10,7 @@ const k = {
|
|
|
10
10
|
letter: [215.9, 279.4],
|
|
11
11
|
legal: [215.9, 355.6],
|
|
12
12
|
tabloid: [279.4, 431.8]
|
|
13
|
-
},
|
|
13
|
+
}, $ = {
|
|
14
14
|
a0: 40,
|
|
15
15
|
a1: 35,
|
|
16
16
|
a2: 30,
|
|
@@ -22,28 +22,28 @@ const k = {
|
|
|
22
22
|
legal: 25.4,
|
|
23
23
|
tabloid: 25
|
|
24
24
|
};
|
|
25
|
-
function
|
|
26
|
-
const e =
|
|
27
|
-
top:
|
|
28
|
-
right:
|
|
29
|
-
bottom:
|
|
30
|
-
left:
|
|
25
|
+
function M(t = {}) {
|
|
26
|
+
const e = t.format ?? "a4", [a, n] = q[e], i = t.pageWidth ?? a, o = t.pageHeight ?? n, s = $[e], r = {
|
|
27
|
+
top: s,
|
|
28
|
+
right: s,
|
|
29
|
+
bottom: s,
|
|
30
|
+
left: s
|
|
31
31
|
};
|
|
32
32
|
return {
|
|
33
|
-
unit:
|
|
33
|
+
unit: t.unit ?? "mm",
|
|
34
34
|
format: e,
|
|
35
|
-
pageWidth:
|
|
36
|
-
pageHeight:
|
|
37
|
-
margin: { ...
|
|
35
|
+
pageWidth: i,
|
|
36
|
+
pageHeight: o,
|
|
37
|
+
margin: { ...r, ...t.margin }
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
function
|
|
41
|
-
const
|
|
42
|
-
return { renderedWidth:
|
|
40
|
+
function x(t, e) {
|
|
41
|
+
const a = t.offsetWidth, n = e.pageWidth - e.margin.left - e.margin.right, i = n / a, s = (e.pageHeight - e.margin.top - e.margin.bottom) / i;
|
|
42
|
+
return { renderedWidth: a, scale: i, contentWidthMm: n, pageContentPx: s };
|
|
43
43
|
}
|
|
44
|
-
function
|
|
45
|
-
const
|
|
46
|
-
return Object.assign(
|
|
44
|
+
function B(t, e = 210) {
|
|
45
|
+
const a = t.cloneNode(!0);
|
|
46
|
+
return Object.assign(a.style, {
|
|
47
47
|
position: "fixed",
|
|
48
48
|
top: "0",
|
|
49
49
|
left: "0",
|
|
@@ -51,224 +51,429 @@ function A(i, e = 210) {
|
|
|
51
51
|
width: e + "mm",
|
|
52
52
|
opacity: "0.000001",
|
|
53
53
|
pointerEvents: "none"
|
|
54
|
-
}), document.body.appendChild(
|
|
54
|
+
}), document.body.appendChild(a), a;
|
|
55
55
|
}
|
|
56
|
-
function
|
|
57
|
-
const
|
|
58
|
-
return
|
|
56
|
+
function N() {
|
|
57
|
+
const t = document.createElement("style");
|
|
58
|
+
return t.setAttribute("data-jspdf-utils", ""), t.textContent = "img { display: inline !important; }", document.head.appendChild(t), () => t.remove();
|
|
59
59
|
}
|
|
60
|
-
function E(
|
|
61
|
-
for (const e of
|
|
62
|
-
const
|
|
63
|
-
if (
|
|
60
|
+
function E(t) {
|
|
61
|
+
for (const e of t.querySelectorAll("table")) {
|
|
62
|
+
const a = e.getAttribute("cellpadding");
|
|
63
|
+
if (a) {
|
|
64
64
|
for (const n of e.querySelectorAll("th, td"))
|
|
65
|
-
n.style.padding || (n.style.padding =
|
|
65
|
+
n.style.padding || (n.style.padding = a + "px");
|
|
66
66
|
e.removeAttribute("cellpadding");
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
function
|
|
71
|
-
for (const
|
|
72
|
-
|
|
70
|
+
function T(t, e) {
|
|
71
|
+
for (const a of Array.from(
|
|
72
|
+
t.querySelectorAll(":scope > table")
|
|
73
73
|
)) {
|
|
74
|
-
if (
|
|
75
|
-
const n = Array.from(
|
|
74
|
+
if (a.offsetHeight <= e) continue;
|
|
75
|
+
const n = Array.from(a.rows);
|
|
76
76
|
if (n.length === 0) continue;
|
|
77
|
-
const
|
|
78
|
-
let
|
|
79
|
-
for (const m of
|
|
80
|
-
const
|
|
81
|
-
g +
|
|
77
|
+
const i = n[0].querySelector("th") !== null, o = i ? n[0] : null, s = i ? n.slice(1) : n, r = o ? o.offsetHeight : 0, l = e - r - 2, d = [];
|
|
78
|
+
let c = [], g = 0;
|
|
79
|
+
for (const m of s) {
|
|
80
|
+
const h = m.offsetHeight;
|
|
81
|
+
g + h > l && c.length > 0 && (d.push(c), c = [], g = 0), c.push(m), g += h;
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
c.length > 0 && d.push(c);
|
|
84
84
|
for (const m of d) {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
for (const f of m)
|
|
88
|
-
|
|
85
|
+
const h = a.cloneNode(!1);
|
|
86
|
+
o && h.appendChild(o.cloneNode(!0));
|
|
87
|
+
for (const f of m) h.appendChild(f.cloneNode(!0));
|
|
88
|
+
a.parentNode.insertBefore(h, a);
|
|
89
89
|
}
|
|
90
|
-
|
|
90
|
+
a.remove();
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
function
|
|
94
|
-
for (const
|
|
95
|
-
const n =
|
|
93
|
+
function R(t, e) {
|
|
94
|
+
for (const a of Array.from(t.querySelectorAll(":scope > *"))) {
|
|
95
|
+
const n = a;
|
|
96
96
|
if (n.offsetHeight <= e || n.tagName === "TABLE")
|
|
97
97
|
continue;
|
|
98
|
-
const
|
|
99
|
-
|
|
98
|
+
const i = n.tagName, o = n.getAttribute("style") || "", s = getComputedStyle(n).width, r = (n.textContent || "").split(/\s+/).filter(Boolean), l = document.createElement(i);
|
|
99
|
+
l.setAttribute("style", o), Object.assign(l.style, {
|
|
100
100
|
position: "absolute",
|
|
101
101
|
visibility: "hidden",
|
|
102
|
-
width:
|
|
103
|
-
}),
|
|
102
|
+
width: s
|
|
103
|
+
}), t.appendChild(l);
|
|
104
104
|
const d = [];
|
|
105
|
-
let
|
|
106
|
-
for (;
|
|
107
|
-
let g =
|
|
105
|
+
let c = 0;
|
|
106
|
+
for (; c < r.length; ) {
|
|
107
|
+
let g = c + 1, m = r.length;
|
|
108
108
|
for (; g < m; ) {
|
|
109
109
|
const f = Math.ceil((g + m) / 2);
|
|
110
|
-
|
|
110
|
+
l.textContent = r.slice(c, f).join(" "), l.offsetHeight <= e ? g = f : m = f - 1;
|
|
111
111
|
}
|
|
112
|
-
const
|
|
113
|
-
|
|
112
|
+
const h = document.createElement(i);
|
|
113
|
+
h.setAttribute("style", o), h.textContent = r.slice(c, g).join(" "), d.push(h), c = g;
|
|
114
114
|
}
|
|
115
|
-
|
|
115
|
+
l.remove();
|
|
116
116
|
for (const g of d)
|
|
117
117
|
n.parentNode.insertBefore(g, n);
|
|
118
118
|
n.remove();
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
-
function
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
function U(t, e, a) {
|
|
122
|
+
const n = Array.from(t.rows);
|
|
123
|
+
if (n.length === 0) return !1;
|
|
124
|
+
const i = n[0].querySelector("th") !== null, o = i ? n[0] : null, s = i ? n.slice(1) : n, r = o ? o.offsetHeight : 0;
|
|
125
|
+
if (s.length < 2) return !1;
|
|
126
|
+
const l = a - r - 2;
|
|
127
|
+
if (l <= 0) return !1;
|
|
128
|
+
let d = 0, c = 0;
|
|
129
|
+
for (const h of s) {
|
|
130
|
+
if (c + h.offsetHeight > l) break;
|
|
131
|
+
c += h.offsetHeight, d++;
|
|
132
|
+
}
|
|
133
|
+
if (d === 0 || d === s.length) return !1;
|
|
134
|
+
const g = t.cloneNode(!1);
|
|
135
|
+
o && g.appendChild(o.cloneNode(!0));
|
|
136
|
+
for (let h = 0; h < d; h++)
|
|
137
|
+
g.appendChild(s[h].cloneNode(!0));
|
|
138
|
+
const m = t.cloneNode(!1);
|
|
139
|
+
o && m.appendChild(o.cloneNode(!0));
|
|
140
|
+
for (let h = d; h < s.length; h++)
|
|
141
|
+
m.appendChild(s[h].cloneNode(!0));
|
|
142
|
+
return e.insertBefore(g, t), e.insertBefore(m, t), t.remove(), !0;
|
|
143
|
+
}
|
|
144
|
+
function _(t, e, a) {
|
|
145
|
+
if (t.tagName === "TABLE" || t.tagName === "IMG") return !1;
|
|
146
|
+
const n = (t.textContent || "").split(/\s+/).filter(Boolean);
|
|
147
|
+
if (n.length < 2) return !1;
|
|
148
|
+
const i = t.tagName, o = t.getAttribute("style") || "", s = getComputedStyle(t).width, r = document.createElement(i);
|
|
149
|
+
if (r.setAttribute("style", o), Object.assign(r.style, {
|
|
150
|
+
position: "absolute",
|
|
151
|
+
visibility: "hidden",
|
|
152
|
+
width: s
|
|
153
|
+
}), e.appendChild(r), r.textContent = n[0], r.offsetHeight > a)
|
|
154
|
+
return r.remove(), !1;
|
|
155
|
+
let l = 1, d = n.length;
|
|
156
|
+
for (; l < d; ) {
|
|
157
|
+
const m = Math.ceil((l + d) / 2);
|
|
158
|
+
r.textContent = n.slice(0, m).join(" "), r.offsetHeight <= a ? l = m : d = m - 1;
|
|
159
|
+
}
|
|
160
|
+
if (r.remove(), l >= n.length) return !1;
|
|
161
|
+
const c = document.createElement(i);
|
|
162
|
+
c.setAttribute("style", o), c.textContent = n.slice(0, l).join(" ");
|
|
163
|
+
const g = document.createElement(i);
|
|
164
|
+
return g.setAttribute("style", o), g.textContent = n.slice(l).join(" "), e.insertBefore(c, t), e.insertBefore(g, t), t.remove(), !0;
|
|
165
|
+
}
|
|
166
|
+
function j(t, e) {
|
|
167
|
+
let a = 0;
|
|
168
|
+
for (; a < t.children.length; ) {
|
|
169
|
+
const n = t.children[a], i = n.offsetTop, o = i + n.offsetHeight, s = (Math.floor(i / e) + 1) * e;
|
|
170
|
+
if (o > s) {
|
|
171
|
+
const r = s - i;
|
|
172
|
+
if (n.tagName === "TABLE") {
|
|
173
|
+
if (U(
|
|
174
|
+
n,
|
|
175
|
+
t,
|
|
176
|
+
r
|
|
177
|
+
))
|
|
178
|
+
continue;
|
|
179
|
+
} else if (_(n, t, r))
|
|
180
|
+
continue;
|
|
181
|
+
if (n.offsetHeight <= e) {
|
|
182
|
+
const l = document.createElement("div");
|
|
183
|
+
l.style.height = s - i + 1 + "px", n.parentNode.insertBefore(l, n), a++;
|
|
184
|
+
}
|
|
128
185
|
}
|
|
186
|
+
a++;
|
|
129
187
|
}
|
|
130
188
|
}
|
|
131
|
-
function
|
|
132
|
-
const
|
|
133
|
-
E(
|
|
134
|
-
const
|
|
135
|
-
return
|
|
136
|
-
clone:
|
|
137
|
-
layout:
|
|
138
|
-
options:
|
|
189
|
+
function J(t, e = {}) {
|
|
190
|
+
const a = M(e), n = N(), i = B(t, a.pageWidth);
|
|
191
|
+
E(i);
|
|
192
|
+
const o = x(i, a);
|
|
193
|
+
return T(i, o.pageContentPx), R(i, o.pageContentPx), j(i, o.pageContentPx), {
|
|
194
|
+
clone: i,
|
|
195
|
+
layout: o,
|
|
196
|
+
options: a,
|
|
139
197
|
cleanup: () => {
|
|
140
|
-
|
|
198
|
+
i.remove(), n();
|
|
141
199
|
}
|
|
142
200
|
};
|
|
143
201
|
}
|
|
144
|
-
async function
|
|
145
|
-
const { clone: n, layout:
|
|
202
|
+
async function Y(t, e, a = {}) {
|
|
203
|
+
const { clone: n, layout: i, options: o, cleanup: s } = J(e, a);
|
|
146
204
|
try {
|
|
147
|
-
await new Promise((
|
|
148
|
-
|
|
149
|
-
callback: () =>
|
|
150
|
-
width:
|
|
151
|
-
windowWidth:
|
|
205
|
+
await new Promise((r) => {
|
|
206
|
+
t.html(n, {
|
|
207
|
+
callback: () => r(),
|
|
208
|
+
width: i.contentWidthMm,
|
|
209
|
+
windowWidth: i.renderedWidth,
|
|
152
210
|
margin: [
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
211
|
+
o.margin.top,
|
|
212
|
+
o.margin.right,
|
|
213
|
+
o.margin.bottom,
|
|
214
|
+
o.margin.left
|
|
157
215
|
]
|
|
158
216
|
});
|
|
159
217
|
});
|
|
160
218
|
} finally {
|
|
161
|
-
|
|
219
|
+
s();
|
|
220
|
+
}
|
|
221
|
+
return a.marginContent && await z(t, a.marginContent, a), t;
|
|
222
|
+
}
|
|
223
|
+
function k(t, e) {
|
|
224
|
+
switch (t) {
|
|
225
|
+
case "top":
|
|
226
|
+
return { x: 0, y: 0, width: e.pageWidth, height: e.margin.top };
|
|
227
|
+
case "bottom":
|
|
228
|
+
return {
|
|
229
|
+
x: 0,
|
|
230
|
+
y: e.pageHeight - e.margin.bottom,
|
|
231
|
+
width: e.pageWidth,
|
|
232
|
+
height: e.margin.bottom
|
|
233
|
+
};
|
|
234
|
+
case "left":
|
|
235
|
+
return { x: 0, y: 0, width: e.margin.left, height: e.pageHeight };
|
|
236
|
+
case "right":
|
|
237
|
+
return {
|
|
238
|
+
x: e.pageWidth - e.margin.right,
|
|
239
|
+
y: 0,
|
|
240
|
+
width: e.margin.right,
|
|
241
|
+
height: e.pageHeight
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async function L(t, e, a, n) {
|
|
246
|
+
const i = document.createElement("div");
|
|
247
|
+
Object.assign(i.style, {
|
|
248
|
+
position: "fixed",
|
|
249
|
+
left: "-99999px",
|
|
250
|
+
top: "0",
|
|
251
|
+
width: e + "mm",
|
|
252
|
+
height: a + "mm",
|
|
253
|
+
overflow: "hidden"
|
|
254
|
+
}), i.appendChild(t), document.body.appendChild(i);
|
|
255
|
+
try {
|
|
256
|
+
return await W(i, {
|
|
257
|
+
scale: n,
|
|
258
|
+
backgroundColor: null
|
|
259
|
+
});
|
|
260
|
+
} finally {
|
|
261
|
+
i.remove();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const D = ["top", "right", "bottom", "left"];
|
|
265
|
+
async function F(t, e, a) {
|
|
266
|
+
const n = {};
|
|
267
|
+
for (const i of D) {
|
|
268
|
+
const o = t[i];
|
|
269
|
+
if (o && typeof o != "function") {
|
|
270
|
+
const s = k(i, e);
|
|
271
|
+
n[i] = await L(
|
|
272
|
+
o.cloneNode(!0),
|
|
273
|
+
s.width,
|
|
274
|
+
s.height,
|
|
275
|
+
a
|
|
276
|
+
);
|
|
277
|
+
}
|
|
162
278
|
}
|
|
163
|
-
return
|
|
279
|
+
return n;
|
|
164
280
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
281
|
+
function Q(t, e) {
|
|
282
|
+
return t == null ? e.margin : typeof t == "number" ? { top: t, right: t, bottom: t, left: t } : {
|
|
283
|
+
top: t.top ?? e.margin.top,
|
|
284
|
+
right: t.right ?? e.margin.right,
|
|
285
|
+
bottom: t.bottom ?? e.margin.bottom,
|
|
286
|
+
left: t.left ?? e.margin.left
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function Z(t, e, a, n, i, o, s) {
|
|
290
|
+
const {
|
|
291
|
+
text: r,
|
|
292
|
+
color: l = "#000000",
|
|
293
|
+
fontSize: d = 2.5,
|
|
294
|
+
fontFamily: c = "Arial, sans-serif"
|
|
295
|
+
} = e, g = d * a, m = (e.gap ?? d * 0.5) * a;
|
|
296
|
+
t.save(), t.fillStyle = l, t.font = `${g}px ${c}`, t.textBaseline = "middle";
|
|
297
|
+
const h = t.measureText(r).width + m;
|
|
298
|
+
t.save(), t.beginPath(), t.rect(n, i - g, o, g * 2), t.clip();
|
|
299
|
+
for (let f = n; f < n + o; f += h)
|
|
300
|
+
t.fillText(r, f, i);
|
|
301
|
+
t.restore(), t.save(), t.beginPath(), t.rect(n, i + s - g, o, g * 2), t.clip();
|
|
302
|
+
for (let f = n; f < n + o; f += h)
|
|
303
|
+
t.fillText(r, f, i + s);
|
|
304
|
+
t.restore(), t.save(), t.translate(n, i + s), t.rotate(-Math.PI / 2), t.beginPath(), t.rect(0, -g, s, g * 2), t.clip();
|
|
305
|
+
for (let f = 0; f < s; f += h)
|
|
306
|
+
t.fillText(r, f, 0);
|
|
307
|
+
t.restore(), t.save(), t.translate(n + o, i), t.rotate(Math.PI / 2), t.beginPath(), t.rect(0, -g, s, g * 2), t.clip();
|
|
308
|
+
for (let f = 0; f < s; f += h)
|
|
309
|
+
t.fillText(r, f, 0);
|
|
310
|
+
t.restore(), t.restore();
|
|
311
|
+
}
|
|
312
|
+
function I(t, e) {
|
|
313
|
+
return Q(t.margin, e);
|
|
314
|
+
}
|
|
315
|
+
async function G(t, e, a, n, i, o, s, r) {
|
|
316
|
+
for (const l of D) {
|
|
317
|
+
const d = e[l];
|
|
318
|
+
if (!d) continue;
|
|
319
|
+
const c = k(l, n);
|
|
320
|
+
let g;
|
|
321
|
+
typeof d == "function" ? g = await L(
|
|
322
|
+
d(o, s),
|
|
323
|
+
c.width,
|
|
324
|
+
c.height,
|
|
325
|
+
r
|
|
326
|
+
) : g = a[l], t.drawImage(
|
|
327
|
+
g,
|
|
328
|
+
0,
|
|
329
|
+
0,
|
|
330
|
+
g.width,
|
|
331
|
+
g.height,
|
|
332
|
+
Math.round(c.x * i),
|
|
333
|
+
Math.round(c.y * i),
|
|
334
|
+
Math.round(c.width * i),
|
|
335
|
+
Math.round(c.height * i)
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
if (e.contentBorder) {
|
|
339
|
+
const { color: l = "#000000", width: d = 0.3 } = e.contentBorder, c = I(e.contentBorder, n);
|
|
340
|
+
t.strokeStyle = l, t.lineWidth = d * i, t.strokeRect(
|
|
341
|
+
Math.round(c.left * i),
|
|
342
|
+
Math.round(c.top * i),
|
|
343
|
+
Math.round((n.pageWidth - c.left - c.right) * i),
|
|
344
|
+
Math.round((n.pageHeight - c.top - c.bottom) * i)
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
if (e.textBorder) {
|
|
348
|
+
const l = I(e.textBorder, n);
|
|
349
|
+
Z(
|
|
350
|
+
t,
|
|
351
|
+
e.textBorder,
|
|
352
|
+
i,
|
|
353
|
+
Math.round(l.left * i),
|
|
354
|
+
Math.round(l.top * i),
|
|
355
|
+
Math.round((n.pageWidth - l.left - l.right) * i),
|
|
356
|
+
Math.round((n.pageHeight - l.top - l.bottom) * i)
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
async function X(t, e = {}) {
|
|
361
|
+
const { imageFormat: a = "JPEG", imageQuality: n = 1, scale: i = 2 } = e, o = M(e), s = N(), r = B(t, o.pageWidth);
|
|
362
|
+
r.style.opacity = "1", r.style.left = "-99999px", E(r);
|
|
363
|
+
const l = x(r, o);
|
|
364
|
+
T(r, l.pageContentPx), R(r, l.pageContentPx), j(r, l.pageContentPx);
|
|
170
365
|
try {
|
|
171
|
-
const d = await
|
|
172
|
-
scale:
|
|
366
|
+
const d = await W(r, {
|
|
367
|
+
scale: i,
|
|
173
368
|
backgroundColor: "#ffffff"
|
|
174
|
-
}), { jsPDF:
|
|
175
|
-
orientation:
|
|
369
|
+
}), { jsPDF: c } = await import("jspdf"), g = o.pageWidth - o.margin.left - o.margin.right, m = o.pageHeight - o.margin.top - o.margin.bottom, h = d.width, f = m / g * h, P = Math.ceil(d.height / f), v = o.pageWidth > o.pageHeight ? "l" : "p", C = new c({
|
|
370
|
+
orientation: v,
|
|
176
371
|
unit: "mm",
|
|
177
|
-
format: [
|
|
372
|
+
format: [o.pageWidth, o.pageHeight]
|
|
178
373
|
});
|
|
179
|
-
for (let
|
|
180
|
-
const
|
|
374
|
+
for (let y = 0; y < P; y++) {
|
|
375
|
+
const p = Math.min(
|
|
181
376
|
f,
|
|
182
|
-
d.height -
|
|
183
|
-
),
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
if (!
|
|
187
|
-
|
|
377
|
+
d.height - y * f
|
|
378
|
+
), w = document.createElement("canvas");
|
|
379
|
+
w.width = h, w.height = p;
|
|
380
|
+
const u = w.getContext("2d");
|
|
381
|
+
if (!u) throw new Error("Could not get canvas context");
|
|
382
|
+
u.fillStyle = "#ffffff", u.fillRect(0, 0, h, p), u.drawImage(
|
|
188
383
|
d,
|
|
189
384
|
0,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
385
|
+
y * f,
|
|
386
|
+
h,
|
|
387
|
+
p,
|
|
193
388
|
0,
|
|
194
389
|
0,
|
|
195
|
-
|
|
196
|
-
|
|
390
|
+
h,
|
|
391
|
+
p
|
|
197
392
|
);
|
|
198
|
-
const
|
|
199
|
-
`image/${
|
|
393
|
+
const A = w.toDataURL(
|
|
394
|
+
`image/${a.toLowerCase()}`,
|
|
200
395
|
n
|
|
201
396
|
);
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
397
|
+
y > 0 && C.addPage([o.pageWidth, o.pageHeight], v);
|
|
398
|
+
const b = p / h * g;
|
|
399
|
+
C.addImage(
|
|
400
|
+
A,
|
|
401
|
+
a,
|
|
402
|
+
o.margin.left,
|
|
403
|
+
o.margin.top,
|
|
209
404
|
g,
|
|
210
|
-
|
|
405
|
+
b,
|
|
211
406
|
void 0,
|
|
212
407
|
"FAST"
|
|
213
408
|
);
|
|
214
409
|
}
|
|
215
|
-
return
|
|
410
|
+
return e.marginContent && await z(C, e.marginContent, e), C;
|
|
216
411
|
} finally {
|
|
217
|
-
|
|
412
|
+
r.remove(), s();
|
|
218
413
|
}
|
|
219
414
|
}
|
|
220
|
-
async function
|
|
221
|
-
const { imageFormat:
|
|
222
|
-
|
|
223
|
-
const
|
|
224
|
-
|
|
415
|
+
async function K(t, e = {}) {
|
|
416
|
+
const { imageFormat: a = "PNG", imageQuality: n = 1, scale: i = 2 } = e, o = M(e), s = N(), r = B(t, o.pageWidth);
|
|
417
|
+
r.style.opacity = "1", r.style.left = "-99999px", E(r);
|
|
418
|
+
const l = x(r, o);
|
|
419
|
+
T(r, l.pageContentPx), R(r, l.pageContentPx), j(r, l.pageContentPx);
|
|
225
420
|
try {
|
|
226
|
-
const d = await
|
|
227
|
-
scale:
|
|
421
|
+
const d = await W(r, {
|
|
422
|
+
scale: i,
|
|
228
423
|
backgroundColor: "#ffffff"
|
|
229
|
-
}),
|
|
230
|
-
for (let
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
d.height -
|
|
234
|
-
),
|
|
235
|
-
|
|
236
|
-
const
|
|
237
|
-
if (!
|
|
238
|
-
|
|
424
|
+
}), c = o.pageWidth - o.margin.left - o.margin.right, g = o.pageHeight - o.margin.top - o.margin.bottom, m = d.width, h = g / c * m, f = m / c, P = Math.round(o.pageWidth * f), v = Math.round(o.pageHeight * f), C = Math.round(o.margin.top * f), y = Math.round(o.margin.left * f), p = Math.ceil(d.height / h), w = [], { marginContent: u } = e, A = u ? await F(u, o, i) : {};
|
|
425
|
+
for (let b = 0; b < p; b++) {
|
|
426
|
+
const O = Math.min(
|
|
427
|
+
h,
|
|
428
|
+
d.height - b * h
|
|
429
|
+
), S = document.createElement("canvas");
|
|
430
|
+
S.width = P, S.height = v;
|
|
431
|
+
const H = S.getContext("2d");
|
|
432
|
+
if (!H) throw new Error("Could not get canvas context");
|
|
433
|
+
H.fillStyle = "#ffffff", H.fillRect(0, 0, P, v), H.drawImage(
|
|
239
434
|
d,
|
|
240
435
|
0,
|
|
241
|
-
|
|
436
|
+
b * h,
|
|
242
437
|
m,
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
438
|
+
O,
|
|
439
|
+
y,
|
|
440
|
+
C,
|
|
246
441
|
m,
|
|
247
|
-
|
|
248
|
-
),
|
|
249
|
-
|
|
250
|
-
|
|
442
|
+
O
|
|
443
|
+
), u && await G(
|
|
444
|
+
H,
|
|
445
|
+
u,
|
|
446
|
+
A,
|
|
447
|
+
o,
|
|
448
|
+
f,
|
|
449
|
+
b + 1,
|
|
450
|
+
p,
|
|
451
|
+
i
|
|
452
|
+
), w.push(
|
|
453
|
+
S.toDataURL(
|
|
454
|
+
`image/${a.toLowerCase()}`,
|
|
251
455
|
n
|
|
252
456
|
)
|
|
253
457
|
);
|
|
254
458
|
}
|
|
255
|
-
return
|
|
459
|
+
return w;
|
|
256
460
|
} finally {
|
|
257
|
-
|
|
461
|
+
r.remove(), s();
|
|
258
462
|
}
|
|
259
463
|
}
|
|
260
|
-
async function
|
|
261
|
-
const n =
|
|
464
|
+
async function tt(t, e, a = {}) {
|
|
465
|
+
const n = M(a), i = await K(t, a);
|
|
262
466
|
e.innerHTML = "", Object.assign(e.style, {
|
|
467
|
+
direction: "ltr",
|
|
263
468
|
width: "fit-content",
|
|
264
469
|
height: n.pageHeight + "mm",
|
|
265
470
|
maxHeight: "100vh",
|
|
266
471
|
overflowY: "auto",
|
|
267
472
|
background: "#e0e0e0"
|
|
268
473
|
});
|
|
269
|
-
for (let
|
|
270
|
-
const
|
|
271
|
-
|
|
474
|
+
for (let o = 0; o < i.length; o++) {
|
|
475
|
+
const s = document.createElement("img");
|
|
476
|
+
s.src = i[o], s.alt = `Page ${o + 1}`, Object.assign(s.style, {
|
|
272
477
|
width: n.pageWidth + "mm",
|
|
273
478
|
maxWidth: "100%",
|
|
274
479
|
height: "auto",
|
|
@@ -277,21 +482,49 @@ async function q(i, e, o = {}) {
|
|
|
277
482
|
border: "1px solid #bbb",
|
|
278
483
|
boxShadow: "0 2px 8px rgba(0,0,0,0.2)",
|
|
279
484
|
marginBottom: "16px"
|
|
280
|
-
}), e.appendChild(
|
|
485
|
+
}), e.appendChild(s);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
async function z(t, e, a = {}) {
|
|
489
|
+
const n = M(a), i = t.getNumberOfPages(), o = 2, s = o * (96 / 25.4), r = Math.round(n.pageWidth * s), l = Math.round(n.pageHeight * s), d = await F(e, n, o);
|
|
490
|
+
for (let c = 1; c <= i; c++) {
|
|
491
|
+
t.setPage(c);
|
|
492
|
+
const g = document.createElement("canvas");
|
|
493
|
+
g.width = r, g.height = l;
|
|
494
|
+
const m = g.getContext("2d");
|
|
495
|
+
m && (await G(
|
|
496
|
+
m,
|
|
497
|
+
e,
|
|
498
|
+
d,
|
|
499
|
+
n,
|
|
500
|
+
s,
|
|
501
|
+
c,
|
|
502
|
+
i,
|
|
503
|
+
o
|
|
504
|
+
), t.addImage(
|
|
505
|
+
g.toDataURL("image/png"),
|
|
506
|
+
"PNG",
|
|
507
|
+
0,
|
|
508
|
+
0,
|
|
509
|
+
n.pageWidth,
|
|
510
|
+
n.pageHeight
|
|
511
|
+
));
|
|
281
512
|
}
|
|
513
|
+
return t;
|
|
282
514
|
}
|
|
283
515
|
export {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
516
|
+
$ as PAGE_MARGINS,
|
|
517
|
+
q as PAGE_SIZES,
|
|
518
|
+
z as addMarginContent,
|
|
519
|
+
x as computeLayout,
|
|
520
|
+
B as createPrintClone,
|
|
288
521
|
j as insertPageBreakSpacers,
|
|
289
522
|
E as normalizeTableAttributes,
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
523
|
+
J as prepare,
|
|
524
|
+
tt as previewPageImages,
|
|
525
|
+
Y as renderHTML,
|
|
526
|
+
X as renderImagePDF,
|
|
527
|
+
K as renderPageImages,
|
|
528
|
+
T as splitOversizedTables,
|
|
529
|
+
R as splitOversizedText
|
|
297
530
|
};
|
package/package.json
CHANGED