Stirling-PDF:合并、设密码、加水印,PDF 在自己机器上处理
你能得到什么:一套装在自己电脑或服务器上的 PDF 工具箱:合并、拆分、压缩、设置打开密码、加水印、OCR 等 50 多种功能,网页点一点就能用,还带 REST 接口能批量处理。合同、证件、报价单不用再上传到在线 PDF 网站,也不用为偶尔用一次的功能开订阅。适合:经常处理 PDF、在意文件隐私的个人和小团队。不适合:只偶尔合并一次 PDF 的人,系统自带的预览工具可能就够了。
项目速览
| 项目 | 内容 |
|---|---|
| 仓库 | Stirling-Tools/Stirling-PDF |
| Star | 94,653(截至 2026-10-21) |
| 许可证 | 主体 MIT;app/proprietary/ 等目录另有许可(官方称为 open-core) |
| 最新版本 | v3.2.0(2026-10-15 发布) |
| 它做什么 | 自托管 PDF 平台:桌面客户端、浏览器界面、带私有 API 的服务器三种用法 |
安装指南
docker run -p 8080:8080 docker.stirlingpdf.com/stirlingtools/stirling-pdf
# 浏览器打开 http://localhost:8080# 到 Releases 页面下载 Stirling-PDF-macos-universal.dmg,拖进「应用程序」
open https://github.com/Stirling-Tools/Stirling-PDF/releases/latest# 到 Releases 页面下载 Stirling-PDF-windows-x86_64.msi 安装
start https://github.com/Stirling-Tools/Stirling-PDF/releases/latest# 需要 Java 25(v3.2.0 的 jar 用 Java 25 编译)
curl -fLO https://github.com/Stirling-Tools/Stirling-PDF/releases/download/v3.2.0/Stirling-PDF-server.jar
java -jar Stirling-PDF-server.jar --server.port=8099Linux 桌面也可以直接用 Releases 里的 AppImage、deb 或 rpm 包。
使用教程:用接口批量处理 PDF
网页界面上传、点按钮就能用,这里演示接口用法,方便以后接进脚本或 n8n 工作流。完整接口列表在 http://localhost:8099/v1/api-docs。
# 合并两个 PDF
curl -o merged.pdf -F fileInput=@a.pdf -F fileInput=@b.pdf \
http://localhost:8099/api/v1/general/merge-pdfs
# 设置打开密码
curl -o locked.pdf -F fileInput=@a.pdf -F password=你的密码 -F ownerPassword=你的密码 \
http://localhost:8099/api/v1/security/add-password
# 加文字水印(alphabet 一定要传,见下方避坑)
curl -o watermarked.pdf -F fileInput=@a.pdf -F watermarkType=text -F watermarkText=WANGXXXL \
-F alphabet=roman -F fontSize=30 -F opacity=0.3 -F rotation=45 \
-F widthSpacer=50 -F heightSpacer=50 -F customColor='#d3d3d3' \
http://localhost:8099/api/v1/security/add-watermark避坑与解决方案
jar 启动报 UnsupportedClassVersionError
我们先用 Java 21 启动 v3.2.0 的 jar,直接报 class file version 69.0,意思是它要 Java 25。解决:装 Java 25(比如 Eclipse Temurin 25),或者用 Docker 镜像,镜像里已经配好了运行环境。
用 jar 跑时部分功能被关掉
jar 版启动时会检查外部程序。我们的日志里提示缺 gs(Ghostscript)、qpdf、tesseract、ocrmypdf、magick、unoconvert 等,并写明会关掉对应的 OCR、修复、Office 文件转 PDF 等功能,压缩也会少掉依赖 Ghostscript、qpdf 的那部分处理。解决:要全功能就用 Docker 镜像;坚持用 jar,就自己装齐这些依赖再重启。
合并报 JPDFium merge failed
我们直接合并两篇带书签目录的论文 PDF 时,接口返回 500,错误是 JPDFium merge failed;把同一份 PDF 拆成两段再合并就成功了。v3 系列合并失败的问题在 issue #8321 里还开着,各平台都有人反馈。解决:关注新版本修复;急用时先换别的文件试,或回到 issue 里提到的旧版本。
加水印报 String.hashCode() is null
接口文档里 alphabet 看起来是可选项,但我们不传它时,水印接口返回 Cannot invoke "String.hashCode()" because "<local4>" is null;加上 -F alphabet=roman(中文水印用 chinese)就成功了。
放到公网前加登录
我们实测的 server jar 打开就能用,没有登录这一步。Releases 里另外提供了 Stirling-PDF-with-login.jar,要让同事通过网络访问,用带登录的版本或按官方文档开启安全设置,别把一个谁都能用的 PDF 接口裸露在公网上。
WANGXXXL 实测于 2026-10-21
- 环境:Linux 云电脑,8 核 CPU;Eclipse Temurin Java 25.0.4.1,Stirling-PDF v3.2.0 server jar,没装 Ghostscript、qpdf、Tesseract 等外部依赖。
- 启动:Java 21 启动失败(版本不符);换 Java 25 后约 6.5 秒启动完成,首页返回 200。
- 成功:拆分页面、合并拆分出的两段(得到 15 页 PDF)、设置打开密码(之后不输密码打不开)、加文字水印;在缺少 Ghostscript 和 qpdf 的情况下,压缩接口(
optimizeLevel=5)把一份 14 页、2,136,361 字节的 PDF 压到 1,846,288 字节,约小了 14%。 - 失败:两篇论文原文件直接合并失败(JPDFium);不传
alphabet时加水印失败。这些都写进了上面的避坑。