解决 java 编辑 pdf 的问题

java / pdf / pdfbox

近来有一个项目需要在现有 pdf 文件上增加内容,原来以为不是特别复杂,后来从选择到真正实验出来,也花了不少时间

技术选择

除去付费的方案,基本上我们只有两个选择,但是再考虑许可证书,其实只能选 pdfbox:

itext

itext 同时存在商业许可和免费许可,不过免费许可是 AGPL,这个协议下,你需要向所有用户提供源码

pdfbox

pdfbox 是 apache 基金会提供的 pdf 编辑库,采用 apache license 2.0,这个协议相对于 agpl 就宽松很多, 有关协议的比较,这里就不再赘述

demo

pdfbox 的官方文档并不完整,不过 dongdongdeng 的这个 demo 已经演示了很多常用的功能,而且是可以直接跑通的, 省去了很多我们自己摸索的时间。

当我把自己的 pdf 替换掉 demo 中的 pdf 后,出现了一个新的问题,新增的文字没有显示出来,似乎是显示在了现有排版的下方:

https://i.loli.net/2020/12/09/RKsv8t7Y9N4OCuk.png

但是跑原有的 pdf 文件是没有这个问题的,所以应该是 pdf 原文件的问题,导致结果异常,但是 pdf 原文件是我们必须要使用的,所以我们要想一下如何修改 demo。

我们注意到 PDPageContentStream 有一个 AppendMode,估计与这个有关,AppendMode 有三种,原 demo 配置为 prepend,我们改为 overwrite 试一下:

https://i.loli.net/2020/12/09/scFH1ey69Rj3GoW.png

文字显示出来了,但是原 pdf 的内容被完全清除了,这也不是我们想要的,我们再试试 append:

https://i.loli.net/2020/12/09/BTP6bw8qVG4gpfh.png

这就是我们想要的结果了,所以 overwrite 是覆盖所有原始内容,append 是先画原 pdf 再画新内容,prepend 是先画新内容,再画 pdf, 所以 demo 中之所以可以选择 prepend,推测他原本的 pdf 空白部分是透明色,而我的原始 pdf 是纯白色。

总结

如果我们需要在 pdf 上添加文字,那么 dongdongdeng 的 pdfbox demo 基本就够用了,另外要注意一下 append mode,还有就是注意字体的选择, pdfbox 似乎不支持 otf 格式的字体,ttf 没有问题,另外注意字体的使用许可。