HTML截图与页面导出目标不同、技术路径不同,混用易致字体缺失、分页错乱;html2canvas生成位图导致PDF失真,原生window.print()才是导出正道。

HTML 截图和页面导出不冲突,但二者目标不同、技术路径不同,强行混用反而容易出错——比如用 screenshot() 拿到的图片去“替代” PDF 导出,结果发现字体缺失、分页错乱、打印样式没生效。
为什么 html2canvas 截图后导出 PDF 常见失真?
这是最常踩的坑:html2canvas 是把 DOM 渲染成 Canvas 位图,本质是「拍快照」;而 PDF 导出(如 jsPDF + html2canvas 组合)是把这张图塞进 PDF,丢失了文本可选、矢量缩放、CSS 分页控制等能力。
-
html2canvas不支持@media print样式,打印专用布局完全失效 - 中文字体、WebFont 在 Canvas 中常 fallback 到系统默认字体(如 `sans-serif`),导致乱码或字重异常
- 滚动区域(
overflow: scroll)默认只截当前视口,需手动滚动+拼接,极易漏内容 - Canvas 导出为 PNG 再转 PDF,文件体积大、放大模糊、无法复制文字
真正要「导出页面」,优先走原生打印流
浏览器原生打印(window.print())或 iframe + contentWindow.print() 是最稳妥的导出路径——它尊重 CSS @media print、保留字体嵌入(只要字体允许嵌入)、支持自动分页与页眉页脚。
- 给要导出的区域加独立
class="print-only",用@media print { .screen-only { display: none; } }控制显示 - 确保关键字体通过
@font-face声明且font-display: swap或block,避免打印时回退 - 避免在
@media print中使用transform、filter等部分浏览器不支持的属性 - 导出前调用
document.execCommand('print')已废弃,必须用window.print()
什么时候才该用截图 + PDF?
仅当页面含大量 Canvas、WebGL、第三方图表库(如 ECharts 的 SVG 模式关了、纯 Canvas 渲染)且无法改用服务端渲染时,才考虑截图兜底。此时务必:
立即学习“前端免费学习笔记(深入)”;
- 先用
html2canvas(element, { useCORS: true, scale: 2, logging: false })提升清晰度 - 截图前手动设置
element.style.width和element.style.height为实际内容尺寸,避免缩放裁剪 - PDF 插入图片时指定宽高(单位 mm),别依赖自动缩放:
doc.addImage(imgData, 'PNG', 0, 0, 210, 0)(A4 宽 210mm) - 放弃文本可选性预期——这不是缺陷,是技术选型决定的边界
导出的本质不是“让页面变成文件”,而是“让信息以目标格式可靠传递”。截图适合留证、分享快照;原生打印流才是导出的正道。字体、分页、语义化这些细节,一不留神就让 PDF 在客户打印机上跑偏两页——与其后期 debug,不如一开始选对链路。



















