【Python自动化办公】pdf文件自动处理
PDF 表示 Portable Document Format,使用 .pdf 作为文件扩展名。虽然 PDF 支持许多功能,但现在我们专注于最常做的两件事:从 PDF 读取文本内容和从已有的文档生成新的 PDF。主要涉及到三个类:PdfFileReader、PdfFileWriter、PageObject。 Python中用于处理PDF文档的模块是PyPDF2。可以直接通过 pip 指令去安装:
pip install PyPDF2
。 这个地方要注意,模块名是区分大小写的,除了 y 是小写其他字母都是大写。
1. PdfFileReader
PdfFileReader是 PyPDF2 提供的一个类,主要是通过方法和属性来提供获取pdf文件内容的相关功能。 使用PdfFileReader读取pdf文件前需要先创建一个PdfFileReader的对象:
PdfFileReader(stream, strict = True,warndest = None,overwriteWarnings = True)
- stream: File 对象或支持与 File 对象类似的标准读取和查找方法的对象, 也可以是表示 PDF 文件路径的字符串。
- strict(bool) : 确定是否应该警告用户所用的问题,也导致一些可纠正的问题是致命的,默认是 True
- warndest : 记录警告的目标(默认是 sys.stderr)
- overwriteWarnings(bool) :确定是否 warnings.py 用自定义实现覆盖 Python 模块(默认为 True)
实例一:从PDF文件中提取文本
# 从PyPDF2模块中导入PdfFileReader类
from PyPDF2 import PdfFileReader
# 打开需要操作的pdf文件,获取文件对象。因为pdf文件是二进制文件,所以打开的时候是 'rb'
pdf_file = open('files/new.pdf', 'rb')
# 创建pdf文件对应的PdfFileReader对象
pdf_reader = PdfFileReader(pdf_file)
# 获取当前pdf文件总页数(这儿其实不需要,只是给大家看看)
total_page = pdf_reader.getNumPages() # 结果是: 17
# 获取pdf文件的第一页
page0 = pdf_reader.getPage(0)
# 获取第一页中的文本内容
text_content = page0.extractText()
print(text_content)
实例二:解密
# 从PyPDF2模块中导入PdfFileReader类
from PyPDF2 import PdfFileReader
# 创建PdfFileReader对象,并且让它和指定的pdf文件进行关联
# pdf_reader = PdfFileReader('files/MySQL.pdf') # 打开文件的时候可以直接给pdf文件路径
pdf_reader = PdfFileReader(open('files/MySQL.pdf', 'rb')) # 打开文件的时候可以直接给文件对象
# 是否加密 - 如果结果是True,表示已经加密,如果获取页面的时候程序会报错
is_encrypted = pdf_reader.isEncrypted
# 通过密码解密, 这儿的 1234 是密码
pdf_reader.decrypt('1234')
# 获取当前pdf文件的第一页
page0 = pdf_reader.getPage(0)
2. PdfFileWriter
在 PyPDF2 中,与 PdfFileReader 对象相对的是 PdfFileWriter 对象,它可以创建一个新的 PDF 文件。但 PyPDF2 不能将任意文本写入 PDF,就像 Python 可以写入纯文本文件那样。PyPDF2 写入 PDF 的能力,仅限于从其他 PDF 中拷贝页面、旋转页面、重叠页面和加密文件。模块不允许直接编辑 PDF。必须创建一个新的 PDF,然后从已有的文档拷贝内容。PdfFileWriter 的使用一般遵守以下方式:
1. 打开一个或多个已有的 PDF(源 PDF),得到 PdfFileReader 对象。
2. 创建一个新的 PdfFileWriter 对象。
3. 将页面从 PdfFileReader 对象拷贝到 PdfFileWriter 对象中。
4. 最后,利用 PdfFileWriter 对象写入输出的 PDF。
创建一个PdfFileWriter 对象,只是在Python 中创建了一个代表PDF 文档的值,这并没有创建实际的PDF 文件,要实际生成文件,必须调用PdfFileWriter 对象的write()方法。
实例三:拷贝页面
from PyPDF2 import PdfFileReader, PdfFileWriter
# 创建两个pdf文件对应的PdfFileReader对象
pdf_reader1 = PdfFileReader('files/file1.pdf')
pdf_reader2 = PdfFileReader('files/file2.pdf')
# 创建PdfFileWriter对象
writer = PdfFileWriter()
# 遍历将第一个pdf文件中的每一页取出来
for page_num in range(pdf_reader1.getNumPages()):
# 取出每一页对应的PageObject对象
page = pdf_reader1.getPage(page_num)
# 将当前取出来的页面添加到writer中
writer.addPage(page)
# 遍历将第二个pdf文件中的每一页取出来
for page_num in range(pdf_reader2.getNumPages()):
# 取出每一页对应的PageObject对象
page = pdf_reader2.getPage(page_num)
# 将当前取出来的页面添加到writer中
writer.addPage(page)
# write(stream) - 将添加到此对象的页面集合写入 PDF 文件 ,这儿的stream必须是以写的方式打开的文件对象
out_file = open('files/out.pdf', 'wb')
writer.write(out_file)
out_file.close()
# 程序结束后,会在files下创建一个 out.pdf 文件,文件中的内容是 file1.pdf 和 file2.pdf 两个文件中的所有内容
3. PageObject
从 PdfFileReader 对象中通过 getPage 方法得到页面都是 PageObject 的对象。
实例四:旋转页面
# **实例三:拷贝页面**
from PyPDF2 import PdfFileReader, PdfFileWriter
# 打开文件
# file_reader = PdfFileReader(open('files/MySQL.pdf', 'rb'))
file_reader = PdfFileReader('files/MySQL.pdf')
# 取第一页
page0 = file_reader.getPage(0)
# 旋转90度
page0.rotateClockwise(90)
# 创建 PdfFileWriter 对象
file_writer = PdfFileWriter()
# 将第一页添加到新文件中
file_writer.addPage(page0)
# 保存新文件
file_writer.write(open('files/MySQL2.pdf', 'wb'))

PyPDF2 也可以将一页的内容叠加到另一页上,这可以用来在页面上添加公司标志、时间戳或水印。利用 Python,很容易为多个文件添加水印,并且只针对程序指定的页面添加。
实例五: 添加水印
from PyPDF2 import PdfFileReader, PdfFileWriter
# 打开需要添加水印的文件
pdf_reader = PdfFileReader('files/MySQL.pdf')
# 打开水印文件
water_reader = PdfFileReader('files/water.pdf')
# 获取需要添加水印的页面(如果所有也都要添加水印就遍历)
page0 = pdf_reader.getPage(0)
# 获取水印页
water_page = water_reader.getPage(0)
page0.mergePage(water_page)
# 创建PdfFileWriter对象并且将已经添加水印的也添加到PdfFileWriter对象中
writer = PdfFileWriter()
writer.addPage(page0)
writer.write(open('out/newMySQL.pdf', 'wb'))

实例六:加密PDF
PdfFileWriter 对象也可以为 PDF 文档进行加密:
from PyPDF2 import PdfFileWriter, PdfFileReader
# 打开需要加密的文件
file_reader = PdfFileReader('files/MySQL.pdf')
# 创建PdfFileWriter对象
file_writer = PdfFileWriter()
# 将原文件的内容全部添加到PdfFileWriter对象中
for page_num in range(file_reader.getNumPages()):
file_writer.addPage(file_reader.getPage(page_num))