jspdf-utils 0.1.3 → 0.1.4
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 +6 -11
- package/dist/html-to-pdf.js +160 -183
- package/package.json +1 -1
package/dist/html-to-pdf.d.ts
CHANGED
|
@@ -38,18 +38,13 @@ export interface PrepareResult {
|
|
|
38
38
|
/** Compute derived layout values from options. */
|
|
39
39
|
declare function computeLayout(container: HTMLElement, opts: PageOptions): Layout;
|
|
40
40
|
/**
|
|
41
|
-
* Clone an element
|
|
42
|
-
|
|
43
|
-
declare function createPrintClone(source: HTMLElement, pageWidth?: number): HTMLElement;
|
|
44
|
-
/**
|
|
45
|
-
* Inline computed styles from `source` onto the matching elements in `clone`.
|
|
41
|
+
* Clone an element into a hidden iframe so that the page's CSS frameworks
|
|
42
|
+
* (Tailwind, Bootstrap, etc.) cannot interfere with PDF rendering.
|
|
46
43
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* values as inline styles on the clone, we bypass jsPDF's CSS processing
|
|
50
|
-
* entirely and get consistent output across all environments.
|
|
44
|
+
* Only @font-face rules are copied into the iframe so custom fonts still work.
|
|
45
|
+
* The returned element's `.remove()` method cleans up the iframe automatically.
|
|
51
46
|
*/
|
|
52
|
-
declare function
|
|
47
|
+
declare function createPrintClone(source: HTMLElement, pageWidth?: number): HTMLElement;
|
|
53
48
|
/**
|
|
54
49
|
* Convert HTML table attributes (cellpadding, cellspacing, border) to
|
|
55
50
|
* inline CSS so doc.html()'s renderer picks them up.
|
|
@@ -90,4 +85,4 @@ export interface ImagePDFOptions {
|
|
|
90
85
|
* screenshot — no selectable or extractable text in the output.
|
|
91
86
|
*/
|
|
92
87
|
declare function renderImagePDF(source: HTMLElement, opts?: Partial<PageOptions> & ImagePDFOptions): Promise<jsPDF>;
|
|
93
|
-
export { PAGE_SIZES, PAGE_MARGINS, computeLayout, createPrintClone,
|
|
88
|
+
export { PAGE_SIZES, PAGE_MARGINS, computeLayout, createPrintClone, normalizeTableAttributes, splitOversizedTables, splitOversizedText, insertPageBreakSpacers, prepare, renderHTML, renderImagePDF, };
|
package/dist/html-to-pdf.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
const
|
|
1
|
+
import D from "html2canvas";
|
|
2
|
+
const N = {
|
|
3
3
|
a0: [841, 1189],
|
|
4
4
|
a1: [594, 841],
|
|
5
5
|
a2: [420, 594],
|
|
@@ -10,7 +10,7 @@ const T = {
|
|
|
10
10
|
letter: [215.9, 279.4],
|
|
11
11
|
legal: [215.9, 355.6],
|
|
12
12
|
tabloid: [279.4, 431.8]
|
|
13
|
-
},
|
|
13
|
+
}, R = {
|
|
14
14
|
a0: 40,
|
|
15
15
|
a1: 35,
|
|
16
16
|
a2: 30,
|
|
@@ -22,251 +22,228 @@ const T = {
|
|
|
22
22
|
legal: 25.4,
|
|
23
23
|
tabloid: 25
|
|
24
24
|
};
|
|
25
|
-
function
|
|
26
|
-
const
|
|
25
|
+
function x(r = {}) {
|
|
26
|
+
const n = r.format ?? "a4", [i, e] = N[n], o = r.pageWidth ?? i, t = r.pageHeight ?? e, a = R[n], c = {
|
|
27
27
|
top: a,
|
|
28
28
|
right: a,
|
|
29
29
|
bottom: a,
|
|
30
30
|
left: a
|
|
31
31
|
};
|
|
32
32
|
return {
|
|
33
|
-
unit:
|
|
34
|
-
format:
|
|
35
|
-
pageWidth:
|
|
36
|
-
pageHeight:
|
|
37
|
-
margin: { ...
|
|
33
|
+
unit: r.unit ?? "mm",
|
|
34
|
+
format: n,
|
|
35
|
+
pageWidth: o,
|
|
36
|
+
pageHeight: t,
|
|
37
|
+
margin: { ...c, ...r.margin }
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
function
|
|
41
|
-
const
|
|
42
|
-
return { renderedWidth:
|
|
40
|
+
function C(r, n) {
|
|
41
|
+
const i = r.offsetWidth, e = n.pageWidth - n.margin.left - n.margin.right, o = e / i, a = (n.pageHeight - n.margin.top - n.margin.bottom) / o;
|
|
42
|
+
return { renderedWidth: i, scale: o, contentWidthMm: e, pageContentPx: a };
|
|
43
43
|
}
|
|
44
|
-
function
|
|
45
|
-
const
|
|
46
|
-
|
|
44
|
+
function v(r, n = 210) {
|
|
45
|
+
const i = document.createElement("iframe");
|
|
46
|
+
Object.assign(i.style, {
|
|
47
47
|
position: "fixed",
|
|
48
48
|
top: "0",
|
|
49
|
-
left: "
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
left: "-99999px",
|
|
50
|
+
width: n + "mm",
|
|
51
|
+
height: "99999px",
|
|
52
|
+
border: "none",
|
|
52
53
|
opacity: "0.000001",
|
|
53
54
|
pointerEvents: "none"
|
|
54
|
-
}), document.body.appendChild(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"border-
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
"border-right-color",
|
|
77
|
-
"border-bottom-color",
|
|
78
|
-
"border-left-color",
|
|
79
|
-
"border-collapse",
|
|
80
|
-
"border-spacing",
|
|
81
|
-
"font-family",
|
|
82
|
-
"font-size",
|
|
83
|
-
"font-weight",
|
|
84
|
-
"font-style",
|
|
85
|
-
"color",
|
|
86
|
-
"background-color",
|
|
87
|
-
"direction",
|
|
88
|
-
"unicode-bidi",
|
|
89
|
-
"table-layout",
|
|
90
|
-
"white-space"
|
|
91
|
-
], t = (l, s) => {
|
|
92
|
-
const h = getComputedStyle(l);
|
|
93
|
-
for (const c of n)
|
|
94
|
-
s.style.setProperty(c, h.getPropertyValue(c));
|
|
95
|
-
};
|
|
96
|
-
t(i, o);
|
|
97
|
-
const r = i.querySelectorAll("*"), e = o.querySelectorAll("*"), a = Math.min(r.length, e.length);
|
|
98
|
-
for (let l = 0; l < a; l++)
|
|
99
|
-
t(r[l], e[l]);
|
|
55
|
+
}), document.body.appendChild(i);
|
|
56
|
+
const e = i.contentDocument;
|
|
57
|
+
if (!e) throw new Error("Could not access iframe document");
|
|
58
|
+
const o = e.createElement("base");
|
|
59
|
+
o.href = document.baseURI, e.head.appendChild(o);
|
|
60
|
+
const t = [];
|
|
61
|
+
for (const c of document.styleSheets)
|
|
62
|
+
try {
|
|
63
|
+
for (const l of c.cssRules)
|
|
64
|
+
l instanceof CSSFontFaceRule && t.push(l.cssText);
|
|
65
|
+
} catch {
|
|
66
|
+
}
|
|
67
|
+
if (t.length > 0) {
|
|
68
|
+
const c = e.createElement("style");
|
|
69
|
+
c.textContent = t.join(`
|
|
70
|
+
`), e.head.appendChild(c);
|
|
71
|
+
}
|
|
72
|
+
const a = r.cloneNode(!0);
|
|
73
|
+
return Object.assign(a.style, {
|
|
74
|
+
boxSizing: "border-box",
|
|
75
|
+
width: n + "mm"
|
|
76
|
+
}), e.body.style.margin = "0", e.body.appendChild(a), a.remove = () => i.remove(), a;
|
|
100
77
|
}
|
|
101
|
-
function
|
|
102
|
-
for (const
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
105
|
-
for (const
|
|
106
|
-
|
|
107
|
-
|
|
78
|
+
function A(r) {
|
|
79
|
+
for (const n of r.querySelectorAll("table")) {
|
|
80
|
+
const i = n.getAttribute("cellpadding");
|
|
81
|
+
if (i) {
|
|
82
|
+
for (const e of n.querySelectorAll("th, td"))
|
|
83
|
+
e.style.padding || (e.style.padding = i + "px");
|
|
84
|
+
n.removeAttribute("cellpadding");
|
|
108
85
|
}
|
|
109
86
|
}
|
|
110
87
|
}
|
|
111
|
-
function
|
|
112
|
-
for (const
|
|
113
|
-
|
|
88
|
+
function E(r, n) {
|
|
89
|
+
for (const i of Array.from(
|
|
90
|
+
r.querySelectorAll(":scope > table")
|
|
114
91
|
)) {
|
|
115
|
-
if (
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
118
|
-
const
|
|
119
|
-
let
|
|
120
|
-
for (const
|
|
121
|
-
const g =
|
|
122
|
-
|
|
92
|
+
if (i.offsetHeight <= n) continue;
|
|
93
|
+
const e = Array.from(i.rows);
|
|
94
|
+
if (e.length === 0) continue;
|
|
95
|
+
const o = e[0].querySelector("th") !== null, t = o ? e[0] : null, a = o ? e.slice(1) : e, c = t ? t.offsetHeight : 0, l = n - c - 2, d = [];
|
|
96
|
+
let f = [], h = 0;
|
|
97
|
+
for (const s of a) {
|
|
98
|
+
const g = s.offsetHeight;
|
|
99
|
+
h + g > l && f.length > 0 && (d.push(f), f = [], h = 0), f.push(s), h += g;
|
|
123
100
|
}
|
|
124
|
-
|
|
125
|
-
for (const
|
|
126
|
-
const g =
|
|
127
|
-
|
|
128
|
-
for (const m of
|
|
129
|
-
|
|
101
|
+
f.length > 0 && d.push(f);
|
|
102
|
+
for (const s of d) {
|
|
103
|
+
const g = i.cloneNode(!1);
|
|
104
|
+
t && g.appendChild(t.cloneNode(!0));
|
|
105
|
+
for (const m of s) g.appendChild(m.cloneNode(!0));
|
|
106
|
+
i.parentNode.insertBefore(g, i);
|
|
130
107
|
}
|
|
131
|
-
|
|
108
|
+
i.remove();
|
|
132
109
|
}
|
|
133
110
|
}
|
|
134
|
-
function
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
111
|
+
function P(r, n) {
|
|
112
|
+
const i = r.ownerDocument;
|
|
113
|
+
for (const e of Array.from(r.querySelectorAll(":scope > *"))) {
|
|
114
|
+
const o = e;
|
|
115
|
+
if (o.offsetHeight <= n || o.tagName === "TABLE")
|
|
138
116
|
continue;
|
|
139
|
-
const
|
|
140
|
-
|
|
117
|
+
const t = o.tagName, a = o.getAttribute("style") || "", c = i.defaultView.getComputedStyle(o).width, l = (o.textContent || "").split(/\s+/).filter(Boolean), d = i.createElement(t);
|
|
118
|
+
d.setAttribute("style", a), Object.assign(d.style, {
|
|
141
119
|
position: "absolute",
|
|
142
120
|
visibility: "hidden",
|
|
143
|
-
width:
|
|
144
|
-
}),
|
|
145
|
-
const
|
|
146
|
-
let
|
|
147
|
-
for (;
|
|
148
|
-
let
|
|
149
|
-
for (;
|
|
150
|
-
const
|
|
151
|
-
|
|
121
|
+
width: c
|
|
122
|
+
}), r.appendChild(d);
|
|
123
|
+
const f = [];
|
|
124
|
+
let h = 0;
|
|
125
|
+
for (; h < l.length; ) {
|
|
126
|
+
let s = h + 1, g = l.length;
|
|
127
|
+
for (; s < g; ) {
|
|
128
|
+
const u = Math.ceil((s + g) / 2);
|
|
129
|
+
d.textContent = l.slice(h, u).join(" "), d.offsetHeight <= n ? s = u : g = u - 1;
|
|
152
130
|
}
|
|
153
|
-
const
|
|
154
|
-
|
|
131
|
+
const m = i.createElement(t);
|
|
132
|
+
m.setAttribute("style", a), m.textContent = l.slice(h, s).join(" "), f.push(m), h = s;
|
|
155
133
|
}
|
|
156
|
-
|
|
157
|
-
for (const
|
|
158
|
-
|
|
159
|
-
|
|
134
|
+
d.remove();
|
|
135
|
+
for (const s of f)
|
|
136
|
+
o.parentNode.insertBefore(s, o);
|
|
137
|
+
o.remove();
|
|
160
138
|
}
|
|
161
139
|
}
|
|
162
|
-
function W(
|
|
163
|
-
const
|
|
164
|
-
for (const
|
|
165
|
-
const
|
|
166
|
-
if (
|
|
167
|
-
const l =
|
|
168
|
-
l.style.height =
|
|
140
|
+
function W(r, n) {
|
|
141
|
+
const i = r.ownerDocument, e = Array.from(r.children);
|
|
142
|
+
for (const o of e) {
|
|
143
|
+
const t = o.offsetTop, a = t + o.offsetHeight, c = (Math.floor(t / n) + 1) * n;
|
|
144
|
+
if (a > c && o.offsetHeight <= n) {
|
|
145
|
+
const l = i.createElement("div");
|
|
146
|
+
l.style.height = c - t + 1 + "px", o.parentNode.insertBefore(l, o);
|
|
169
147
|
}
|
|
170
148
|
}
|
|
171
149
|
}
|
|
172
|
-
function
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
return
|
|
177
|
-
clone:
|
|
178
|
-
layout:
|
|
179
|
-
options:
|
|
180
|
-
cleanup: () =>
|
|
150
|
+
function T(r, n = {}) {
|
|
151
|
+
const i = x(n), e = v(r, i.pageWidth);
|
|
152
|
+
A(e);
|
|
153
|
+
const o = C(e, i);
|
|
154
|
+
return E(e, o.pageContentPx), P(e, o.pageContentPx), W(e, o.pageContentPx), {
|
|
155
|
+
clone: e,
|
|
156
|
+
layout: o,
|
|
157
|
+
options: i,
|
|
158
|
+
cleanup: () => e.remove()
|
|
181
159
|
};
|
|
182
160
|
}
|
|
183
|
-
async function
|
|
184
|
-
const { clone:
|
|
161
|
+
async function F(r, n, i = {}) {
|
|
162
|
+
const { clone: e, layout: o, options: t, cleanup: a } = T(n, i);
|
|
185
163
|
try {
|
|
186
|
-
await new Promise((
|
|
187
|
-
|
|
188
|
-
callback: () =>
|
|
189
|
-
width:
|
|
190
|
-
windowWidth:
|
|
164
|
+
await new Promise((c) => {
|
|
165
|
+
r.html(e, {
|
|
166
|
+
callback: () => c(),
|
|
167
|
+
width: o.contentWidthMm,
|
|
168
|
+
windowWidth: o.renderedWidth,
|
|
191
169
|
margin: [
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
170
|
+
t.margin.top,
|
|
171
|
+
t.margin.right,
|
|
172
|
+
t.margin.bottom,
|
|
173
|
+
t.margin.left
|
|
196
174
|
]
|
|
197
175
|
});
|
|
198
176
|
});
|
|
199
177
|
} finally {
|
|
200
178
|
a();
|
|
201
179
|
}
|
|
202
|
-
return
|
|
180
|
+
return r;
|
|
203
181
|
}
|
|
204
|
-
async function
|
|
205
|
-
const { imageFormat:
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
182
|
+
async function B(r, n = {}) {
|
|
183
|
+
const { imageFormat: i = "JPEG", imageQuality: e = 1, scale: o = 2 } = n, t = x(n), a = v(r, t.pageWidth);
|
|
184
|
+
A(a);
|
|
185
|
+
const c = C(a, t);
|
|
186
|
+
E(a, c.pageContentPx), P(a, c.pageContentPx), W(a, c.pageContentPx);
|
|
209
187
|
try {
|
|
210
|
-
const
|
|
211
|
-
scale:
|
|
188
|
+
const l = await D(a, {
|
|
189
|
+
scale: o,
|
|
212
190
|
backgroundColor: "#ffffff"
|
|
213
|
-
}), { jsPDF:
|
|
214
|
-
orientation:
|
|
191
|
+
}), { jsPDF: d } = await import("jspdf"), f = t.pageWidth - t.margin.left - t.margin.right, h = t.pageHeight - t.margin.top - t.margin.bottom, s = l.width, g = h / f * s, m = Math.ceil(l.height / g), u = t.pageWidth > t.pageHeight ? "l" : "p", H = new d({
|
|
192
|
+
orientation: u,
|
|
215
193
|
unit: "mm",
|
|
216
|
-
format: [
|
|
194
|
+
format: [t.pageWidth, t.pageHeight]
|
|
217
195
|
});
|
|
218
196
|
for (let p = 0; p < m; p++) {
|
|
219
|
-
const
|
|
197
|
+
const y = Math.min(
|
|
220
198
|
g,
|
|
221
|
-
|
|
199
|
+
l.height - p * g
|
|
222
200
|
), b = document.createElement("canvas");
|
|
223
|
-
b.width =
|
|
224
|
-
const
|
|
225
|
-
if (!
|
|
226
|
-
|
|
227
|
-
|
|
201
|
+
b.width = s, b.height = y;
|
|
202
|
+
const w = b.getContext("2d");
|
|
203
|
+
if (!w) throw new Error("Could not get canvas context");
|
|
204
|
+
w.fillStyle = "#ffffff", w.fillRect(0, 0, s, y), w.drawImage(
|
|
205
|
+
l,
|
|
228
206
|
0,
|
|
229
207
|
p * g,
|
|
230
|
-
|
|
231
|
-
|
|
208
|
+
s,
|
|
209
|
+
y,
|
|
232
210
|
0,
|
|
233
211
|
0,
|
|
234
|
-
|
|
235
|
-
|
|
212
|
+
s,
|
|
213
|
+
y
|
|
236
214
|
);
|
|
237
|
-
const
|
|
238
|
-
`image/${
|
|
239
|
-
|
|
215
|
+
const S = b.toDataURL(
|
|
216
|
+
`image/${i.toLowerCase()}`,
|
|
217
|
+
e
|
|
240
218
|
);
|
|
241
|
-
p > 0 &&
|
|
242
|
-
const
|
|
243
|
-
|
|
219
|
+
p > 0 && H.addPage([t.pageWidth, t.pageHeight], u);
|
|
220
|
+
const M = y / s * f;
|
|
221
|
+
H.addImage(
|
|
222
|
+
S,
|
|
223
|
+
i,
|
|
224
|
+
t.margin.left,
|
|
225
|
+
t.margin.top,
|
|
226
|
+
f,
|
|
244
227
|
M,
|
|
245
|
-
n,
|
|
246
|
-
e.margin.left,
|
|
247
|
-
e.margin.top,
|
|
248
|
-
c,
|
|
249
|
-
E,
|
|
250
228
|
void 0,
|
|
251
229
|
"FAST"
|
|
252
230
|
);
|
|
253
231
|
}
|
|
254
|
-
return
|
|
232
|
+
return H;
|
|
255
233
|
} finally {
|
|
256
234
|
a.remove();
|
|
257
235
|
}
|
|
258
236
|
}
|
|
259
237
|
export {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
q as inlineComputedStyles,
|
|
238
|
+
R as PAGE_MARGINS,
|
|
239
|
+
N as PAGE_SIZES,
|
|
240
|
+
C as computeLayout,
|
|
241
|
+
v as createPrintClone,
|
|
265
242
|
W as insertPageBreakSpacers,
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
243
|
+
A as normalizeTableAttributes,
|
|
244
|
+
T as prepare,
|
|
245
|
+
F as renderHTML,
|
|
246
|
+
B as renderImagePDF,
|
|
247
|
+
E as splitOversizedTables,
|
|
248
|
+
P as splitOversizedText
|
|
272
249
|
};
|
package/package.json
CHANGED