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

相关推荐
web打印社区10 小时前
前端开发实现PDF打印需求:从基础方案到专业解决方案
前端·vue.js·react.js·electron·pdf
时光追逐者10 小时前
使用 MWGA 帮助 7 万行 Winforms 程序快速迁移到 WEB 前端
前端·c#·.net
搬砖的阿wei10 小时前
CSS常用选择器总结
前端·css
2601_9498333911 小时前
flutter_for_openharmony口腔护理app实战+意见反馈实现
android·javascript·flutter
Trae1ounG11 小时前
Vue Iframe
前端·javascript·vue.js
阿部多瑞 ABU11 小时前
`tredomb`:一个面向「思想临界质量」初始化的 Python 工具
前端·python·ai写作
比特森林探险记11 小时前
React API集成与路由
前端·react.js·前端框架
爱上妖精的尾巴12 小时前
8-1 WPS JS宏 String.raw等关于字符串的3种引用方式
前端·javascript·vue.js·wps·js宏·jsa
hvang198812 小时前
某花顺隐藏了重仓涨幅,通过chrome插件计算基金的重仓涨幅
前端·javascript·chrome
Async Cipher12 小时前
TypeScript 的用法
前端·typescript