更新记录
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 合并等功能。当前版本适配 H5、App-Android、App-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 |
否 | 水印配置,同 addWatermark 的 options |
返回值: 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 |
是 | 字段名到值的映射,值类型为 string 或 boolean |
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 中正确显示中文,需要嵌入中文字体。插件不内置字体文件(体积过大),你需要通过以下任一方式提供:
-
构造函数传入
chineseFont(推荐在 App 或小程序中使用,直接读取字体文件)const fontBytes = await getFontBytesSomehow() // Uint8Array const helper = new PdfHelper({ chineseFont: fontBytes }) -
构造函数传入
chineseFontUrl(推荐在 H5 中使用)const helper = new PdfHelper({ chineseFontUrl: 'https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf' }) -
H5 项目放置默认字体:在项目的
public/fonts/NotoSerifCJKsc-Regular.otf放置字体文件,插件会自动尝试加载(仅 H5 有效)。
推荐字体:Noto Sans CJK SC 或 Source Han Sans,可使用其 OTF 或 TTF 格式。
🧩 平台差异说明
| 平台 | 支持情况 | 说明 |
|---|---|---|
| H5 | ✅ 完全支持 | 使用 fetch 请求网络资源 |
| 微信小程序 | ✅ 支持 | 使用 uni.request,需注意包体积限制,推荐使用远程字体 |
| App (uni-app) | ✅ 支持 | 使用 uni.request,环境与小程序类似 |
| 支付宝小程序 | ⚠️ 理论支持 | 未完整测试,建议实际验证 |
小程序端注意事项:
- 由于
pdf-lib和@pdf-lib/fontkit体积较大,请确保小程序主包或分包不超过 2MB 限制,必要时可分包加载。 - 处理超大 PDF 可能因内存限制失败,建议处理文件大小不超过 10MB。
- 中文字体无法从本地
public目录加载,请使用chineseFontUrl或chineseFont传入。
❓ 常见问题
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]

收藏人数:
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 1
赞赏 0
下载 12509477
赞赏 1943
赞赏
京公网安备:11010802035340号