反应:使用jspdf和html2canvas将HTML元素传输到网络工作者以生成Pdf

时间:2019-02-22 20:05:23

标签: reactjs web-worker jspdf html2canvas

我目前正在使用jspdf和html2canvas从react组件内的html创建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");
    });
};

这已修改为使用网络工作者:

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.

这是我工作人员中的代码:

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)。

1 个答案:

答案 0 :(得分:0)

事实证明DOM元素不适用于the structured clone algorithm。但是,确实有图像,所以我可以简单地传输画布图像而不是canvas元素。相反,我决定解析DOM元素以提取所需的数据,并使用pdfMake创建pdf文件(由于使用html2canvas / jsPDF造成的模糊性)。