一行代码将html页面转成矢量PDF

非标题党,真的一行代码就可以实现纯前端 html 转矢量 pdf 的功能

javascript 复制代码
// 引入 dompdf.js库
import dompdf from "dompdf.js";

dompdf(document.querySelector("#capture")).then(function (blob) {
  //文件操作
});

实现效果(复杂表格)

1. 在线体验

dompdfjs.lisky.com.cn

2. Git 仓库地址 (欢迎 Star⭐⭐⭐)

github.com/lmn1919/dom...

3. 生成 PDF

在前端生态里,把网页内容生成 PDF 一直是一个常见但不简单的需求。从报表导出、小票生成、合同下载到打印排版,很多项目或多或少都会遇到。市面上常见的方案大致有以下几类:

  • 服务端渲染 PDF(后端库如 wkhtmltopdf、PrinceXML 等)

  • 客户端将 HTML 渲染为图片(如 html2canvas + jsPDF)然后再封装为 PDF

  • 前端调用相关 pdf 生成库来生成 PDF(如 pdfmake,jspdf,pdfkit)

但是这些方案都有各自的局限性,

  • 比如服务端渲染 PDF 对服务器资源要求高,需要后端参与。

  • html2canvas + jsPDF 需要将 html 内容渲染为图片,再将图片封装为 PDF,速度会比较慢,而且生成体积会比较大,内容会模糊,限制于 canvas 生成高度,不能生成超过 canvas 高度的内容。

  • 而前端调用相关 pdf 生成库来生成 PDF 则需要对相关库有一定的了解,api 比较复杂,学习使用成本很高。

使用 jspdf 生成如图简单的 pdf

就需要如此复杂的代码,如果要生成复杂的 pdf, 比如包含表格、图片、图表等内容,那使用成本就更高了。

javascript 复制代码
function generateChinesePDF() {
  // Check if jsPDF is loaded
  if (typeof window.jspdf === "undefined") {
    alert("jsPDF library has not finished loading, please try again later");
    return;
  }

  const { jsPDF } = window.jspdf;
  const doc = new jsPDF();

  // Note: Default jsPDF does not support Chinese, this is just a demo
  // In real projects you need to add Chinese font support

  doc.setFontSize(16);
  doc.text("Chinese Text Support Demo", 20, 30);

  doc.setFontSize(12);
  doc.text("Note: Default jsPDF does not support Chinese characters.", 20, 50);
  doc.text("You need to add Chinese font support for proper display.", 20, 70);

  // Draw some graphics for demonstration
  doc.setFillColor(255, 182, 193);
  doc.rect(20, 90, 60, 30, "F");
  doc.setTextColor(0, 0, 0);
  doc.text("Pink Rectangle", 25, 108);

  doc.setFillColor(173, 216, 230);
  doc.rect(100, 90, 60, 30, "F");
  doc.text("Light Blue Rectangle", 105, 108);

  doc.save("chinese-example.pdf");
}

但是现在,有了 dompdf.js,你只需要一行代码,就可以完成比这个复杂 10 倍的 PDF 生成任务,html页面所见即所得,可以将复杂的css样式转化成pdf

javascript 复制代码
dompdf(document.querySelector("#capture")).then(function (blob) {
  //文件操作
});

而且,dompdf.js 生成的 PDF 是矢量的,非图片式的,高清晰度的,文字可以选中、复制、搜索等操作(在支持的 PDF 阅读器环境下),区别于客户端将 HTML 渲染为图片(如 html2canvas + jsPDF)然后再封装为 PDF。

具体可以去体验 立即体验 https://dompdfjs.lisky.com.cn

4. dompdf.js 是如何实现的?

其实 dompdf.js 也是基于 html2canvas+jspdf 实现的,但是为什么 dompdf.js 生成的 pdf 文件可以二次编辑,更清晰,体积小呢?

不同于普通的 html2canvas + jsPDF 方案,将 dom 内容生成为图片,再将图片内容用 jspdf 绘制到 pdf 上,这就导致了生成的 pdf 文件体积大,无法编辑,放大后会模糊。

html2canvas 原理简介

1. DOM 树遍历 html2canvas 从指定的 DOM 节点开始,递归遍历所有子节点,构建一个描述页面结构的内部渲染队列。

2. 样式计算 对每个节点调用 window.getComputedStyle() 获取最终的 CSS 属性值。这一步至关重要,因为它包含了所有 CSS 规则(内联、内部、外部样式表)层叠计算后的最终结果。

3. 渲染模型构建 将每个 DOM 节点和其计算样式封装成渲染对象,包含绘制所需的完整信息:位置(top, left)、尺寸(width, height)、背景、边框、文本内容、字体属性、层级关系(z-index)等。

4. Canvas 上下文创建 在内存中创建 canvas 元素,获取其 2D 渲染上下文(CanvasRenderingContext2D)。

5. 浏览器绘制模拟 按照 DOM 的堆叠顺序和布局规则,遍历渲染队列,将每个元素绘制到 Canvas 上。这个过程实质上是将 CSS 属性"翻译"成对应的绘制 API 调用:

CSS 属性 传统 Canvas API dompdf.js 中的 jsPDF API
background-color ctx.fillStyle + ctx.fillRect() doc.setFillColor() + doc.rect(x, y, w, h, 'F')
border ctx.strokeStyle + ctx.strokeRect() doc.setDrawColor() + doc.rect(x, y, w, h, 'S')
color, font-family, font-size ctx.fillStyle, ctx.font + ctx.fillText() doc.setTextColor() + doc.setFont() + doc.text()
border-radius arcTo()bezierCurveTo() 创建剪切路径 doc.roundedRect()doc.lines() 绘制圆角
image ctx.drawImage() doc.addImage()

核心创新:API 替换,底层是封装了 jsPDF 的 API dompdf.js 的关键突破在于改造了 html2canvas 的 canvas-renderer.ts 文件,将原本输出到 Canvas 的绘制 API 替换为 jsPDF 的 API 调用。这样就实现了从 DOM 直接到 PDF 的转换,生成真正可编辑、可搜索的 PDF 文件,而不是传统的图片格式。

目前实现的功能

1. 文字绘制 (颜色,大小) 2. 图片绘制 (支持 jpeg, png 等格式) 3. 背景,背景颜色 (支持合并单元格) 4. 边框,复杂表格绘制 (支持合并单元格) 5. canvas (支持多种图表类型) 6. svg (支持 svg 元素绘制) 7. 阴影渲染 (使用 foreignObjectRendering,支持边框阴影渲染) 8. 渐变渲染 (使用 foreignObjectRendering,支持背景渐变渲染)

7.使用

安装

bash 复制代码
        npm install dompdf.js --save

CDN 引入

html 复制代码
<script src="https://cdn.jsdelivr.net/npm/dompdf.js@latest/dist/dompdf.js"></script>

基础用法

js 复制代码
import dompdf from "dompdf.js";
dompdf(document.querySelector("#capture"), {
  useCORS: true, //是否允许跨域
})
  .then(function (blob) {
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "example.pdf";
    document.body.appendChild(a);
    a.click();
  })
  .catch(function (err) {
    console.log(err, "err");
  });

写在最后

dompdf.js 让前端 PDF 生成变得前所未有的简单:无需后端、无需繁琐配置、一行代码即可输出矢量、可检索、可复制的专业文档。无论是简历、报告还是发票,它都能轻松胜任。 欢迎在你的项目中使用它 。

如果它帮到了你,欢迎去 github.com/lmn1919/dom... 点个 Star,提优化,共建项目。

相关推荐
天若有情6736 分钟前
前端HTML精讲03:页面性能优化+懒加载,搞定首屏加速
前端·性能优化·html
踩着两条虫18 分钟前
AI驱动的Vue3应用开发平台深入探究(十):物料系统之内置组件库
android·前端·vue.js·人工智能·低代码·系统架构·rxjava
和沐阳学逆向22 分钟前
我现在怎么用 CC Switch 管中转站,顺手拿 Codex 举个例子
开发语言·javascript·ecmascript
swipe43 分钟前
AI 应用里的 Memory,不是“保存聊天记录”,而是管理上下文预算
前端·llm·agent
慧一居士1 小时前
nuxt3 项目和nuxt4 项目区别和对比
前端·vue.js
威联通安全存储1 小时前
破除“重前端、轻底层”的数字幻象:如何夯实工业数据的物理底座
前端·python
inksci2 小时前
Js生成安全随机数
前端·微信小程序
吴声子夜歌2 小时前
TypeScript——泛型
前端·git·typescript
kgduu3 小时前
js之客户端存储
javascript·数据库·oracle
四千岁3 小时前
2026 最新版:WSL + Ubuntu 全栈开发环境,一篇搞定!
javascript·node.js