一行代码将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,提优化,共建项目。

相关推荐
Dorian_Ov04 小时前
GeoServer添加要素图层的SLD样式文件以及中文乱码相关解决方案
前端·gis
Holin_浩霖4 小时前
前端开发者的 Web3 全图解实战 一
前端
uhakadotcom4 小时前
deno在2025年新出了哪些api可供使用?
前端·面试·github
uhakadotcom4 小时前
2025年honojs提供了哪些新的基础能力与API可以使用?
前端·javascript·面试
Pluto5384 小时前
第一个成功在APP store 上架的APP
前端·后端·cursor
SWAYING4 小时前
每天不到1毛钱,用AI自动追踪GitHub热门项目并生成营销文案 | Cursor全程开发
前端·后端
沢田纲吉4 小时前
《LLVM IR 学习手记(五):关系运算与循环语句的实现与解析》
前端·c++·llvm
aidingni8884 小时前
保护你的前端:打造数字堡垒的艺术
前端·javascript
快乐是一切4 小时前
PDF底层结构之字体与编码系统
前端