前端 HTML 转 PDF 的两种主流方案深度解析
目前前端生成 PDF 最主流的两种方案是:
- 客户端方案:
html2canvas + jsPDF(或其封装库html2pdf.js) - 服务端方案:
Puppeteer / Playwright(Node.js 无头浏览器)
这两种方案几乎占据了 90% 以上的实际项目。下面从原理、优缺点、适用场景、核心代码、坑点与优化等维度进行深度对比。
一、核心对比表(快速决策)
| 维度 | 客户端方案(html2canvas + jsPDF) | 服务端方案(Puppeteer / Playwright) | 胜出方 |
|---|---|---|---|
| 实现难度 | ★☆☆☆☆(最简单) | ★★★☆☆(需后端) | 客户端 |
| 生成质量 | 中等(样式丢失常见) | 极高(接近浏览器打印效果) | 服务端 |
| 中文/字体支持 | 较差(需特殊处理) | 优秀(可加载本地字体) | 服务端 |
| 大文件 / 长页面 | 容易卡顿、崩溃 | 稳定 | 服务端 |
| 分页控制 | 弱(需 hack) | 强(支持 @page、页眉页脚) | 服务端 |
| 部署复杂度 | 零(纯前端) | 中等(需 Node 服务) | 客户端 |
| 性能压力 | 前端浏览器承担 | 后端服务器承担 | 看场景 |
| 安全性 | 高(客户端) | 中(后端需注意 HTML 注入) | 客户端 |
| 推荐场景 | 简单报表、导出预览、H5 小程序 | 正式合同、发票、复杂报告、打印级 PDF | — |
二、方案一:客户端 —— html2canvas + jsPDF(最常用)
原理
html2canvas把 DOM 元素渲染成 Canvas(像素级截图)jsPDF把 Canvas 转为 PDF 文件并下载
推荐库
- 直接用
html2pdf.js(封装版,最推荐) - 或手动组合
html2canvas + jsPDF
核心代码(Vue 3 + html2pdf.js)
<template>
<div ref="content">
<!-- 你的 HTML 内容 -->
<h1>发票标题</h1>
<table>...</table>
</div>
<button @click="exportPDF">导出 PDF</button>
</template>
<script setup>
import html2pdf from 'html2pdf.js'
const content = ref(null)
const exportPDF = () => {
const opt = {
margin: [10, 10, 10, 10],
filename: 'report.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: {
scale: 2, // 清晰度(2 倍最合适)
useCORS: true, // 跨域图片
letterRendering: true
},
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
}
html2pdf().set(opt).from(content.value).save()
}
</script>

