React:使用 jspdf 和 html2canvas 将 HTML 元素传输到 web worker 以生成 Pdf
React: transferring HTML elements to web worker to generate Pdf using jspdf and html2canvas
我目前正在使用 jspdf 和 html2canvas 从 html 在 React 组件中创建一个 pdf 文件。它可以工作,但是当有大量数据时它可以锁定浏览器。所以,我想把这个任务委托给网络工作者在后台完成,而不是阻止浏览器。
我就是这样做的没有工人:
handleExportToPdf = () => {
const pages = Array.from(document.getElementsByClassName("client-report__container"));
Promise.all(pages.map(p => html2canvas(p, { logging: false }))).then(canvases => {
const pdf = new JsPDF({
orientation: "l",
unit: "in",
});
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < canvases.length; i++) {
if (i > 0) pdf.addPage();
pdf.addImage(canvases[i].toDataURL("image/png"), "PNG", 0.25, 0, 11, 8);
}
pdf.save("report.pdf");
});
};
这里修改为使用 web worker:
handleExportToPdf = () => {
const pages = Array.from(document.getElementsByClassName("client-report__container"));
this.reportWorker.postMessage(pages);
};
但是,当我尝试 运行 时出现此错误:
Uncaught DOMException: Failed to execute 'postMessage' on 'Worker': HTMLDivElement object could not be cloned.
这是我的 worker 中的代码:
export default () => {
self.addEventListener("message", event => {
console.log("in worker");
const canvases = event.data;
const pdf = new JsPDF({
orientation: "l",
unit: "in",
});
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < canvases.length; i++) {
if (i > 0) pdf.addPage();
pdf.addImage(canvases[i].toDataURL("image/png"), "PNG", 0.25, 0, 11, 8);
}
pdf.save("report.pdf");
});
};
有没有办法将 Html 元素传输给 web worker?或者,更好的方法来做到这一点?
我试着只转移画布,但这也没有用。遇到同样的错误 (HtmlCanvasElement)。
事实证明 DOM 元素不适用于 the structured clone algorithm。但是,图像可以,所以我可以简单地传输 canvas 图像而不是 canvas 元素。相反,我决定解析 DOM 元素以提取我需要的数据并使用 pdfMake 创建 pdf 文件(由于使用 html2canvas/jsPDF 造成的模糊)。
我目前正在使用 jspdf 和 html2canvas 从 html 在 React 组件中创建一个 pdf 文件。它可以工作,但是当有大量数据时它可以锁定浏览器。所以,我想把这个任务委托给网络工作者在后台完成,而不是阻止浏览器。
我就是这样做的没有工人:
handleExportToPdf = () => {
const pages = Array.from(document.getElementsByClassName("client-report__container"));
Promise.all(pages.map(p => html2canvas(p, { logging: false }))).then(canvases => {
const pdf = new JsPDF({
orientation: "l",
unit: "in",
});
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < canvases.length; i++) {
if (i > 0) pdf.addPage();
pdf.addImage(canvases[i].toDataURL("image/png"), "PNG", 0.25, 0, 11, 8);
}
pdf.save("report.pdf");
});
};
这里修改为使用 web worker:
handleExportToPdf = () => {
const pages = Array.from(document.getElementsByClassName("client-report__container"));
this.reportWorker.postMessage(pages);
};
但是,当我尝试 运行 时出现此错误:
Uncaught DOMException: Failed to execute 'postMessage' on 'Worker': HTMLDivElement object could not be cloned.
这是我的 worker 中的代码:
export default () => {
self.addEventListener("message", event => {
console.log("in worker");
const canvases = event.data;
const pdf = new JsPDF({
orientation: "l",
unit: "in",
});
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < canvases.length; i++) {
if (i > 0) pdf.addPage();
pdf.addImage(canvases[i].toDataURL("image/png"), "PNG", 0.25, 0, 11, 8);
}
pdf.save("report.pdf");
});
};
有没有办法将 Html 元素传输给 web worker?或者,更好的方法来做到这一点? 我试着只转移画布,但这也没有用。遇到同样的错误 (HtmlCanvasElement)。
事实证明 DOM 元素不适用于 the structured clone algorithm。但是,图像可以,所以我可以简单地传输 canvas 图像而不是 canvas 元素。相反,我决定解析 DOM 元素以提取我需要的数据并使用 pdfMake 创建 pdf 文件(由于使用 html2canvas/jsPDF 造成的模糊)。