下面是一个div块: "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240923/e48097d7b655f763eb3f5d9320085223.png) 我用html2canvas把这个div生成了图片,然后用jspdf把图片保存成pdf格式。 "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240923/21de63149e634516dbd5677005ab5f4c.png) 现在的问题是html2canvas把div生成图片时DIV里面的图片没有显示 ,这图片是需要单独处理吗?有遇到过这问题的没? 下面是代码: const printHandle = async () => { console.log('打印') console.log('生成pdf') isPrint.value = true setTimeout(async () => { const content = document.getElementById('printContent') if (content) { const canvas = await html2canvas(content, { scale: 2 }) const imgData = canvas.toDataURL('image/png') const pdf = new jsPDF('p', 'mm', 'a4') const imgProps = pdf.getImageProperties(imgData) const pdfWidth = pdf.internal.pageSize.getWidth() const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight) // 将PDF输出为Blob对象 const pdfBlob = pdf.output('blob') // 创建一个链接元素并设置其属性 const downloadLink = document.createElement('a') downloadLink.href = URL.createObjectURL(pdfBlob) downloadLink.download = 'document.pdf' // 设置下载的文件名 // 触发点击事件以开始下载 document.body.appendChild(downloadLink) downloadLink.click() document.body.removeChild(downloadLink) // 之后可以移除链接元素 isPrint.value = false } }, 500) }
项目中多处使用到 PDF 打印功能,我之前采用的实现方案是: 1 先在 html 上渲染出来 2 通过 html2canvas 转换为 canvas 3 通过 canvas.toDataURL 转换为 jpeg 图片 URL 4 通过 jspdf 创建 PDF 并添加转换来的 jpeg PDF 模板中各元素尺寸是根据数据灵活变换的,考虑到纸张大小,换页,布局等问题,通过 html2canvas 将页面元素转换为 canvas 的时要根据实际情况进行多次转换生成包一个含多张图片的列表。jspdf 再根据图片列表逐一添加。 现在问题就来了,虽然功能已经实现,但 html2canvas 是异步操作,而且非常耗时,当页面只需要转换一两张图片的时候勉强还可以接受,但是当图片的数量越来越多,十张左右的时候就要二十多秒了。 为了优化这个问题,我查找并尝试了几种方法均已失败告终,方法和失败原因如下: 1 html2canvas 官网提供的 ignoreElements 根据介绍,ignoreElements 可以用来排除掉不需要被截图(转换为canvas)的 html 子元素,以便减少 html2canvas 遍历 HTML 元素的时间。但在我的项目中,因为前面提到的考虑换页等问题,已经对 html2canvas 转换的元素粒度降到最细了。没有可排除打印的子元素。 2 Promise.all 多个异步并行, 不知道是因为浏览器限制还是因为线程的资源上限,虽然在代码逻辑上多个 html2canvas 已经是并行处理了,但实际使用时间并没有减少,而且从F12的性能上看,多个 html2canvas 最终还是逐一执行的 3 web worker 后台线程处理 既然在同一个线程里没办法做到真正的并行处理,第一时间想到的就是 web worker 甚至可以使用多个 web worker 启用后台线程并行处理,但是 html2Canvas 是根据 DOM 元素进行操作处理,而 web worker 是没法访问 Dom 的,所以 html2Canvas 好像又不能放到后台线程中处理。 进行到这里就没了头绪,接下来该怎么做希望有遇到过这个问题的前辈给个方向,不胜感激。
背景: 项目中有需要将html下载成pdf的需求,我看项目中的实现思路是 1. 利用html2Canvas库将html转换成图片; 2. 利用jspdf库将canvas生成的图片转换成pdf格式。 后面发现html2pdf可以直接将html转换成pdf格式 示例代码如下 HTML to PDF conversion function createPDF () { // get the element of ticket content. const docElement = document.getElementById('ticket'); // select the element and save as the PDF. html2pdf().from(docElement).save(); } Jiyik Learning JavaScript create and download pdf Our Ticket Ticket content here Download as PDF html2pdf下载链接:"https://www.cdnpkg.com/html2pdf.js/file/html2pdf.bundle.min.js/" (https://link.segmentfault.com/?enc=W%2FgTXM%2FGAk0KP1rMTzEmSg%3D%3D.O3i6yJ5k4kIzoUPTdp%2FEUcXnwdOmyhcQA3L%2BXIkrEX87T%2FJBHo15XKZD0eSNxL%2FkSKNup%2BPddHJyHPKCKdqQtQ%3D%3D) 例如htnl2pdf好像更简洁,请问下两种方式哪种比较好?
前端Vue导出pdf文件,用的html2canvas和jspdf依赖,已经解决分页和字体内容模糊问题,但是会出现文字遭拦腰截断这种情况,有做过得相同经验么?https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241015/184c5d9d1a32c4e357564671d4e295d2.png