工作中经常会遇到一些pdf文件处理的问题,一千种pdf有一千种处理方式,每次都是绞尽脑汁和这些pdf战斗到底。
本人又是一个gopher,所以这篇文章会以一个goper的视角,列举一下我所经历过的每一种pdf处理场景,比如:
本文大多是场景问题的罗列,可以根据标题摘取自己有兴趣的部分查看
很多pdf的问题我也不是特别专业,如果问题或者疑问欢迎与我交流
一、HTML页面渲染PDF
根据html页面渲染pdf,我使用过以下两种方案:
- wkhtmltopdf
- chromedp
1. 使用wkhtmltopdf渲染pdf
wkhtmltopdf是一个命令行工具,用于将HTML页面渲染为PDF,基于Qt WebKit渲染引擎实现
使用方式比较简单:
wkhtmltopdf的参数很丰富,比如:
支持发送 http post请求,适合将自定义开发的网页渲染成pdf文件:
支持javascript脚本,在渲染pdf前对html进行修改:
更多详细参数可看官网文档
如果你使用Go语言,还有一个第三方包,是对wkhtmltopdf的使用封装: go-wkhtmltopdf
2. 使用chromedp渲染pdf
chromedp是一种在Go语言中以更快,更简单的方式来驱动支持Chrome DevTools协议的浏览器的软件包,而无需外部依赖((例如Selenium或PhantomJS).
使用方式:
二、PDF加水印
我了解到的支持pdf加水印的工具有:
- unidoc/unipdf
- pdfcpu
1.unidoc/unipdf
unidoc平台开发的unipdf是一款用Go语言编写的PDF库,提供API和CLI使用模式,支持以下功能:
CLI模式添加水印
使用API添加水印,可以直接参考unipdf github example
注意:unidoc的产品需要付费购买license使用
2.pdfcpu
pdfcpu 是一个用Go语言编写的PDF处理库,提供API和CLI模式使用
支持以下功能:
使用CLI工具以图片形式添加水印:
调用api添加水印
三、PDF合并
- cpdf
- unipdfc
- pdfcpu
1.使用cpdf合并pdf
cpdf是一个开源免费的PDF命令行工具库,有丰富的功能,比如:
- Merge PDF files together, or split them apart
- Encrypt and decrypt
- Scale, crop and rotate pages
- Read and set document info and metadata
- Copy, add or remove bookmarks
- Stamp logos, text, dates, page numbers
- Add or remove attachments
- Losslessly compress PDF files
合并pdf:
2.使用unipdf合并pdf
使用API合并pdf,参考unpdf github example
3.使用pdfcpu合并pdf
注意: pdfcpu只支持版本低于PDF V1.7的pdf文件
四、拆分PDF
- cpdf
- unipdf
- pdfcpu
1.使用cpdf拆分pdf
2. 使用unipdf拆分pdf
使用api拆分pdf,参考unipdf github examples
3.使用pdfcpu拆分pdf
五、PDF转图片
- mupdf
- xpdf
1. 使用mupdf操作pdf转图片
MuPDF is a lightweight PDF, XPS, and E-book viewer.
MuPDF consists of a software library, command line tools, and viewers for various platforms.
下载mupdf后得到一些工具,比如:
其中
注意: mupdf不支持mac OS
2. 使用xpdf操作pdf转图片
xpdf是一个免费的PDF工具包,包括文字解析,图片转换,html转换等
下载该软件包后,可以得到一系列的工具:
从名称上看,大致能看出来每一个工具的用处
六、PDF解密
经常会遇到一种场景,读取pdf文件的时候发现会报错:文件被加密
但是在没有密码的情况下怎么解决呢?
- 使用qpdf解密
使用qpdf进行强制解密,有些情况是可以解密成功的,但是有些情况也不一定能解密成功
qpdf是一个支持命令行的pdf工具
- 使用pdfcpu解密
当有密码的情况下,可以使用密码解密:
- 使用unipdf解密pdf
七、PDF识别
经常会遇到一些场景,比如识别一个文件是不是pdf文件,识别pdf中的文字,识别pdf中的图片等
1.识别pdf中的文字
这里使用xpdf将pdf中的文字解析出来,然后再使用一些字符串操作或者正则表达式进行业务分析
- 使用
xpdf/pdftotext 解析pdf中的文本
- 使用
unipdf 解析pdf中的文本
使用API解析pdf文本,参考unipdf github examples
- 使用坐标信息解析pdf数据
上面都是先解析出pdf的文本,再根据业务进行处理
还有一种方式是按照坐标位置解析pdf,这种方式更加灵活以及通用,利用的是pdflib/tet
坐标可以使用tet对pdf进行分析得到一个tetml文件,里面包含了坐标信息:
当然也可以用一些其他的方式获取pdf中数据的坐标信息,比如nodejs等
注意:
pdflib/tet 是收费软件,但是根据官方文档说明,tet提供基础功能,处理不超过10页或者小于1M的pdf文件是不需要购买license的
pdflib/tet 提供了命令行工具以及多种语言的sdk支持,比如C/C++/Java/.NET/Perl/PHP/Python/Ruby/Swift 但目前还不支持Go语言,所以对于gopher而言目前只有两种选择:CLI OR CGO
八、修复受损pdf文件
有一些pdf文件在电脑上打开时,显示正常,但是用代码检测却是不正常的,比如在Go中尝试用一个第三方库去解析一个(受损的)pdf:
运行后会得到这样一个结果:
电脑打开正常,程序却读取错误!
这时候如果尝试在电脑上打开pdf,然后另存为一个新的pdf文件,再用代码去检测,会发现竟然修复了!
太好了,问题解决!
等等,如果我有1000张pdf文件,难道要逐个打开并另存为?这怎么能忍? 所以如果有一种批量修复的功能就好了
在网上找了很久,大概得到三种解决方案:
- 利用 Acrobat SDK,调用SDK中的另存为功能,可以实现电脑打开另存为的效果
- 利用ghostscript进行pdf修复
- 利用mupdf进行pdf修复
这里我只验证了第三种方式是可行的,这里我使用
下载软件包后,得到其中一个可执行文件:
从输出结果来看,mupdf尝试了修复处理
得到新的pdf文件之后,再用前面的Go代码尝试打开,就正常了
剩下的就是写一个bash脚本,批量修复,目标达成!
九、识别一个PDF文件的字体信息
有时候要使多个pdf文本字体保持一致,免不得要去分析pdf中都使用了哪些字体,这时候可以使用
xpdf/pdffonts 进行字体分析
其他Libiray介绍
- PDF-Writer
这是一个C++的开源库,支持创建pdf,合并pdf,图片水印文字操作等
对于gopher来讲,要使用这个库,需要封装一层CGO代码才可以
- rsc/pdf
这是一个Go语言实现的pdf库,可以用于读取pdf信息,比如读取pdf内容/页数/字体等... 具体可以参考文档
介绍了这么多第三方库,简直就是五花八门,各显神通。有些功能在大多数库中都是有重复的,具体使用中会遇到什么问题,还是要看实际情况如何。
希望这些总结能够对读者有所帮助
参考:
- wkhtmltopdf
- xpdf
- cpdf
- qpdf
- unidoc
- pdflib/tet
- pdfwriter
- mupdf
- pdfcpu