下面给你整理一份 《基于 JavaScript 实现 HTML 到 PDF 的转换指南(2025 最新版)》,覆盖客户端(浏览器)、服务端(Node.js)、主流库、实践示例和优化技巧,直接可用于项目开发或学习。


🚀 JavaScript 实现 HTML → PDF 转换指南

前端常见场景:

  • 导出报表 / 票据 / 合同
  • 保存网页内容 / 图表 / Dashboard
  • 打印预览 / 下载 PDF

实现方式主要分为:

  1. 浏览器端 JS(Client-side)
  2. Node.js 服务端生成(Server-side)

⭐ 一、浏览器端 JS 生成 PDF

浏览器端的优势:无需服务器支持,用户本地即可生成。

1️⃣ 使用 html2canvas + jsPDF(最常用)

安装:

npm install jspdf html2canvas

示例:

<div id="content">
  <h1>报告标题</h1>
  <p>这里是内容...</p>
</div>
<button id="btnDownload">下载 PDF</button>

<script type="module">
import jsPDF from "jspdf";
import html2canvas from "html2canvas";

const btn = document.getElementById("btnDownload");
btn.addEventListener("click", async () => {
  const content = document.getElementById("content");

  const canvas = await html2canvas(content, { scale: 2 });
  const imgData = canvas.toDataURL("image/png");

  const pdf = new jsPDF("p", "mm", "a4");
  const imgProps = pdf.getImageProperties(imgData);
  const pdfWidth = pdf.internal.pageSize.getWidth();
  const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;

  pdf.addImage(imgData, "PNG", 0, 0, pdfWidth, pdfHeight);
  pdf.save("report.pdf");
});
</script>

✅ 优点:

  • 简单易用
  • 支持 DOM 元素截图,保留样式
  • 不需要后端

⚠️ 缺点:

  • 内容多页需要手动分页处理
  • 大型页面可能内存消耗高
  • 对字体排版、表格渲染有限制

2️⃣ 使用 pdfMake(适合表格、报表)

安装:

npm install pdfmake

示例:

import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";

pdfMake.vfs = pdfFonts.pdfMake.vfs;

const docDefinition = {
  content: [
    { text: 'PDF 报告', fontSize: 18, bold: true },
    { text: '生成时间: ' + new Date().toLocaleString() },
    {
      table: {
        body: [
          ['姓名', '年龄', '性别'],
          ['张三', '28', '男'],
          ['李四', '32', '女']
        ]
      }
    }
  ]
};

pdfMake.createPdf(docDefinition).download("report.pdf");

✅ 优点:

  • 支持多页、表格、页眉页脚
  • 排版精准,不依赖 DOM
  • 客户端生成速度快

⚠️ 缺点:

  • 样式自定义相对复杂
  • 不适合复杂 HTML 或图表直接转换

⭐ 二、服务端 Node.js 生成 PDF

服务端生成 PDF 适合 批量导出 / 自动化

1️⃣ 使用 puppeteer(Chrome Headless)

安装:

npm install puppeteer

示例:

import puppeteer from "puppeteer";

async function generatePDF() {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // 加载 HTML
  await page.setContent(`
    <html>
      <body>
        <h1>报表标题</h1>
        <p>这是服务端生成的 PDF 示例</p>
      </body>
    </html>
  `);

  await page.pdf({ path: "report.pdf", format: "A4", printBackground: true });
  await browser.close();
}

generatePDF();

✅ 优点:

  • 完整渲染 HTML/CSS/JS
  • 支持图表、字体、图片
  • 生成效果接近浏览器打印

⚠️ 缺点:

  • Node.js 依赖 Chromium
  • 对资源性能消耗较高

2️⃣ 使用 wkhtmltopdf(通过 Node 调用)

安装:

npm install wkhtmltopdf

示例:

import wkhtmltopdf from "wkhtmltopdf";
import fs from "fs";

wkhtmltopdf('<h1>Hello PDF</h1>', { output: 'report.pdf' });

✅ 优点:

  • 支持复杂 HTML/CSS
  • 速度快,内存占用小

⚠️ 缺点:

  • 外部依赖,需要安装 wkhtmltopdf
  • 不支持 JS 动态渲染

⭐ 三、PDF 转换优化技巧

  1. 分页处理
    • html2canvas + jsPDF:手动拆分页
    • pdfMake / puppeteer:支持自动分页
  2. 图表导出
    • Chart.js / ECharts → 转 Canvas → PNG → PDF
  3. 字体问题
    • pdfMake 可嵌入自定义字体
    • puppeteer:系统已安装字体即可
  4. 多页表格
    • pdfMake 支持 headerRowspageBreak
    • puppeteer 可用 CSS break-inside: avoid
  5. 样式优化
    • 浏览器端使用内联 CSS 保证渲染一致
    • puppeteer 支持完整 CSS 文件加载

⭐ 四、总结与选型建议

场景推荐方案优点缺点
简单 HTML / 单页html2canvas + jsPDF简单,客户端生成大页面性能差
报表 / 表格pdfMake排版精准,多页支持样式复杂时需手动写布局
高保真页面puppeteer支持 JS 动态内容、图表依赖 Chromium,资源占用高
自动化 / 批量puppeteer / wkhtmltopdf可后台生成 PDF需服务端环境