html2canvas导出pdf 网页截图怎么生成pdf【转换】

1次阅读

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

html2canvas导出pdf 网页截图怎么生成pdf【转换】

html2canvas 本身不生成 PDF,得靠 jsPDF 中转

html2canvas 只负责把网页元素画成 Canvas 图片,它没有 PDF 生成功能。想导出 PDF,必须把 canvas 输出的 data URLblob 交给 jsPDFaddImage() 方法拼成 PDF 页面。

常见错误是直接调用 html2canvas().then(canvas => canvas.toBlob(...)) 就以为完事了——结果只拿到一张 PNG,根本不是 PDF。

  • 必须引入 jsPDF(推荐用 jspdf@2.5.1+,老版本对高 DPI 屏幕支持差)
  • html2canvasscale 建议设为 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 成空白。

  • 确保运行环境装了中文字体(如 ubuntufonts-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,避免因个别资源加载失败中断整个截图流程

实际导出逻辑就三步:用 html2canvas 渲染整块 DOM → 转成 data URL → 丢给 jsPDF 插入页面。难点不在代码长短,而在每一步的隐式依赖:字体、DPI、CORS、容器尺寸——漏一个,PDF 就不是你看到的那个样子。

text=ZqhQzanResources