jspdf - 在 React 中使用 OffScreenCanvas 将 HTML 转换为 PDF
问题描述
好的,所以这个问题是不言自明的。
目前,我正在执行以下操作
- 使用 html2canvas npm 包将我的 html 转换为画布。
- 将画布转换为图像
canvas.toDataURL("image/png");
- 经过一些操作后,使用 jsPDF 使用此图像创建 pdf。
所以基本上所有这些过程都是 CPU 密集型的,并导致页面无响应。
我正在尝试将进程卸载到网络工作者,但我无法将 HTML 节点或画布元素 postMessage 到我的工作者线程。
因此,尝试使用 OffScreenCanvas 但我对如何继续这样做感到困惑。
解决方案
第一步不能在 Web-Worker 中完成。您需要访问 DOM 才能绘制它,而 Workers 无权访问 DOM。
第二步可以在OffscreenCanvas上完成,html2canvas确实接受一个{ canvas }
您也可以设置为OffscreenCanvas的参数。但是,一旦您从OffscreenCanvas
获得上下文,您就无法再传输它,因此您将无法将该OffscreenCanvas传递给 Worker,并且您不会从中获得任何收益,因为一切仍将在 UI 线程上完成.
所以我们能做的最好的就是让html2canvas初始化一个HTMLCanvasElement,在它上面绘图,然后将它转换成一个 Blob 中的图像。Blob 可以在没有任何复制成本的情况下穿越领域,并且toBlob()
方法可以使其压缩部分异步完成。
第三步可以在 Worker 中完成,因为这个 PR。
我不知道反应所以你将不得不重写它,但这里是一个裸 JS 实现:
脚本.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,因此这里有一个外包的实时示例。
推荐阅读
- r - 具有 NA 值的热图
- c# - SmtpClient Send(Mail) 函数超时错误
- python-3.x - 如何将我从列表中抓取的数据导出到我的 csv 文件?
- apache-spark - 带有 Hive 的 pyspark,追加将添加到现有分区并重复数据
- java - 使用 Eclipse Debugger 调试 Eclipse CDT 时出现奇怪的行为
- python - 我应该怎么做才能读取 dbf 文件并将数据插入 Oracle db?
- apache-kafka - 创建和使用自定义 kafka 连接配置提供程序
- java-8 - 使用 OAuth 2.0 URL 生成令牌时,如何配置 SwaggerUI 以正确设置标头上的承载令牌?
- java - 在 Spring Boot 中从 id 令牌获取主题
- android - 如何根据设置的主题更改颤动中的状态栏图标和文本颜色?