更新记录

1.0.1(2026-08-15) 下载此版本

  • 修复 PdfHelper 对本地临时文件路径的识别与读取,支持 H5、App、主流小程序直接处理本地 PDF 源
  • 修复合并后添加中文水印时 fontkit 未正确注册的问题
  • 修复表单填充在纯英文场景下仍强制依赖中文字体的问题
  • 修复 App 端示例页面保存 PDF 时写入 base64 文本导致文件不可预览的问题
  • 修复 Base64 兜底编解码实现,避免部分客户端生成损坏 PDF
  • 完善插件发布所需的 package.json 元数据与平台声明

平台兼容性

uni-app(4.51)

Vue2 Vue2插件版本 Vue3 Vue3插件版本 Chrome Chrome插件版本 Safari app-vue app-vue插件版本 app-nvue Android Android插件版本 iOS 鸿蒙
1.0.1 1.0.1 1.0.1 - 1.0.1 - 12.0 1.0.1 - -
微信小程序 微信小程序插件版本 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
1.0.1 - - - - - - - - - - -

其他

多语言 暗黑模式 宽屏模式
× ×

pdf-helper

一个功能全面的 uni-app PDF 操作插件,基于 pdf-lib 封装,提供水印、表单字段添加与填充、图片添加、PDF 合并等功能。当前版本适配 H5App-AndroidApp-iOS微信小程序支付宝小程序百度小程序头条小程序QQ 小程序


✨ 功能特性

  • ✅ 添加文字水印(支持中文、自定义字体、旋转、透明度、间距)
  • ✅ 合并多个 PDF 并统一添加水印
  • ✅ 动态添加表单字段:文本框、复选框、下拉框、单选按钮组
  • ✅ 批量填充已有表单字段(支持中文显示)
  • ✅ 向指定页添加 PNG / JPEG 图片
  • ✅ 灵活返回 Uint8Array 或 Base64 字符串
  • ✅ 纯 JavaScript 实现,无原生依赖,易于集成
  • ✅ 提供统一的平台适配层,兼容 H5、小程序、App 网络请求及 Base64 处理

平台支持

平台 支持情况 说明
H5 支持 支持本地选择、远程 URL、base64、Blob URL 预览与下载
App-Android 支持 支持本地临时文件、远程 URL、uni.openDocument 预览
App-iOS 支持 支持本地临时文件、远程 URL、uni.openDocument 预览
微信小程序 支持 支持 getFileSystemManager 读写与 uni.openDocument
支付宝小程序 支持 支持文件系统读写与文档预览
百度小程序 支持 支持文件系统读写与文档预览
头条小程序 支持 支持文件系统读写与文档预览
QQ 小程序 支持 支持文件系统读写与文档预览
快应用 不支持 当前未提供专门适配代码
uni-app x 不支持 当前版本为 uni-app JS SDK,并非 UTS 插件

注意:若业务场景需要加载远程 PDF 或远程字体文件,请按目标平台要求配置合法域名、下载白名单或网络权限。


📦 安装

1. 导入插件

将整个 pdf-helper 文件夹放入项目的 uni_modules 目录。

2. 安装 npm 依赖

插件使用了 pdf-lib@pdf-lib/fontkit,请在你的 uni-app 项目根目录执行:

npm install pdf-lib @pdf-lib/fontkit

如果你使用的是 HBuilderX 创建的项目,且没有启用 npm 管理,请先右键项目 -> 使用命令行窗口打开,然后执行上述命令。


🚀 快速开始

import PdfHelper from '@/uni_modules/pdf-helper'

// 初始化(可选传入中文字体,用于水印或表单填写的汉字显示)
const helper = new PdfHelper({
  // 推荐传入远程字体地址,避免打包字体文件
  chineseFontUrl: 'https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf',
  // 也可直接传入字体二进制数据
  // chineseFont: fontUint8Array,
  // 默认水印配置(可被方法级参数覆盖)
  defaultWatermark: {
    text: '内部资料',
    fontSize: 40,
    color: [0.5, 0.5, 0.5],
    opacity: 0.3,
    rotate: -45,
    spacing: 180
  }
})

// 示例1:给 PDF 添加水印,返回 base64
const base64 = await helper.addWatermark(pdfSource, {
  text: '机密文件',
  returnBase64: true
})

// 示例2:填充表单字段
const filledPdf = await helper.fillFormFields(pdfSource, {
  name: '张三',
  age: '30',
  agreed: true
}, { flatten: true })

其中 pdfSource 可以是以下任一形式:

  • base64 字符串(可含 data:application/pdf;base64, 前缀)
  • http/https 远程 URL
  • H5 Blob URL
  • H5、本地 App、小程序生成的临时文件路径

📚 API 文档

构造函数

new PdfHelper(options?)

创建 PdfHelper 实例。

参数:

属性 类型 必填 描述
defaultWatermark Object 默认水印配置,见下方水印配置表
chineseFont Uint8Array 中文字体二进制数据,与 chineseFontUrl 二选一
chineseFontUrl string 中文字体远程 URL,与 chineseFont 二选一

示例:

const helper = new PdfHelper({
  defaultWatermark: {
    text: '机密',
    fontSize: 48,
    color: [0.8, 0.8, 0.8],
    opacity: 0.2,
    rotate: -45,
    spacing: 200
  },
  chineseFontUrl: 'https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf'
})

方法

addWatermark(pdfSource, options?)

给 PDF 的每一页添加文字水印。

参数:

参数名 类型 必填 描述
pdfSource string PDF 源(base64 字符串或 URL)
options Object 水印配置,会与默认水印合并

options 可选属性(水印配置):

属性 类型 默认值 描述
text string '机密' 水印文字
fontSize number 48 字体大小
color [number, number, number] [0.8, 0.8, 0.8] RGB 颜色,取值范围 0~1
opacity number 0.2 透明度,范围 0~1
rotate number -45 旋转角度(度)
spacing number 200 水印间距(横纵相同)
customFont Uint8Array 自定义字体数据(优先级最高)
returnBase64 boolean false true 时返回 base64 字符串,否则返回 Uint8Array

返回值: Promise<Uint8Array | string>

示例:

const result = await helper.addWatermark(pdfSource, {
  text: '机密',
  fontSize: 60,
  color: [1, 0, 0],
  opacity: 0.5,
  returnBase64: true
})
// result 为 data:application/pdf;base64,....

mergeAndAddWatermark(pdfSources, options?)

将多个 PDF 合并,并在合并后的每一页添加水印。

参数:

参数名 类型 必填 描述
pdfSources string[] PDF 源数组(每个元素同 pdfSource
options Object 水印配置,同 addWatermarkoptions

返回值: Promise<Uint8Array | string>

示例:

const merged = await helper.mergeAndAddWatermark([pdf1, pdf2, pdf3], {
  text: '合并文件',
  fontSize: 36,
  returnBase64: true
})

addFormField(pdfSource, field, options?)

向 PDF 动态添加一个表单字段(文本框、复选框、下拉框或单选组)。

参数:

参数名 类型 必填 描述
pdfSource string PDF 源
field Object 表单字段配置,见下方字段配置表
options Object { returnBase64?: boolean }

field 对象属性:

属性 类型 必填 描述
name string 字段名(唯一)
type 'text' \| 'checkbox' \| 'dropdown' \| 'radio' 字段类型
pageIndex number 页码,从 0 开始,默认 0
x number 字段左下角 x 坐标
y number 字段左下角 y 坐标
width number 字段宽度,默认 180
height number 字段高度,默认 20
rotate number 旋转角度,默认 0
fontSize number 字体大小(仅 text 类型),默认 12
defaultValue string 默认值(text / dropdown / radio)
checked boolean 复选框默认是否选中(checkbox)
options string[] 下拉或单选项列表(dropdown / radio)
optionSpacing number 单选组选项之间的垂直间距,默认 24

返回值: Promise<Uint8Array | string>

示例:

// 添加文本框
const result = await helper.addFormField(pdfSource, {
  name: 'signature',
  type: 'text',
  pageIndex: 0,
  x: 100,
  y: 200,
  width: 150,
  height: 30,
  fontSize: 14
})

// 添加复选框
await helper.addFormField(pdfSource, {
  name: 'agree',
  type: 'checkbox',
  x: 100,
  y: 150,
  width: 20,
  height: 20,
  checked: true
})

// 添加下拉框
await helper.addFormField(pdfSource, {
  name: 'gender',
  type: 'dropdown',
  x: 100,
  y: 100,
  width: 100,
  height: 20,
  options: ['男', '女', '其他'],
  defaultValue: '男'
})

// 添加单选组
await helper.addFormField(pdfSource, {
  name: 'bloodType',
  type: 'radio',
  x: 100,
  y: 50,
  width: 20,
  height: 20,
  options: ['A', 'B', 'AB', 'O'],
  optionSpacing: 30
})

fillFormFields(pdfSource, fieldValues, options?)

批量填充 PDF 中已有的表单字段,支持文本框、复选框、下拉框、单选组。

参数:

参数名 类型 必填 描述
pdfSource string PDF 源
fieldValues Object 字段名到值的映射,值类型为 stringboolean
options Object 填充选项,见下方

options 可选属性:

属性 类型 默认值 描述
flatten boolean false 是否扁平化表单(填充后表单域不可再编辑)
returnBase64 boolean false true 时返回 base64 字符串
customFont Uint8Array 自定义字体数据,用于正确显示中文字符

返回值: Promise<Uint8Array | string>

注意: 填充中文字符时,必须提供中文字体(通过构造函数或 customFont),否则可能出现乱码。

示例:

const result = await helper.fillFormFields(pdfSource, {
  name: '张三',
  age: '28',
  agreed: true,
  gender: '男'
}, {
  flatten: true,
  returnBase64: true
})

addImage(pdfSource, imageData, x, y, options?)

在指定页的指定坐标添加图片(PNG 或 JPEG)。

参数:

参数名 类型 必填 描述
pdfSource string PDF 源
imageData Uint8Array \| string 图片数据,支持 Uint8Array 或 base64 data:image 字符串
x number 图片左下角 x 坐标
y number 图片左下角 y 坐标
options Object 图片选项

options 可选属性:

属性 类型 默认值 描述
pageIndex number 0 页码,从 0 开始
width number 图片原始宽 绘制宽度
height number 图片原始高 绘制高度
rotate number 0 旋转角度
opacity number 1 透明度 0~1
returnBase64 boolean false true 时返回 base64 字符串

返回值: Promise<Uint8Array | string>

示例:

const result = await helper.addImage(pdfSource, imageBase64, 50, 50, {
  pageIndex: 0,
  width: 100,
  height: 100,
  opacity: 0.8,
  returnBase64: true
})

🔤 中文字体处理

在 PDF 中正确显示中文,需要嵌入中文字体。插件不内置字体文件(体积过大),你需要通过以下任一方式提供:

  1. 构造函数传入 chineseFont(推荐在 App 或小程序中使用,直接读取字体文件)

    const fontBytes = await getFontBytesSomehow() // Uint8Array
    const helper = new PdfHelper({ chineseFont: fontBytes })
  2. 构造函数传入 chineseFontUrl(推荐在 H5 中使用)

    const helper = new PdfHelper({
     chineseFontUrl: 'https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf'
    })
  3. H5 项目放置默认字体:在项目的 public/fonts/NotoSerifCJKsc-Regular.otf 放置字体文件,插件会自动尝试加载(仅 H5 有效)。

推荐字体Noto Sans CJK SCSource Han Sans,可使用其 OTF 或 TTF 格式。


🧩 平台差异说明

平台 支持情况 说明
H5 ✅ 完全支持 使用 fetch 请求网络资源
微信小程序 ✅ 支持 使用 uni.request,需注意包体积限制,推荐使用远程字体
App (uni-app) ✅ 支持 使用 uni.request,环境与小程序类似
支付宝小程序 ⚠️ 理论支持 未完整测试,建议实际验证

小程序端注意事项:

  • 由于 pdf-lib@pdf-lib/fontkit 体积较大,请确保小程序主包或分包不超过 2MB 限制,必要时可分包加载。
  • 处理超大 PDF 可能因内存限制失败,建议处理文件大小不超过 10MB。
  • 中文字体无法从本地 public 目录加载,请使用 chineseFontUrlchineseFont 传入。

❓ 常见问题

Q1:为什么填充中文表单出现乱码? A1:必须提供中文字体。请通过构造函数或 customFont 选项传入字体数据。

Q2:小程序端无法使用 fetch,插件如何处理? A2:插件内部已封装了 uni.request,会自动使用,无需手动处理。

Q3:可以处理带密码的 PDF 吗? A3:pdf-lib 不支持加密 PDF 的解密,请先解密后再使用。

Q4:能否在 Node.js 环境中使用? A4:本插件设计用于 uni-app 环境,但核心逻辑可在 Node.js 中运行(需自行实现网络请求和 Base64),建议直接使用 pdf-lib 原生 API。

Q5:返回的 Uint8Array 如何保存为文件? A5:H5 可使用 Blob 下载,小程序可使用 FileSystemManager.writeFile 保存。


📄 许可证

MIT License

Copyright (c) 2026 [wxq]


🔗 相关链接

隐私、权限声明

1. 本插件需要申请的系统权限列表:

插件本身无原生权限依赖;如业务侧通过网络加载 PDF 或字体,请按目标平台要求自行配置网络白名单与文件访问权限。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件仅处理调用方提供的 PDF、字体和图片数据,不内置采集逻辑。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无广告

许可协议

MIT协议

暂无用户评论。