工作中经常会遇到一些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后得到一些工具,比如:

其中pdfdraw可用来转换图片

注意: 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-0.9-linux-amd64这个版本进行验证

下载软件包后,得到其中一个可执行文件:pdfclean

从输出结果来看,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