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)

下表是部分 PdfFileReader 对象的方法和属性:

属性和方法 描述
getDestinationPageNumber(destination) 检索给定目标对象的页码
getDocumentInfo() 检索 PDF 文件的文档信息字典
getFields(tree = None,retval = None,fileObj= None) 如果此 PDF 包含交互式表单字段,则提取字段数据,
getFormTextFields() 从文档中检索带有文本数据(输入,下拉列表)的表单域
getNameDestinations(tree = None,retval= None) 检索文档中的指定目标
getNumPages() 计算此 PDF 文件中的页数
getOutlines(node = None,outline = None,) 检索文档中出现的文档大纲
getPage(pageNumber) 从这个 PDF 文件中检索指定编号的页面
getPageLayout() 获取页面布局
getPageMode() 获取页面模式
getPageNumber(pageObject) 检索给定 pageObject 处于的页码
getXmpMetadata() 从 PDF 文档根目录中检索 XMP 数据
isEncrypted 显示 PDF 文件是否加密的只读布尔属性
decrypt(密码) 通过指定密码对pdf文件进行解密

实例一:从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()方法。

下表是部分 PdfFileWriter 对象的方法和属性:

属性和方法 描述
addAttachment(fname,fdata) 在 PDF 中嵌入文件
addBlankPage(width= None,height=None) 追加一个空白页面到这个 PDF 文件并返回它
addJS(javascript) 添加将在打开此 PDF 是启动的 javascript
addLink(pagenum,pagedest,rect,border=None,fit=’/fit’,*args) 从一个矩形区域添加一个内部链接到指定的页面
addPage(page) 添加一个页面到这个PDF 文件,该页面通常从 PdfFileReader 实例获取
getNumpages() 页数
getPage(pageNumber) 从这个 PDF 文件中检索一个编号的页面
insertBlankPage(width=None,height=None,index=0) 插入一个空白页面到这个 PDF 文件并返回它,如果没有指定页面大小,就使用最后一页的大小
insertPage(page,index=0) 在这个 PDF 文件中插入一个页面,该页面通常从 PdfFileReader 实例获取
removeLinks() 从次数出中删除连接盒注释
removeText(ignoreByteStringObject = False) 从这个输出中删除图像
write(stream) 将添加到此对象的页面集合写入 PDF 文件

实例三:拷贝页面

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 的对象。

下表是部分 PageObject 对象的属性和方法:

扫描二维码关注公众号,回复: 10686680 查看本文章
属性或方法 描述
createBlankPage(pdf=None,width=None,height=None) 返回一个新的空白页面(静态方法)
extractText() 找到所有文本绘图命令,按照他们在内容流中提供的顺序,并提取文本
getContents() 访问页面内容,返回 Contents 对象或 None
rotateClockwise(angle) 顺时针旋转指定度数
scale(sx,sy) 通过向其内容应用转换矩阵并更新页面大小
mergePage(page) 页面的合并
compressContentStreams() 页面压缩
mediaBox.upperRight 将页面裁剪成指定大小
mediaBox.getUpperRight_x()/mediaBox.getUpperRight_y() 获取页面的大小

实例四:旋转页面

# **实例三:拷贝页面**
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))

# 加密,并且设置密码为: 123456
file_writer.encrypt('123456')

# 保存文件
file_writer.write(open('out/newMySQL.pdf', 'wb'))

参考书籍:《Python编程快速上手-让繁琐工作自动化》

发布了40 篇原创文章 · 获赞 11 · 访问量 1464

猜你喜欢

转载自blog.csdn.net/yuting209/article/details/104871180