本文详解客户端 HTML 转 PDF 的完整配置、分页控制、Worker API 链式调用,以及跨域图片、Canvas 尺寸限制、CVE-2026-22787 XSS 漏洞修复等常见问题解决方案。
文章目录 **
- 一、html2pdf.js 项目简介
- 二、html2pdf.js 安装与引入
- 三、html2pdf.js 使用场景与实战案例
- 四、html2pdf.js 配置选项完全解析
- 五、Worker API 与高级用法
- 六、html2pdf.js 分页问题:避免内容截断的完整方案
- 七、html2pdf.js 常见问题与解决方案
- 7.1 html2pdf.js 生成的 PDF 文字模糊 / 图像质量差
- 7.2 html2pdf.js 跨域图片显示为空白
- 7.3 html2pdf.js 自定义字体(如 Inter、阿里巴巴普惠体)未生效
- 7.4 html2pdf.js 内容被 margin 截断 / 边缘裁切
- 7.5 长文档生成空白 PDF(Canvas 尺寸限制)
- 7.6 html2pdf.js 生成的PDF文字不可选中 / 搜索(固有局限)
- 7.7 Promise 冲突(与 Bluebird 等库冲突)
- 7.8 html2pdf.js 节点克隆导致 CSS 丢失 / 样式异常
- 7.9 根元素被 resize 导致内容重排
- 7.10 html2pdf.js XSS 安全漏洞(CVE-2026-22787)
- 八、html2pdf.js 与 html2canvas 的关系与协同
- 九、html2pdf.js 依赖与版本信息
- 十、使用建议与注意事项
你可能会问,鼠标右键就能打印网页,为什么还要自己编程实现这种需求。我的回答是:第一,做网页永远优先考虑移动端的体验;第二,需要精细化控制生成的PDF内容,而非打印整个HTML网页。
一、html2pdf.js 项目简介
html2pdf.js 是一个纯客户端 JavaScript 库,可将任意网页或 DOM 元素转换为可打印的 PDF 文档。它基于 html2canvas(负责将 HTML 渲染为 Canvas 图像)和 jsPDF(负责将图像封装为 PDF)构建,整个转换过程完全在浏览器中完成,无需服务器参与。
核心定位:html2pdf.js 本质上是一个"截图式"PDF 生成器——它将 HTML 内容先渲染为位图图像,再将图像嵌入 PDF。这意味着输出的是栅格图像而非矢量文本,文字不可选中和搜索,且文件体积较大。
html2pdf.js 基本用法示例
最简单的用法只需一行代码:
var element = document.getElementById("element-to-print");
html2pdf(element);
这将生成 #element-to-print 的 PDF 并自动触发下载。
二、html2pdf.js 安装与引入
CDN 引入(推荐)
使用 cdnjs 锁定特定版本,确保稳定性:
<script
src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"
integrity="sha512-GsLlZN/3F2ErC5ifS5QtgpiJtWd43JWSuIgh7mbzZ8zBps+dvLusV+eNQATqgA/HdeKFVgA5v3S/cIrLF7QnIg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
直接下载
下载 dist/html2pdf.bundle.min.js 到项目目录:
<script src="html2pdf.bundle.min.js"></script>
npm 安装
npm install --save html2pdf.js
注意:包名必须包含
.js后缀,即html2pdf.js而非html2pdf。
Bower 安装
bower install --save html2pdf.js
浏览器控制台临时使用
若无法修改页面源码,可在浏览器控制台中动态注入:
function addScript(url) {
var script = document.createElement("script");
script.type = "application/javascript";
script.src = url;
document.head.appendChild(script);
}
addScript(
"https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js",
);
// 注入后即可使用
html2pdf(document.body);
非打包版本依赖顺序
若使用未打包的 dist/html2pdf.min.js,必须按顺序引入依赖,否则 jsPDF 内置的 html2canvas 会覆盖独立版本:
<script src="jspdf.min.js"></script>
<script src="html2canvas.min.js"></script>
<script src="html2pdf.min.js"></script>
三、html2pdf.js 使用场景与实战案例
github仓库:github.com/eKoopmans/h…
场景 1:发票与报表导出
这是 html2pdf.js 最典型的应用场景。将页面中的发票或报表区域导出为 PDF。
function exportInvoice() {
const element = document.getElementById("invoice");
const opt = {
margin: [10, 10, 10, 10], // 上下左右边距 10mm
filename: `invoice-${Date.now()}.pdf`,
image: { type: "jpeg", quality: 0.98 },
html2canvas: {
scale: 2, // 高清输出
useCORS: true, // 允许跨域图片
scrollX: 0,
scrollY: 0,
},
jsPDF: {
unit: "mm",
format: "a4",
orientation: "portrait",
},
pagebreak: {
mode: ["css", "legacy"], // 尊重 CSS 分页规则
avoid: ".no-break", // 避免在这些元素内分页
},
};
html2pdf().set(opt).from(element).save();
}
代码参考自:blog.axiaoxin.com/post/html2p…
场景 2:简历 / 证书 / 合同一键下载
利用 onclone 在导出前隐藏编辑按钮、添加水印等。
function exportResume() {
const element = document.querySelector(".resume-container");
const opt = {
margin: 0,
filename: "my-resume.pdf",
image: { type: "jpeg", quality: 0.95 },
html2canvas: { scale: 2 },
jsPDF: { unit: "mm", format: "a4", orientation: "portrait" },
};
// 使用 Worker API 在生成后添加水印
html2pdf()
.set(opt)
.from(element)
.toPdf()
.get("pdf")
.then(function (pdf) {
// 在每页添加页眉/页脚
const totalPages = pdf.internal.getNumberOfPages();
for (let i = 1; i <= totalPages; i++) {
pdf.setPage(i);
pdf.setFontSize(10);
pdf.text("Confidential - Page " + i + " of " + totalPages, 10, 287);
}
})
.save();
}