javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > 前端HTML转PDF方案

前端实现HTML转PDF的两种主流方案详解

作者:likuolei

本文详细对比了前端生成PDF的两种主流方案:客户端(html2canvas+jsPDF)和服务端(Puppeteer/Playwright),从原理、优缺点、适用场景、核心代码、坑点与优化等方面进行分析,推荐了适合不同场景的方案,需要的朋友可以参考下

目前前端生成 PDF 最主流的两种方案是:

  1. 客户端方案:html2canvas + jsPDF(或其封装库 html2pdf.js)
  2. 服务端方案Puppeteer / Playwright(Node.js 无头浏览器)

这两种方案几乎占据了 90% 以上的实际项目。下面从原理、优缺点、适用场景、核心代码、坑点与优化等维度进行深度对比。

一、核心对比表(快速决策)

维度客户端方案(html2canvas + jsPDF)服务端方案(Puppeteer / Playwright)胜出方
实现难度★☆☆☆☆(最简单)★★★☆☆(需后端)客户端
生成质量中等(样式丢失常见)极高(接近浏览器打印效果)服务端
中文/字体支持较差(需特殊处理)优秀(可加载本地字体)服务端
大文件 / 长页面容易卡顿、崩溃稳定服务端
分页控制弱(需 hack)强(支持 @page、页眉页脚)服务端
部署复杂度零(纯前端)中等(需 Node 服务)客户端
性能压力前端浏览器承担后端服务器承担看场景
安全性高(客户端)中(后端需注意 HTML 注入)客户端
2026 年推荐场景简单报表、导出预览、H5 小程序正式合同、发票、复杂报告、打印级 PDF

二、方案一:客户端 —— html2canvas + jsPDF(最常用)

原理

  1. html2canvas 把 DOM 元素渲染成 Canvas(像素级截图)
  2. jsPDF 把 Canvas 转为 PDF 文件并下载

推荐库

核心代码(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>

优点

致命缺点(2026 年仍未彻底解决)

优化技巧

三、方案二:服务端 —— Puppeteer / Playwright(质量之王)

原理

启动无头浏览器(Headless Chrome / Firefox / WebKit),加载完整 HTML 页面后,直接调用 page.pdf() 生成 PDF。

2026 年推荐:Playwright(已全面超越 Puppeteer)

Playwright 优势:多浏览器支持、自动等待、API 更现代、稳定性更高。

核心代码(Node.js + Express)

// pdfService.js
const { chromium } = require('playwright')

async function htmlToPdf(htmlContent) {
  const browser = await chromium.launch({ headless: true })
  const page = await browser.newPage()

  // 关键:设置视口和打印样式
  await page.setContent(htmlContent, { waitUntil: 'networkidle' })

  const pdfBuffer = await page.pdf({
    format: 'A4',
    printBackground: true,
    margin: { top: '15mm', bottom: '15mm', left: '10mm', right: '10mm' },
    displayHeaderFooter: true,
    headerTemplate: '<div style="font-size:10px;width:100%;text-align:center;">页眉</div>',
    footerTemplate: '<div style="font-size:10px;width:100%;text-align:center;">第 <span class="pageNumber"></span> 页</div>'
  })

  await browser.close()
  return pdfBuffer
}

前端调用示例

const res = await fetch('/api/export-pdf', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ html: document.getElementById('content').outerHTML })
})

const blob = await res.blob()
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'report.pdf'
a.click()

优点

缺点

四、最终推荐(2026 年真实选择)

你现在要做的是哪类 PDF?

告诉我具体需求,我可以给你对应方案的最优完整代码模板。

以上就是前端实现HTML转PDF的两种主流方案详解的详细内容,更多关于前端HTML转PDF方案的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文