如何在客户端将网页HTML转为PDF?html2pdf.js 完全实战指南
本文详解客户端 HTML 转 PDF 的完整配置、分页控制、Worker API 链式调用,以及跨域图片、Canvas 尺寸限制、CVE-2026-22787 XSS 漏洞修复等常见问题解决方案。 文章目录 ** 你可能会问,鼠标右键就能打印网页,为什么还要自己编程实现这种需求。我的回答是:第一,做网页永远优先考虑移动端的体验;第二,需要精细化控制生成的PDF内容,而非打印整个HTML网页。 html2pdf.js 是一个纯客户端 JavaScript 库,可将任意网页或 DOM 元素转换为可打印的 PDF 文档。它基于 html2canvas(负责将 HTML 渲染为 Canvas 图像)和 jsPDF(负责将图像封装为 PDF)构建,整个转换过程完全在浏览器中完成,无需服务器参与。 最简单的用法只需一行代码: 这将生成 使用 cdnjs 锁定特定版本,确保稳定性: 下载 若无法修改页面源码,可在浏览器控制台中动态注入: 若使用未打包的 github仓库:https://github.com/eKoopmans/html2pdf.js 这是 html2pdf.js 最典型的应用场景。将页面中的发票或报表区域导出为 PDF。 利用 一、html2pdf.js 项目简介
核心定位:html2pdf.js 本质上是一个"截图式"PDF 生成器——它将 HTML 内容先渲染为位图图像,再将图像嵌入 PDF。这意味着输出的是栅格图像而非矢量文本,文字不可选中和搜索,且文件体积较大。
html2pdf.js 基本用法示例
var element = document.getElementById("element-to-print");
html2pdf(element);#element-to-print 的 PDF 并自动触发下载。二、html2pdf.js 安装与引入
CDN 引入(推荐)
<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 使用场景与实战案例
场景 1:发票与报表导出
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();
}场景 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();
}场景 3:长文档分页导出(避免内容截断)