【问题标题】:Convert HTML to PDF Using OffScreenCanvas in React在 React 中使用 OffScreenCanvas 将 HTML 转换为 PDF
【发布时间】:2021-06-25 12:48:56
【问题描述】:

好的,所以问题是不言自明的。

目前,我正在做以下事情

  1. 使用 html2canvas npm 包将我的 html 转换为画布。
  2. 将画布转换为图像
         canvas.toDataURL("image/png");
  1. 经过一些操作后,使用 jsPDF 创建使用此图像的 pdf。

所以基本上所有这些过程都是 CPU 密集型的,并导致页面无响应。

我正在尝试将进程卸载到网络工作者,但我无法将 HTML 节点或 Canvas 元素发布到我的工作者线程。

因此,尝试使用 OffScreenCanvas,但我不知道如何继续。

【问题讨论】:

    标签: jspdf web-worker html2canvas offscreen-canvas


    【解决方案1】:

    第一步不能在 Web-Worker 中完成。您需要访问 DOM 才能绘制它,而 Workers 无权访问 DOM。

    第二步可以在OffscreenCanvas上完成,html2canvas确实接受{ canvas }参数,您也可以将其设置为OffscreenCanvas。
    但是,一旦您从 OffscreenCanvas 获得上下文,您就无法再将其传输,因此您将无法将该 OffscreenCanvas 传递给 Worker,并且您不会从中获利,因为一切仍将在 UI 线程上完成。
    所以我们能做的最好的就是让html2canvas 初始化一个HTMLCanvasElement,在它上面绘图,然后将它转换成一个Blob 中的图像。 Blob 可以在没有任何复制成本的情况下遍历领域,并且 toBlob() 方法可以使其压缩部分异步完成。

    第三步可以在一个Worker中完成,因为this PR

    我不知道 react 所以你必须重写它,但这里是一个裸 JS 实现:

    script.js

    const dpr = window.devicePixelRatio;
    const worker = new Worker( "worker.js" );
    worker.onmessage = makeDownloadLink;
    worker.onerror = console.error;
    
    html2canvas( target ).then( canvas => {
      canvas.toBlob( (blob) => worker.postMessage( {
        source: blob,
        width: canvas.width / dpr, // retina?
        height: canvas.height / dpr // retina?
      } ) );
    } );
    

    worker.js

    importScripts( "https://unpkg.com/jspdf@latest/dist/jspdf.umd.min.js" );
    onmessage = ({ data }) => {
      const { source, width, height } = data;
      const reader = new FileReaderSync();
      const data_url = reader.readAsDataURL( source );
      const doc = new jspdf.jsPDF( { unit: "px", format: [ width, height ], orientation: width > height ? "l" : "p" });
      doc.addImage( data_url, "PNG", 0, 0, width, height, { compression: "NONE" } );
      postMessage( doc.output( "blob" ) );
    };
    

    而且由于 StackSnippet 的过度保护 iframe 确实会破坏 html2canvas,因此这里是 outsourced live example

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-19
      • 2014-03-23
      • 2016-01-09
      • 2013-10-30
      • 1970-01-01
      • 1970-01-01
      • 2020-09-04
      • 2017-12-19
      相关资源
      最近更新 更多