当前位置: 首页 > 科技观察

超全总结!下面说说使用python操作PDF的几种方法

时间:2023-03-19 19:31:43 科技观察

1.前言大家好。关于Python操作PDF的案例,之前写过PDF批量合并。本案例的初衷只是为了给大家提供一个方便的脚本,并没有过多的解释原理,其中涉及到非常实用的PDF处理模块PyPDF2,本文将对这个模块进行分析,主要涉及到的综合应用os模块,glob模块的综合应用,PyPDF2模块操作2.基本操作PyPDF2导入模块的代码往往是:fromPyPDF2importPdfFileReader,PdfFileWriter在这里导入两个方法:PdfFileReader可以理解为阅读器PdfFileWriter可以以笔者的理解接下来通过几个案例进一步了解这两个工具的妙用,使用的示例文件是5张发票的pdf每张发票的PDF包含两页:3.合并第一个工作是合并5张发票pdf分为10页。读者和作者在这里应该如何合作?逻辑是这样的:reader读取一次所有的pdf,reader将读取的内容传递给writer,writer统一输出到一个新的pdf。这里还有一个重要的知识点:读者只能将读取到的内容一页一页地交给作者。因此,逻辑上的第1步和第2步其实并不是独立的步骤,而是读者阅读完一个pdf后,会循环遍历pdf的所有页面,一页一页地交给作者。最后等待读取工作完成再输出。看代码可以思路更清晰:fromPyPDF2importPdfFileReader,PdfFileWriterpath=r'C:\Users\xxxxxx'pdf_writer=PdfFileWriter()foriinrange(1,6):pdf_reader=PdfFileReader(path+'/INV{}.pdf'.format(i))forpageinrange(pdf_reader.getNumPages()):pdf_writer.addPage(pdf_reader.getPage(page))withopen(path+r'\mergePDF\merge.pdf','wb')asout:pdf_writer.write(out)由于所有的内容都需要交给同一个writer一起最终输出,所以writer的初始化必须在循环体之外。如果在循环体内,每次访问一个pdf都会变成一个新的read。Writer,这样每次读者交给writer的内容都会被反复覆盖,无法实现我们的合并需求!循环体开头的代码:foriinrange(1,6):pdf_reader=PdfFileReader(path+'/INV{}.pdf'.format(i))的目的是每次手动读取一个新的pdf文件交给读者进行后续操作。其实这种写法不是很推荐。由于每个pdf的命名恰好是很规律的,所以可以直接手动指定编号循环。更好的方法是使用glob模块:代码中的importglobforfileinglob.glob(path+'/*.pdf'):pdf_reader=PdfFileReader(path)pdf_reader.getNumPages():可以得到阅读器的页数,它可以用范围遍历阅读器的所有页面。pdf_writer.addPage(pdf_reader.getPage(page))可以将当前页面提供给作者。最后用with新建一个pdf,通过writer的pdf_writer.write(out)方法输出。4.拆分如果理解了合并操作中reader和writer的配合,那么拆分就很容易理解了,这里我们以将INV1.pdf拆分成两个单独的pdf文件为例,我们也来回顾一下逻辑优先:读者阅读PDF文档,读者将其逐页发送给作者编写。读者每获得一个页面,都会通过这段代码逻辑立即输出。我们也可以这样理解,writer初始化输出的位置一定是在PDF阅读循环的每一页的循环体中,而不是在循环外。代码很简单:fromPyPDF2importPdfFileReader,PdfFileWriterpath=r'C:\Users\xxx'pdf_reader=PdfFileReader(path+'\INV1.pdf')forpageinrange(pdf_reader.getNumPages()):#遍历到每个页面生成作者一个一个pdf_writer=PdfFileWriter()pdf_writer。addPage(pdf_reader.getPage(page))#writer添加页面后立即输出生成pdfwithopen(path+'\INV1-{}.pdf'.format(page+1),'wb')asout:pdf_writer.write(out)5.水印这次的工作是给INV1.pdf添加下图作为水印。首先是准备工作,将需要做水印的图片插入到word中,调整合适的位置,保存为PDF文件。然后就可以码代码了,需要额外使用copy模块。具体解释见下图:初始化读写器,先读取带水印的PDF页面进行备份。核心代码有点难懂:addWatermarking本质上就是把打了水印的PDF页面和每个需要打水印的页面合并。由于需要加水印的PDF可能有很多页,而加水印的PDF只有一页,所以如果直接合并加水印的PDF,可以抽象理解。添加第一页后,带有水印的PDF页面将消失。因此不能直接用于合并,而是要将带水印的PDF页面不断复制到一个新的页面中作为备用的new_page,然后使用.mergePage方法完成与各个页面的合并,将合并后的页面交给最后统一输出给作者!关于.mergePage的使用:.mergePage出现在底页(出现在首页)。相关操作完成后需要调用pdf_writer.encrypt(密码)。以单个PDF的加密为例:写在最后。当然,除了PDF的合并、拆分、加密、水印,我们还可以用Python结合Excel和Word来实现更多的自动化需求,这些就留给读者去开发吧。最后希望大家能够明白,Python办公自动化的核心之一就是批量操作——解放双手,将复杂的工作自动化!