当前位置: 首页 > 后端技术 > Python

最全总结!说说用python操作PDF的几种方法

时间:2023-03-26 15:53:10 Python

作者:陈曦来源:早起Python1.前言大家好,之前写过Python操作PDF的案例吗?PDF批量合并,本案例的初衷只是为大家提供一个方便的脚本,原理上并没有过多的讲解,其中涉及到非常实用的PDF处理模块PyPDF2。本文将仔细分析这个模块,主要涉及os模块的综合应用、glob模块的综合应用、PyPDF2的综合应用。导入模块的代码往往是:fromPyPDF2importPdfFileReader,PdfFileWriter这里导入了两个方法:PdfFileReader可以理解为reader,PdfFileWriter可以理解为writer接下来通过几个案例,进一步了解这两个的妙用tools,使用的示例文件是5张发票的pdf,每张发票的PDF由两页组成:3.Merge第一个工作是将5张发票pdf合并成10页。读者和作者在这里应该如何合作?逻辑是这样的:reader读取一次所有的pdf,reader将读取的内容传递给writer,writer统一输出到一个新的pdf。这里还有一个重要的知识点:读者只能将读取到的内容一页一页地交给作者。因此,逻辑上的第1步和第2步其实并不是独立的步骤,而是读者阅读完一个pdf后,会循环遍历pdf的所有页面,一页一页地交给作者。最后等待读取工作完成再输出。看代码可以更清楚思路:fromPyPDF2importPdfFileReader,PdfFileWriterpath=r'C:Usersxxxxxx'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'MergePDFmerge.pdf','wb')作为输出:pdf_writer.write(out)由于所有的内容都需要交给同一个writer一起最终输出,所以writer的初始化必须在循环体之外。如果在循环体内,每次访问都会变成readpdf生成新的writer,这样每次reader交给writer的内容都会被反复覆盖,无法实现我们的合并需求!循环体开头的代码:foriinrange(1,6):pdf_reader=PdfFileReader(path+'/INV{}.pdf'.format(i))目的是读取一个新的pdf文件in每次循环,交给读者进行后续操作。其实这种写法不是很推荐。由于每个pdf的命名恰好是很规律的,所以可以直接手动指定编号循环。更好的方法是使用glob模块:importglobforfileinglob.glob(path+'/*.pdf'):pdf_reader=PdfFileReader(path)代码中pdf_reader.getNumPages():可以得到的页数thereader,有了range,可以遍历reader的所有页面。pdf_writer.addPage(pdf_reader.getPage(page))可以将当前页面提供给作者。最后用with新建一个pdf,通过writer的pdf_writer.write(out)方法输出。4.拆分如果理解了reader和writer在merge操作中的配合,那么拆分就很容易理解了,这里我们以将INV1.pdf拆分成2个单独的pdf文件为例,我们也通过逻辑先行:读者阅读PDF文档,读者将其发送给作者逐页写入读者立即输出它得到的每一页。通过这段代码逻辑,我们也可以了解到,writer初始化和输出的位置一定是在PDF阅读循环的每一页的循环体内,而不是在循环外。代码很简单:fromPyPDF2importPdfFileReader,PdfFileWriterpath=r'C:Usersxxx'pdf_reader=PdfFileReader(path+'INV1.pdf')forpageinrange(pdf_reader.getNumPages()):遍历每个页面生成writers一个一个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办公自动化的核心之一就是批量操作——解放双手,将复杂的工作自动化!