☰
dompdf.js终极指南:浏览器端HTML转PDF引擎,零后端、无jsPDF,一行代码生成可选中矢量PDF
2026/10/11 18:54:08 网站建设 项目流程

【免费下载链接】dompdf.js

HTML to PDF in the browser — one line of code for selectable, searchable vector PDFs (10,000+ pages). Pure frontend: zero backend, zero runtime deps. TypeScript over a Rust + WebAssembly engine; an html2canvas/jsPDF alternative.

项目地址:https://gitcode.com/gh_mirrors/do/dompdf.js
点击查看免费下载

dompdf.js是一个纯前端的浏览器端 HTML 转 PDF 引擎:它直接读取浏览器已计算好的 DOM 布局,在浏览器内生成可选中、可搜索的矢量 PDF。零后端、无 jsPDF 依赖,一行代码即可导出,500 页文档典型耗时约 2 秒,极限可扩到上万页。

它是什么?为什么值得用?

传统的「HTML 转 PDF」方案大多依赖html2canvas + jsPDF:先把整个页面截图成 Canvas,再拼进 PDF。结果就是——文字变成了图片:不可选、不可搜索,文件还特别大。

dompdf.js换了一条路:

不截图,而是读取浏览器已经算好的布局几何信息,重新「画」出一份以矢量文本为主的 PDF。

这意味着:

  • ✅ 文本可复制、可搜索、可放大不失真
  • ✅ 整份文档不经过服务器,隐私零上传
  • ✅ 长文档性能强:典型测试约 2 秒生成 500 页
  • ✅ 自带页眉页脚、水印、中文字体、表单、加密等导出刚需能力

一句话定位:它是 html2canvas/jsPDF 的替代方案,也是目前少有的「纯前端 + Rust/WASM」矢量 PDF 引擎。

功能清单:一张表看懂能力

能力说明
📄 分页与纸张A/B/C 系列、Letter、Legal、Tabloid 及自定义尺寸
📑 页眉页脚页码占位符${currentPage}/${totalPages}、逐页不同配置
💧 水印文字/图片水印,角度、透明度、上下层叠放、逐页控制
🔤 中文与自定义字体TTF 嵌入、字体子集、语言区间回退(langFontConfig)
🖼️ 视觉效果图片、SVG、Canvas、背景、圆角、阴影、渐变、透明度
🔗 超链接自动转为 PDF 链接注释
📝 表单导出静态外观 + 可交互 AcroForm 字段(hybrid模式)
🔒 加密与压缩用户/所有者密码、权限控制、DEFLATE 压缩
📊 进度回调onProgress返回采集、计页、渲染、完成四个阶段

完整选项表见 README_CN.md,页面尺寸速查表见 page_sizes.md。

工作原理:5 步生成 PDF

dompdf.js的流水线由TypeScript + Web Worker + Rust/WASM三层协作完成:

  1. 主线程采集——遍历目标元素,读取浏览器计算后的布局、样式、文本、图片和表单状态;
  2. 编码快照——TypeScript 把采集结果编码成紧凑的二进制快照;
  3. 转移给 Worker——快照通过可转移对象发送到 Web Worker,主线程不被阻塞;
  4. Rust/WASM 渲染——完成分页、字体子集、绘制和 PDF 对象写入;
  5. 回传结果——主线程拿到 PDF 字节,返回Blob/Uint8Array或触发下载。

这套结构的关键优势:不先把整份文档画成一张 Canvas,把最重的 PDF 生成工作移出主线程,所以长文档导出不卡顿。

  • 前端采集与快照:src/snapshot.ts、src/worker.ts
  • Rust 渲染层:wasm/src/paginate.rs、wasm/src/font.rs、wasm/src/encrypt.rs、wasm/src/deflate.rs

快速上手:两种安装方式

方式一:npm 安装(推荐)

npm install dompdf.js

运行环境需要支持 Web Workers、WebAssembly 的现代浏览器;构建开发需要 Node.js 18+。

方式二:CDN 一行引入

<script src="https://cdn.jsdelivr.net/npm/dompdf.js@latest/dist/dompdf.min.js"></script>

引入后 API 挂载在全局dompdf上,适合快速验证。

一行代码生成 PDF:最小示例

获取 PDF 的Blob(用于预览、上传或自定义下载):

import dompdf from 'dompdf.js'; const element = document.querySelector<HTMLElement>('#capture'); const blob = await dompdf(element, { format: 'a4', pagination: true, backgroundColor: '#ffffff', }); const url = URL.createObjectURL(blob); window.open(url, '_blank');

更省事的一键下载:

import { downloadPDF } from 'dompdf.js'; await downloadPDF(element, { format: 'a4', pagination: true, compress: true, }, 'report.pdf');

常用 API 一览:

API返回值适用场景
dompdf(root, options?)Blob默认入口,预览/自定义流程
exportPDF(root, options?)Blob同上,语义更明确
renderToBytes(root, options?)Uint8Array上传接口、File System API
downloadPDF(root, options?, filename?)触发下载一键导出按钮
inspect(root, options?)快照摘要诊断节点/图片/字体/页数

完整 TypeScript 类型定义见 src/snapshot.ts。

实战技巧:长尾功能速查

📑 分页与强制换页

pagination: true按页面可用高度自动分页;想手动控制换页位置,给元素加属性即可:

<section pageBreak>从新的一页开始</section> <article divisionDisable>尽量保持在本页完整显示</article>

横向 A4 直接传自定义尺寸:format: [842.25, 595.5]。

📑 页眉页脚与页码

pageConfig: { excludePages: [1], // 第一页不显示 footer: { content: 'Page ${currentPage} / ${totalPages}', height: 48, contentPosition: 'center', }, }

还支持pageConfig(pageNum, totalPages)函数形式,每页返回不同配置(比如奇偶页水印不同)。

💧 文字水印

watermark: { text: 'INTERNAL ${currentPage}', color: 'rgba(185, 28, 28, 0.14)', angle: -35, spacing: [180, 130], layer: 'under', }

🔤 中文字体:避免空白和方框

浏览器字体不会自动嵌入 PDF,中文文档必须显式注册 TTF:

const fontBuffer = await fetch('/fonts/SourceHanSansSC-Regular.ttf') .then((r) => r.arrayBuffer()); await dompdf(element, { fontConfig: { fontFamily: 'SourceHanSansSC-Regular', // 与 CSS font-family 一致 fontBytes: new Uint8Array(fontBuffer), fontWeight: 400, }, });

多语言混排可用langFontConfig按 Unicode 区间选择字体并设置默认回退。仓库内置示例字体加载脚本,如 examples-main/SourceHanSansCNNormal-normal.js。

🔒 加密与文档属性

encryption: { userPassword: 'reader-password', ownerPassword: 'owner-password', userPermissions: ['print', 'copy'], }, metadata: { title: 'Quarterly Report', author: 'Alice', keywords: ['report', 'finance'], }

加密由 Rust 层实现,源码见 wasm/src/encrypt.rs。

📈 导出进度反馈

onProgress(progress) { if (progress.stage === 'rendering') { console.log(`渲染中:${progress.currentPage}/${progress.totalPages}`); } }

四个阶段:collecting→countingPages(按需)→rendering→done,非常适合做导出进度条。

常见问题(FAQ)

❓ 中文显示为空白或方框?通过fontConfig.fontBytes注册含相应字符的 TTF 字体,并保证元素 CSSfont-family与fontFamily一致。

❓ 分页位置和浏览器预览不一致?把导出容器宽度调到接近目标纸张内容宽度(A4 ≈ 794px @ 96DPI,需扣除页边距),导出前等待字体和图片加载完成。

❓ 跨域图片没出现在 PDF 里?设置useCORS: true,并确认图片服务器返回Access-Control-Allow-Origin——前端选项无法绕过服务器限制。

❓ 如何减小 PDF 体积?开启compress: true、避免使用远超显示尺寸的大图、适当降低jpegQuality、只注册实际用到的字体和字重。

❓ 能跑在 Node.js / SSR 里吗?不能直接采集页面(依赖 DOM),Next.js、Nuxt 等 SSR 项目请在客户端调用导出 API。

从 html2canvas + jsPDF 迁移过来?

项目已从旧的html2canvas + jsPDF流水线迁移到DOM 快照 + Worker + WASM。旧参数大多被接受(部分会输出 warning)以平滑过渡,完整对照见迁移说明:

  • 中文:docs/migration-compat.zh-CN.md
  • 英文:docs/migration-compat.md

建议升级路径:先升级版本保留旧参数 → 观察 warning 确认哪些只是兼容签名 → 把依赖 jsPDF 实例的定制逻辑迁到导出前后处理 → 状态反馈统一切到onProgress。

⚠️ 已知边界:动画、视频、iframe 无法完整动态导出;复杂滤镜/遮罩可能被降级或栅格化;它不是完整浏览器渲染引擎。

本地开发与项目结构

rustup target add wasm32-unknown-unknown npm install npm run build # 构建发布包 npm test # 构建 WASM 并运行 PDF 冒烟验证 npm run serve # 8080 端口启动示例服务

验证脚本 scripts/verify.mjs 会检查基础分页、PDF 结构、图片、中文字体子集等核心链路。

dompdf.js/ ├── src/ # TypeScript API、DOM 采集、Worker 和 WASM 桥接 ├── wasm/ # Rust 分页、字体、压缩、加密和 PDF 写入器 ├── examples-main/ # 浏览器演示页面和示例字体 ├── docs/ # 迁移说明与 PDF 差异系统文档 └── scripts/ # 构建、验证和 PDF 差异工具

写在最后

如果你需要一个不上传数据、文本可选中、长文档不卡死的浏览器端 HTML 转 PDF 方案,dompdf.js目前的组合拳——TypeScript API + Web Worker + Rust/WASM 矢量渲染,再加上水印、页眉页脚、中文字体、加密压缩这些导出刚需——相当完整。

💬 欢迎加入维护交流群交流实战问题:

项目基于 MIT License 开源,变更记录见 CHANGELOG.md,参与贡献前请阅读 CONTRIBUTING.md。

【免费下载链接】dompdf.js

HTML to PDF in the browser — one line of code for selectable, searchable vector PDFs (10,000+ pages). Pure frontend: zero backend, zero runtime deps. TypeScript over a Rust + WebAssembly engine; an html2canvas/jsPDF alternative.

项目地址:https://gitcode.com/gh_mirrors/do/dompdf.js
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询