html2canvas 仅生成 canvas 图片,导出 pdf 必须结合 jspdf 的 addimage();需设 scale: 2、手动适配 a4 像素尺寸(794×1123)、确保中文字体可用、usecors: true + allowtaint: false 解决跨域与截全问题。

html2canvas 本身不生成 PDF,得靠 jsPDF 中转
html2canvas 只负责把网页元素画成 Canvas 图片,它没有 PDF 生成功能。想导出 PDF,必须把 canvas 输出的 data URL 或 blob 交给 jsPDF 的 addImage() 方法拼成 PDF 页面。
常见错误是直接调用 html2canvas().then(canvas => canvas.toBlob(...)) 就以为完事了——结果只拿到一张 PNG,根本不是 PDF。
- 必须引入
jsPDF(推荐用jspdf@2.5.1+,老版本对高 DPI 屏幕支持差) -
html2canvas的scale建议设为2,否则在 Retina 屏上截图模糊 - 如果页面内容超一页,
jsPDF不会自动分页——得手动切区域、多次addImage()
导出 A4 尺寸 PDF 时,canvas 宽高要按 96dpi 换算
浏览器里 1cm ≈ 37.8px(按 96dpi 计算),A4 纸是 210mm × 297mm → 换算成像素约 794px × 1123px。但 html2canvas 默认按元素原始尺寸渲染,不考虑打印尺寸,所以得手动控制 canvas 输出大小。
否则 PDF 看起来“太小”或“被压缩”,尤其文字边缘发虚。
立即学习“前端免费学习笔记(深入)”;
- 给
html2canvas传{ width: 794, height: 1123, scale: 2 },确保输出 canvas 至少 1588×2246 像素 - 创建
jsPDF实例时用new jsPDF({ unit: 'px', format: [794, 1123] }),单位和尺寸对齐 - 调用
addImage()时指定宽高:pdf.addImage(imgData, 'PNG', 0, 0, 794, 1123)
中文乱码?字体没嵌入,不是编码问题
jsPDF 默认只支持 ASCII 字体,哪怕页面用了 @font-face 引入思源黑体,导出 PDF 后中文仍显示为方块——因为 addImage() 是把 canvas 当图片贴进去,字体渲染已在 canvas 阶段完成;而 canvas 绘制中文依赖系统字体,若目标环境(比如 Linux 服务器或无头浏览器)缺字体,就直接 fallback 成空白。
- 确保运行环境装了中文字体(如 Ubuntu 装
fonts-wqy-zenhei) - 开发时用 Chrome 浏览器测试,避免在 Electron 或 Puppeteer 里跑 html2canvas 却没配好字体路径
- 不要指望
jsPDF.setFont()对addImage()生效——它只影响text()方法绘制的文字
滚动区域截不全?别用 scrollY,改用 useCORS: true + allowTaint: false
如果要截图的区域超出视口(比如长表格、带 overflow-y: scroll 的 div),html2canvas 默认只渲染当前可见部分。有人试过先滚到顶部再截图,但异步滚动 + 渲染时机难控,容易截漏。
真正可靠的解法是让 html2canvas 强制渲染整个 DOM 区域,而不是依赖滚动位置。
- 给目标容器加
style="height: auto; overflow: visible;"临时撑开(注意别影响原布局) -
html2canvas选项里必须设useCORS: true,否则跨域图片(如 CDN 上的 avatar)会触发 canvas 污染,导致toDataURL()报错Failed to execute 'toDataURL' on 'HTMLCanvasElement' - 同时设
allowTaint: false,避免因个别资源加载失败中断整个截图流程
data URL → 丢给 jsPDF 插入页面。难点不在代码长短,而在每一步的隐式依赖:字体、DPI、CORS、容器尺寸——漏一个,PDF 就不是你看到的那个样子。











