介绍
在RPA流程设计中,会有各类文件的处理,其中就包括对pdf文件的处理,这时候就需要调用PyPDF2进行相关的代码编写了。
PyPDF2 是一个纯 Python 包,可通过使用 PyPDF2 包在 Python 中处理已先存在的 PDF。
- 提取 PDF 中的文档信息
- 旋转页面
- 合并 PDF
- 拆分 PDF
- 添加水印
- 加密 PDF
1、提取文档信息
使用 PyPDF2 从 PDF 中提取元数据和一些文本,尤其是当在预先存在的 PDF 文件上执行某些类型的自动化时是非常有用的。
以下是当前可以提取的数据:
- Author
- Creator
- Producer
- Subject
- Title
- Number of page
可以在自己的电脑上随便找一个 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 中提取文本。
2、旋转页面
有时候 PDF 是横向模式而不是纵向模式,甚至是颠倒的。当有人扫描文档为 PDF 或电子邮件时,很可能会发生这种情况。我们可以打印出文档并阅读纸质版本,也可以使用 Python 的强大功能来旋转有问题的页面。
下面看一下如何使用 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)
3、合并 PDF
在许多情况下,我们希望将两个或多个 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 模块为这个函数创建一个命令行接口。
4、拆分 PDF
有时可能需要将 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。
5、添加水印
水印是纸质或者电子文档上的图像或图案,一些水印只能在特殊照明条件下才能看到。水印的重要性在于它可以保护你的知识产权,例如图像或 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 有三个参数:
- input_pdf:要加水印的 PDF 文件路径
- output:要保存 PDF 的水印版本的路径
- watermark:包含水印图像或文本的 PDF
在代码中,打开水印 PDF 并从文档中抓取第一页,因为这是水印应该驻留的位置。然后使用 input_pdf 和通用 pdf_writer 对象创建 PDF 的 writer 对象,以写出带水印的 PDF。
下一步是遍历 input_pdf 中的页面,然后调用.mergePage() 并以用上面读取的水印对象 watermark_page 为参数,这样会将 watermark_page 覆盖在当前页面的顶部,然后再将新合并的页面添加到 pdf_writer 对象中。遍历完成后,最后将新加水印的 PDF 写入磁盘。
6、加密 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 位加密。
免费下载试用:https://support.i-search.com.cn/