在RPA流程设计中,会有各种文件的处理,其中就包括对pdf文件的处理,这时候就须要调用PyPDF2进行相关的代码编写了。
PyPDF2 是一个纯 Python 包,可经过使用 PyPDF2 包在 Python 中处理已先存在的 PDF。python
使用 PyPDF2 从 PDF 中提取元数据和一些文本,尤为是当在预先存在的 PDF 文件上执行某些类型的自动化时是很是有用的。
如下是当前能够提取的数据:函数
能够在本身的电脑上随便找一个 PDF 文件进行尝试操做。下面是使用该 PDF 编写一些代码,并了解如何访问这些属性:加密
from PyPDF2 import PdfFileReader def extract_information(pdf_path): with open(pdf_path, 'rb') as f: pdf = PdfFileReader(f) information = pdf.getDocumentInfo() number_of_pages = pdf.getNumPages() txt = f""" Information about {pdf_path}: Author: {information.author} Creator: {information.creator} Producer: {information.producer} Subject: {information.subject} Title: {information.title} Number of pages: {number_of_pages} """ print(txt) return information if __name__ == '__main__': path = 'xxxx.pdf' extract_information(path)
首先从 PyPDF2 包导入 PdfFileReader。PdfFileReader 是一个具备多种与 PDF 文件交互的方法的类。在此示例中,咱们调用了.getDocumentInfo(),它将返回 DocumentInformation 的实例, 包含了咱们感兴趣的大部分信息。咱们还能够在 reader 对象上调用.getNumPages(),让它返回文档中的页数。命令行
information 这个变量具备多个实例属性,可使用这些属性从文档中获取所需的其他元数据。咱们能够打印出该信息并将其返回以备未来使用。设计
虽然 PyPDF2 具备.extractText(),能够在其页面对象上使用提取文本(本例中未显示),但它的效果不是很好。有些 PDF 会返回文本,有些会返回空字符串。若是要从 PDF 中提取文本,建议应该看一下 PDFMiner 项目。PDFMiner 更增强大,专门用于从 PDF 中提取文本。code
有时候 PDF 是横向模式而不是纵向模式,甚至是颠倒的。当有人扫描文档为 PDF 或电子邮件时,极可能会发生这种状况。咱们能够打印出文档并阅读纸质版本,也可使用 Python 的强大功能来旋转有问题的页面。orm
下面看一下如何使用 PyPDF2 旋转文章的一些页面:对象
from PyPDF2 import PdfFileReader, PdfFileWriter def rotate_pages(pdf_path): pdf_writer = PdfFileWriter() pdf_reader = PdfFileReader(path) # 顺时针旋转90度 page_1 = pdf_reader.getPage(0).rotateClockwise(90) pdf_writer.addPage(page_1) # 逆时针旋转90度 page_2 = pdf_reader.getPage(1).rotateCounterClockwise(90) pdf_writer.addPage(page_2) # 在正常方向上添加一页 pdf_writer.addPage(pdf_reader.getPage(2)) with open('rotate_pages.pdf', 'wb') as fh: pdf_writer.write(fh) if __name__ == '__main__': path = '新路径.pdf' rotate_pages(path)
在许多状况下,咱们但愿将两个或多个 PDF 合并到一个 PDF 中。例如,如今可能有一个标准的封面,须要转到许多类型的报告中。这时候就可使用 python 来帮助完成这类工做。接口
下面是实现的代码,完成 PDF 合并的操做:文档
from PyPDF2 import PdfFileReader, PdfFileWriter def merge_pdfs(paths, output): pdf_writer = PdfFileWriter() for path in paths: pdf_reader = PdfFileReader(path) for page in range(pdf_reader.getNumPages()): # 将每页添加到writer对象 pdf_writer.addPage(pdf_reader.getPage(page)) # 写入合并的pdf with open(output, 'wb') as out: pdf_writer.write(out) if __name__ == '__main__': paths = ['document1.pdf', 'document2.pdf'] merge_pdfs(paths, output='merged.pdf')
假若有一个要合并到一块儿的 pdf 列表时,能够直接使用 merge_pdf 函数完成。此函数采用了输入路径和输出路径做为参数。
首先遍历输入的 paths,并为每一个输入建立一个 PDF 阅读对象。而后遍历 PDF 文件中的全部页面,并使用.addpage() 将这些页面写入 writer 对象。当完成对列表中全部 PDF 的全部页面的写入后,将在末尾写入新的结果中。
若是不想合并每一个 PDF 的全部页面,能够经过添加一系列要添加的页面来稍微加强这个脚本。挑战一点的话,也可使用 Python 的 argparse 模块为这个函数建立一个命令行接口。
有时可能须要将 PDF 拆分为多个 PDF,对于包含大量扫描内容的 PDF 来讲尤为重要。如下是如何使用 PyPDF2 将 PDF 拆分为多个文件:
from PyPDF2 import PdfFileReader, PdfFileWriter def split(path, name_of_split): pdf = PdfFileReader(path) for page in range(pdf.getNumPages()): pdf_writer = PdfFileWriter() pdf_writer.addPage(pdf.getPage(page)) output = f'{name_of_split}{page}.pdf' with open(output, 'wb') as output_pdf: pdf_writer.write(output_pdf) if __name__ == '__main__': path = 'xxx.pdf' split(path, 'jupyter_page')
这个函数中再次建立了 PDF 的 reaer 对象,并对其所读取的页面进行遍历。对于 PDF 中的每一个页面,建立一个新的 PDF 的 writer 实例并向其添加单个页面。而后,将该页面写入一个惟一命名的文件。脚本运行完毕后,就能够将原始 PDF 的每一个页面拆分为单独的 PDF。
水印是纸质或者电子文档上的图像或图案,一些水印只能在特殊照明条件下才能看到。水印的重要性在于它能够保护你的知识产权,例如图像或 PDF。
咱们可使用 Python 和 PyPDF2 为文档添加水印,并且是拥有仅包含水印图像或文本的 PDF。下面是向 PDF 添加水印方法:
from PyPDF2 import PdfFileWriter, PdfFileReader def create_watermark(input_pdf, output, watermark): watermark_obj = PdfFileReader(watermark) watermark_page = watermark_obj.getPage(0) pdf_reader = PdfFileReader(input_pdf) pdf_writer = PdfFileWriter() # 给全部页面添加水印 for page in range(pdf_reader.getNumPages()): page = pdf_reader.getPage(page) page.mergePage(watermark_page) pdf_writer.addPage(page) with open(output, 'wb') as out: pdf_writer.write(out) if __name__ == '__main__': create_watermark( input_pdf='Jupyter_Notebook_An_Introduction.pdf', output='watermarked_notebook.pdf', watermark='watermark.pdf')
上面 create_watermark 有三个参数:
在代码中,打开水印 PDF 并从文档中抓取第一页,由于这是水印应该驻留的位置。而后使用 input_pdf 和通用 pdf_writer 对象建立 PDF 的 writer 对象,以写出带水印的 PDF。
下一步是遍历 input_pdf 中的页面,而后调用.mergePage() 并以用上面读取的水印对象 watermark_page 为参数,这样会将 watermark_page 覆盖在当前页面的顶部,而后再将新合并的页面添加到 pdf_writer 对象中。遍历完成后,最后将新加水印的 PDF 写入磁盘。
PyPDF2 目前仅支持将用户密码和全部者密码添加到预先存在的 PDF。在 PDF 版本中,全部者密码会提供 PDF 的管理员权限,并容许设置文档的权限,而用户密码只容许打开文档。
实际上,PyPDF2 是不容许设置文档的任何权限的,即便它容许设置全部者密码的状况下。但不管如何,这是能够加密的方式,也将固有地加密 PDF:
from PyPDF2 import PdfFileWriter, PdfFileReader def add_encryption(input_pdf, output_pdf, password): pdf_writer = PdfFileWriter() pdf_reader = PdfFileReader(input_pdf) for page in range(pdf_reader.getNumPages()): pdf_writer.addPage(pdf_reader.getPage(page)) pdf_writer.encrypt(user_pwd=password, owner_pwd=None, use_128bit=True) with open(output_pdf, 'wb') as fh: pdf_writer.write(fh) if __name__ == '__main__': add_encryption(input_pdf='reportlab-sample.pdf', output_pdf='reportlab-encrypted.pdf', password='twofish')
dd_encryption 以输入输出 PDF 路径和要添加到 PDF 的密码为参数。因为须要加密整个输入 PDF,所以须要遍历其全部页面并将其添加到 writer 编写器。最后一步是调用.encrypt(),以用户密码,全部者密码以及是否应该添加 128 位加密为参数。默认状况下,要启用 128 位加密。若是将其设置为 False,则将应用 40 位加密。