菜鸟-创作你的创作

基于JavaScript实现HTML到PDF的转换指南 

好的,我给你整理一份 基于 JavaScript 的 HTML → PDF 转换完整指南,涵盖浏览器端、Node.js 环境以及常用库和技巧,便于快速实现网页或内容导出 PDF。


基于 JavaScript 的 HTML 到 PDF 转换指南

1️⃣ 常用场景


2️⃣ 实现方式概览

方法适用环境特点常用库
浏览器端 JS浏览器用户端直接生成 PDF,无需服务端jsPDF, html2canvas
Node.js服务端生成 PDF 可自动化或批量处理puppeteer, playwright, pdfkit
API / 服务任何环境通过第三方 API 转换,快速简单pdfcrowd, html2pdf

3️⃣ 浏览器端实现

3.1 使用 jsPDF + html2canvas

<div id="content">
    <h1>标题</h1>
    <p>这是导出 PDF 的内容</p>
</div>
<button id="download">下载 PDF</button>

<script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
<script>
document.getElementById('download').onclick = async () => {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF('p', 'pt', 'a4');
    
    const content = document.getElementById('content');
    const canvas = await html2canvas(content, { scale: 2 });
    const imgData = canvas.toDataURL('image/png');

    const pageWidth = doc.internal.pageSize.getWidth();
    const pageHeight = doc.internal.pageSize.getHeight();
    const imgProps = doc.getImageProperties(imgData);
    const pdfHeight = (imgProps.height * pageWidth) / imgProps.width;

    doc.addImage(imgData, 'PNG', 0, 0, pageWidth, pdfHeight);
    doc.save('output.pdf');
};
</script>

优点:

缺点:


3.2 使用 html2pdf.js(封装方案)

<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
<script>
document.getElementById('download').onclick = () => {
    const element = document.getElementById('content');
    html2pdf()
        .set({ margin: 10, filename: 'output.pdf', html2canvas: { scale: 2 } })
        .from(element)
        .save();
};
</script>

html2pdf.js 底层仍使用 jsPDF + html2canvas,封装了分页、缩放和导出。


4️⃣ Node.js 服务端实现

4.1 使用 Puppeteer

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'networkidle0' });
  
  await page.pdf({
    path: 'example.pdf',
    format: 'A4',
    printBackground: true
  });

  await browser.close();
})();

优点:


4.2 使用 Playwright

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.pdf({ path: 'example.pdf', format: 'A4' });
  await browser.close();
})();


4.3 使用 PDFKit(纯 Node.js 绘制)

const PDFDocument = require('pdfkit');
const fs = require('fs');

const doc = new PDFDocument();
doc.pipe(fs.createWriteStream('output.pdf'));

doc.fontSize(25).text('Hello PDFKit', 100, 100);
doc.end();


5️⃣ 导出技巧

  1. 处理长页面
    • 浏览器端使用 html2canvas 分段截图
    • Puppeteer/Playwright 可自动分页 page.pdf({ format: 'A4', printBackground: true })
  2. 保留 CSS
    • 确保所有 CSS 已加载(字体、图片、背景色)
    • Puppeteer 支持 printBackground: true
  3. 动态内容
    • 等待 JS 渲染完成再导出:
    await page.waitForSelector('#content');
  4. 自定义页眉/页脚await page.pdf({ path: 'output.pdf', format: 'A4', displayHeaderFooter: true, headerTemplate: '<div style="font-size:12px">页眉</div>', footerTemplate: '<div style="font-size:12px">页脚</div>' });

6️⃣ 总结

场景推荐方案优缺点
前端单页内容导出jsPDF + html2canvas / html2pdf.js简单,但长页面分页复杂
服务端生成 PDFPuppeteer / Playwright高保真渲染,支持长页面、动态 JS
文本/图表生成PDFKit可绘制 PDF 元素,HTML 转换不便

总结:

  • 前端导出适合用户即时下载报表
  • 服务端生成适合批量、自动化或高保真 PDF
退出移动版