DomPDF.js

2天前发布 3 00

该脚本允许您直接在用户浏览器上将网页或部分网页生成为可编辑、非图片式、可打印的矢量 pdf。支持分页,最多可以生成上数千页的 pdf 文件。由于生成是基于 DOM 的,因此可能与实际表现不会 100% 一致。如果是复杂的 pdf 生成需求,不建议使用。

所在地:
中国
收录时间:
2026-03-10
其他站点:
DomPDF.jsDomPDF.js

“还在用 html2canvas 把网页切成一张张模糊的图片塞进 PDF?生成的文件巨大、文字无法复制、打印效果差,而且一旦超过几千像素就报错?”

dompdf.js 是一个革命性的前端库,它摒弃了传统的“HTML -> Canvas 图片 -> PDF”的低效路径,转而采用 DOM -> 矢量 PDF 的直接渲染模式。

DomPDF.js

基于 html2canvas 和 jspdf 深度改造,dompdf.js 能够直接读取 DOM 结构和 CSS 样式,调用 jsPDF 原生方法绘制矢量图形。这意味着生成的 PDF 文字可复制、可搜索、可编辑,且文件体积极小,更能轻松支撑数千页的长文档生成,彻底打破 Canvas 的高度限制。

🚀 核心优势:为什么选择 dompdf.js?

特性传统方案 (html2canvas + jspdf)dompdf.js
渲染原理HTML -> Canvas 图片 -> PDFHTML/DOM -> 矢量 PDF 指令
文件性质图片式 PDF (不可选中文本)矢量 PDF (文字可选、可搜、可编辑)
文件大小极大 (每张图都占空间)极小 (仅存储绘图指令和字体)
打印质量低 (放大后模糊锯齿)高 (无限缩放不失真)
长度限制受 Canvas 高度限制 (通常 ~30000px)无限制 (支持数千页长文档)
服务器依赖可选 (可纯前端)纯前端 (零服务器渲染成本)

✨ 功能全景:强大的渲染能力

dompdf.js 已经实现了绝大多数常用 Web 样式的矢量还原:

  • 📄 智能分页:支持自动分页,可生成数千页的超长 PDF。支持自定义页眉页脚(含动态页码 ${currentPage}/${totalPages})。
  • 🔤 文本渲染:完美支持 font-familyfont-sizecolorfont-style 等。支持文字描边,暂不支持文字阴影。
  • 🖼️ 多媒体支持
    • 图片:支持网络图、Base64、SVG。
    • Canvas/SVG:直接渲染 <canvas> 和 <svg> 元素为矢量或高清嵌入。
  • 🎨 样式还原
    • 边框:支持 border-width/color/style/radius (目前仅实线)。
    • 背景:支持纯色、背景图、线性/径向渐变
    • 阴影:利用 foreignObjectRendering 技术支持边框阴影。
  • 🔒 安全加密:支持设置用户密码、所有者密码及打印/复制/修改权限。

(注:暂不支持 <iframe> 渲染;部分复杂 CSS 属性可能尚未覆盖)

🛠️ 快速开始:三步生成矢量 PDF

1. 安装

npm install dompdf.js --save
# 或使用 CDN
# <script src="https://cdn.jsdelivr.net/npm/dompdf.js@latest/dist/dompdf.js"></script>

2. 基础用法

import dompdf from 'dompdf.js';

// 选中你要转换的 DOM 节点
const element = document.querySelector('#capture');

dompdf(element)
    .then((blob) => {
        // 创建下载链接
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'report.pdf';
        document.body.appendChild(a);
        a.click();
    })
    .catch((err) => {
        console.error('PDF 生成失败:', err);
    });

3. 进阶:开启分页与自定义页眉页脚

生成 A4 格式文档,并添加动态页码:

dompdf(document.querySelector('#report'), {
    pagination: true,       // 开启分页
    format: 'a4',           // 纸张格式
    // ⚠️ 重要:确保 #report 的宽度设置为 794px (A4 在 96dpi 下的像素宽度)
    pageConfig: {
        header: {
            content: '公司月度报告',
            height: 40,
            contentColor: '#333',
            contentFontSize: 14,
            contentPosition: 'center'
        },
        footer: {
            content: '第 ${currentPage} 页 / 共 ${totalPages} 页', // 支持变量
            height: 40,
            contentColor: '#666',
            contentFontSize: 12,
            contentPosition: 'center'
        }
    }
}).then(/* ... */);

💡 防断裂技巧:如果不希望某个区块(如表格行、卡片)被分页切断,给该元素添加 divisionDisable 属性:

<div divisionDisable>此内容将整体移至下一页,不会被切断</div>

🌍 解决乱码:自定义字体导入

由于 jsPDF 默认只内置西文字体,生成中文 PDF 会出现乱码。dompdf.js 提供了便捷的 fontConfig 配置项,支持加载 Base64 格式的 .ttf 字体。

推荐方案:使用体积较小的思源黑体 (Source Han Sans) 或类似中文字体。

import myFontBase64 from './fonts/SourceHanSansCN-Regular.base64.js'; // 假设你已转换好

dompdf(element, {
    fontConfig: [
        {
            fontFamily: 'Source Han Sans CN', // 必须与 CSS 中的 font-family 一致
            fontBase64: myFontBase64,         // .ttf 文件的 Base64 字符串
            fontStyle: 'normal',
            fontWeight: 400
        }
    ]
});

⚙️ 高级配置参数一览

参数类型说明
paginationboolean是否开启自动分页 (默认 false)
formatstring纸张规格 (a4lettera3 等)
useCORSboolean允许加载跨域图片 (需服务端配合 CORS)
backgroundColorstring/null背景色,设为 null 可生成透明背景 PDF
encryptionobjectPDF 加密配置 (密码、权限控制)
compressboolean是否压缩输出文件 (默认 false)
putOnlyUsedFontsboolean仅嵌入实际用到的字体,减小体积
onJspdfReadyFunctionjsPDF 实例初始化后的回调,可进行底层定制

💡 适用场景与局限性

✅ 最佳场景

  • 后台管理系统报表导出(订单、日志、数据列表)。
  • 电子合同、发票、证书生成。
  • 长篇文章、博客、文档的离线保存。
  • 对文件体积和文字可编辑性有要求的场景。

⚠️ 注意事项

  • 一致性:由于是直接映射 DOM 到 PDF 指令,极少数复杂 CSS 布局可能与浏览器渲染效果有细微差异(非 100% 像素级一致)。
  • CSS 支持:部分最新 CSS 特性(如 Grid 的某些复杂用法、filter 滤镜等)可能尚未完全支持,使用前建议查阅官方支持的 CSS 列表。
  • Iframe:暂不支持渲染 <iframe> 内容。

数据统计

相关导航

暂无评论

none
暂无评论...