公司船务部一个重要任务就是需要准备每单货物的发票,从系统导出发票时是默认存为一个PDF文档,在打印的时候,有多少个文件,就需要点多少次“打印”。如果能够将当天的发票PDF档合并在一个PDF里面,只需要点一次“打印”即可完成。 在网上我们可以搜到很多PDF合并软件,但在真实工作环境下并不是非常实用,比如有些PDF有封面页,我们在合并的时候只需要第一个文件的封面即可,后续的只要封面后的内容。而PDF合并软件是简单粗暴的直接将所有内容合并,那合并后的文件就会多出很多我们不需要的“封面”。 Python有一个库PyPDF2 可轻松解决这个小问题,可以实现任意选定页面的合并。通过文件夹遍历,可以将不同文件夹下的PDF按选定的页面合并在一起,方便实用,绝不含糊 。 %%time import PyPDF2 #可从PDF文档提取信息 import os #用于获取需要合并的PDF文件所在路径 path='data/' # 文件夹路径 #1.获取需要用于合并的文件名及路径 files=[] for file in os.listdir(path): if file.endswith('.pdf'): #排除文件夹内的其它干扰文件,只获取PDF文件 files.append(path+file) #2.获取每个PDF文件里面需要的信息并添加到写入文件 pdf_writer=PyPDF2.PdfFileWriter() for file in files: pdf_obj=open(file,'rb')# 以二进制读取,将保留PDF中的所有信息 pdf_reader=PyPDF2.PdfFileReader(pdf_obj) for page_num in range(1,pdf_reader.numPages): #不要第一页的封面,从第2页开始获取 page_obj=pdf_reader.getPage(page_num) pdf_writer.addPage(page_obj) #3.写入并保存汇总PDF文件 pdf_output_file=open('data\combined_inv.pdf','wb') #以二进制写入,将保留源PDF中的所有信息 pdf_writer.write(pdf_output_file) pdf_output_file.close()
我们先导入PyPDF2 和os 库。若未安装PyPDF2 ,可运行'cmd.exe',输入'pip install PyPDF2',请注意PyPDF2有大小写要求,不然无法安装。 
然后定义pyth为我们需要操作的文件夹的路径。随后就需要获取我们待合并的所有PDF文件的文件名和路径,并存入我们定义的列表files 。如果文件夹内有非pdf文件,也会被获取。比如如下,我们可以看到这个路径下有一个txt文件,那可不是我们想要的。因此需要加入一个筛选,file.endswith('.pdf') 我们只要以'.pdf'结尾的文件。这样得到的files列表就是我们需要合并的文件及其路径了。files.append(path+file) 里面'path+file'是用于将路径和文件名连接起来,这样才能得到文件的完整路径,程序才可以找得到这个文件。
os.listdir(path) >['combined_inv.pdf', 'INV1.pdf', 'INV2.pdf', 'INV3.pdf', 'INV4.pdf', 'INV5.pdf', 'test.txt']
files >['data/INV1.pdf', 'data/INV2.pdf', 'data/INV3.pdf', 'data/INV4.pdf', 'data/INV5.pdf']
待合并的PDF文件路径搜集完后,就可以开始逐个读取其中想要的页面了。按照PyPDF2的操作要求,我们需要按如下步骤来进行读取和写入: 1. 打开PDF文件,得到一个“读取”对象。读取对象相当于是盛装这个PDF文件内容的容器。 2.创建一个 “写入” 对象,相当于另一个容器,用于向其中转移上一个步骤读取出来的内容。 3.将页面从 “读取” 容器倒入 “写入” 容器之中。 4.待“写入”容器装完所有需要的内容后,写入并输出新的 PDF。
pdf_writer=PyPDF2.PdfFileWriter() 就是用于装待写入文件的容器, PyPDF2.PdfFileWriter() 是固定写法,其原理就无需深究了。然后我们读取每个PDF文件,先将打开PDF文件,并存到pdf_obj ,然后使用PyPDF2.PdfFileReader(pdf_obj) 读取其中的信息,存到pdf_reader ,然后再获取其中的页面,此处我们将其中第2页及以后的页(如果有的话)面提取出来。因此range(1,pdf_reader.numPages) 是从1开始,因为range 是从0索引开始,因此1代表第二页。“pdf_reader.numPages”是该PDF文件的总页数。pdf_reader.getPage(page_num) 可获得其中每页的信息,我们将它存入page_obj 容器。随后我们使用addPage方法pdf_writer.addPage(page_obj) 将page_obj 中的信息放入最开始的pdf_writer容器中。
就这样逐个打开相关PDF文件,读取文件,获取页面信息,然后存入pdf_writer容器。如同吃火锅时,从不同的佐料中取我们想要的佐料和量,加入到自己的油碟中一样。 待所有想要合并的页面都加入pdf_writer容器之后,就可以写入新的PDF文件并保存了。先新建一个名为“combined_inv.pdf”的文件,并以二进制打开 open('data\combined_inv.pdf','wb') 。然后将pdf_writer容器中的所有信息用write方法写入到新的文件pdf_writer.write(pdf_output_file) 。最后关闭该文件pdf_output_file.close() ,操作完成。合并后的PDF文件combined_inv.pdf 如下:

所有源代码和说明都在Jupyter notebook上完成,所用到的Excel 资料已上传GitHub, 欢迎Fork或下载到本地随意玩。。。转载请注明出处,谢谢。 GitHub链接: https://github.com/weidylan/Office_Automation_by_Using_Python
|