jsPDF生成PDF时首页URL图片无法渲染的解决方法问询
解决jsPDF生成PDF时首页图片未加载的问题
问题重现
现有HTML结构:
<div id="printDiv"> <img src="https://www.example.com/cover.png"> </div>
使用jsPDF生成PDF的代码:
new jsPDF('p', 'pt', 'a4', true).html( document.getElementById('printDiv'), { filename: 'print.pdf', image: { quality: 10, type: 'png' }, html2canvas: { // scale: 2, // 设为2时图片被推到第二页可正常显示 }, callback: function (doc) { doc.save(); }, } );
遇到的问题:生成的PDF中仅首页图片无法显示,推测是图片加载耗时较长,晚于首页渲染完成;将html2canvas.scale设为2时,图片被推到第二页即可正常显示。需要修改代码确保首页图片在PDF渲染前完成加载。
可行解决方案
方法1:预加载所有图片后再生成PDF
先等待目标容器内的所有图片加载完成,再执行PDF生成逻辑,从根源避免渲染时图片未就绪的问题。
function generatePDF() { const printDiv = document.getElementById('printDiv'); const images = printDiv.querySelectorAll('img'); let loadedCount = 0; // 所有图片加载完成后触发PDF生成 function triggerPDF() { loadedCount++; if (loadedCount === images.length) { const doc = new jsPDF('p', 'pt', 'a4', true); doc.html(printDiv, { filename: 'print.pdf', image: { quality: 10, type: 'png' }, html2canvas: {}, callback: (doc) => doc.save(), }); } } // 遍历处理每张图片 images.forEach(img => { // 图片已加载完成的情况直接计数 if (img.complete) { triggerPDF(); } else { // 监听加载/错误事件,确保无论成功失败都继续流程 img.addEventListener('load', triggerPDF); img.addEventListener('error', triggerPDF); } }); // 容器内无图片时直接生成PDF if (images.length === 0) { triggerPDF(); } } // 调用生成函数 generatePDF();
方法2:利用html2canvas的onclone回调等待图片加载
在html2canvas的配置中使用onclone回调,克隆DOM后等待所有图片加载完成再继续渲染流程:
new jsPDF('p', 'pt', 'a4', true).html( document.getElementById('printDiv'), { filename: 'print.pdf', image: { quality: 10, type: 'png' }, html2canvas: { onclone: async (cloneDoc) => { const cloneImages = cloneDoc.querySelectorAll('img'); // 用Promise.all等待所有图片加载完成 await Promise.all(Array.from(cloneImages).map(img => { if (img.complete) return Promise.resolve(); return new Promise(resolve => { img.addEventListener('load', resolve); img.addEventListener('error', resolve); }); })); } }, callback: (doc) => doc.save(), } );
方法3:延长html2canvas的超时时间
如果图片只是加载稍慢,可以尝试延长html2canvas的超时时间,给图片足够的加载窗口:
new jsPDF('p', 'pt', 'a4', true).html( document.getElementById('printDiv'), { filename: 'print.pdf', image: { quality: 10, type: 'png' }, html2canvas: { timeout: 5000, // 设置为5秒,可根据实际加载速度调整 }, callback: (doc) => doc.save(), } );
内容的提问来源于stack exchange,提问作者Peter Huang
相关产品推荐
相关产品推荐

