jsPDF+html2canvas生成PDF适配问题:大屏导出内容错位空白
大屏导出PDF排版异常的解决办法
问题根源
- 屏幕视口影响DOM渲染:html2canvas基于当前屏幕的DOM状态截图,大屏下页面的响应式布局会改变元素位置、换行方式,导致截图内容和中等屏不一致,出现空白或错位。
- 异步循环顺序混乱:原代码的for循环同步执行,但html2canvas是异步操作,回调执行顺序不可控,会导致PDF页面添加和内容插入的顺序错乱。
具体修复步骤
1. 固定截图容器的渲染尺寸
强制要截图的.myDiv在任何屏幕下都使用和PDF页面匹配的固定宽度,避免响应式布局变化。可以在onclone回调中修改克隆后的DOM样式:
onclone: function (clonedDoc) { clonedDoc.getElementById("selfAssessment").style.display = "block"; // 给克隆后的容器设置固定宽度(对应letter横向页面的px宽度,1mm≈3.7795px,215.9mm≈816px) const clonedDiv = clonedDoc.querySelector('.myDiv'); if (clonedDiv) { clonedDiv.style.width = '816px'; clonedDiv.style.maxWidth = '816px'; clonedDiv.style.margin = '0 auto'; // 根据实际布局添加其他强制样式,比如禁止换行、固定高度等 } }
2. 修复异步循环的顺序问题
使用async/await配合for...of循环,确保前一个截图完成后再处理下一个元素,保证PDF内容的顺序正确:
修改后的完整代码:
setTimeout(async () => { const doc = new jsPDF('l', 'mm', 'letter', true); const htmlInput = document.querySelectorAll('.myDiv'); // 用for...of+await保证异步操作顺序 for (const div of htmlInput) { const canvas = await html2canvas(div, { scale: 2, // 提高截图分辨率,避免PDF内容模糊 onclone: function (clonedDoc) { clonedDoc.getElementById("selfAssessment").style.display = "block"; // 固定容器尺寸 const clonedDiv = clonedDoc.querySelector('.myDiv'); if (clonedDiv) { clonedDiv.style.width = '816px'; clonedDiv.style.maxWidth = '816px'; clonedDiv.style.margin = '0 auto'; } }, // 如果有跨域图片,添加useCORS: true // useCORS: true }); const imgWidth = 219; const imgHeight = canvas.height * imgWidth / canvas.width; doc.addImage(canvas.toDataURL('image/png'), 'PNG', 30, 10, imgWidth, imgHeight); // 非最后一个元素则添加新页面 if (!isLastItem(div, htmlInput)) { doc.addPage(); } } doc.save('data.pdf'); // 判断是否为最后一个元素的辅助函数 function isLastItem(item, list) { return list[list.length - 1] === item; } }, 2000);
3. 额外优化建议
- 替换固定超时:不要依赖2000ms的固定延迟,监听页面所有动态内容(如图片、异步组件)加载完成后再执行截图,比如监听图片的
load事件或使用IntersectionObserver确认元素渲染完成。 - 调整截图位置:如果PDF内容仍有偏移,可以修改
addImage的x、y参数(当前是30,10),微调内容在页面中的位置。
内容的提问来源于stack exchange,提问作者Shri Raksha Dk
相关产品推荐
相关产品推荐

