Python|PyPDF2实现PDF自动拆分

实现PDF自动拆分

前段时间帮同事从系统中批量导出几十个流程,导出发现合并生成了一个PDF,需要每2页拆分为一个PDF。Adobe pdfreader虽然可以拆分,但逐一拆分还是比较耗费精力。在线PDF处理工具大多也可以实现PDF的批量拆分,考虑到公司内部文件,还是尽量避免使用在线工具。之后我就用python实现了PDF文件的自动拆分。

源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from PyPDF2 import PdfReader, PdfWriter
# 获取文件页数
def pdf_reader(pdf_in):
with open(pdf_in,'rb') as in_pdf:
pdf_file = PdfReader(in_pdf)
pages = pdf_file.getNumPages()
return pages

# 拆分pdf
def pdf_split(pdf_in,pdf_out,start,end):
# 初始化一个pdf
output = PdfWriter()
# 从指定路径读取目标pdf
with open(pdf_in, 'rb') as in_pdf:
pdf_file = PdfReader(in_pdf)
# 从目标pdf中取出指定页
for i in range(start, end):
output.addPage(pdf_file.getPage(i))
# 写入新的pdf,输出到指定路径
with open(pdf_out, 'ab') as out_pdf:
output.write(out_pdf)

if __name__ == '__main__':
pdf_in = r'C:\Users\Administrator\Desktop\测试.pdf'
pages = pdf_reader(pdf_in)
for i in range(1,pages):
pdf_out = r'C:\Users\Administrator\Desktop\第{}个.pdf'.format(i)
pdf_split(pdf_in, pdf_out, i-1 ,i)

代码更新完善

在之前的代码中,虽然实现了PDF的自动拆分,但却仅仅是每2页拆分为一个,实际使用时有一定的局限性。一般情况下都是根据固定的内容(如标题、编号、关键字等)进行拆分的。所以我又优化了代码,逐页读取文件内容,并根据“出差申请”关键字进行拆分,且通过内容中的“编号”生成文件名。代码如下:

使用时发现PyPDF2库更新了,舍弃了之前reader.getNumPages()、writer.addPage()的用法,新的用法为len(reader.pages)、writer.add_page()。知识的学习果真是常学常新。😁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from PyPDF2 import PdfReader, P dfWriter
import re
# 获取文件页数
def pdf_reader(pdf_in):
pdf_file = PdfReader(pdf_in)
pages = len(pdf_file.pages)
return pages

# 获取页面内容
def pdf_content(pdf_in,page):
pdf_page = PdfReader(pdf_in)
page = pdf_page.pages[page]
return page.extract_text()

# 拆分pdf
def pdf_split(pdf_in,pdf_out,start,end):
# 初始化一个pdf
output = PdfWriter()
# 从指定路径读取目标pdf
with open(pdf_in, 'rb') as in_pdf:
pdf_file = PdfReader(in_pdf)
# 从目标pdf中取出指定页
for i in range(start, end):
output.add_page(pdf_file.pages[i])
# 写入新的pdf,输出到指定路径
with open(pdf_out, 'ab') as out_pdf:
output.write(out_pdf)

if __name__ == '__main__':
pdf_in = r'C:\Users\admin\Desktop\新建文件夹\all.pdf'
# 获取编号,用于生成拆分后的pdf文件名
pat = r'(?<=[0-9]{4}\])[0-9]+'
pages = pdf_reader(pdf_in)
startPage = pages-1
endPage = pages
for i in range(pages,0,-1):
s = pdf_content(pdf_in,i-1)
if "[XXX信][出差申请]" in s:
filename = re.findall(pat,s)[0]
pdf_out = r'C:\Users\admin\Desktop\新建文件夹\申请编号{}.pdf'.format(filename)
startPage = i-1
pdf_split(pdf_in,pdf_out,startPage,endPage)
startPage = i-2
endPage = i-1
print('申请编号:{},拆分成功!'.format(filename))

PyPDF2库基本用法整理

PyPDF2历史

PyPDF2是一个免费的开源纯 python PDF 库,能够分割、合并、裁剪和转换 PDF 文件的页面。它还可以向 PDF 文件添加自定义数据、查看选项和密码。PyPDF2也可以从 PDF 中检索文本和元数据。PyPDF2 近期也没有再更新了,最近一个版本发布在2016年,但使用热度依然没有消退。

PDF文件信息处理

1
2
3
4
5
6
7
8
9
10
11
# 读取pdf文件信息
from PyPDF2 import PdfReader
def pdf_info(pdf_in):
    reader = PdfReader(pdf_in)
    pdfinfo = reader.metadata
    return reader.numPages , len(reader.pages) , pdfinfo.author , pdfinfo.creator , pdfinfo.producer , pdfinfo.subject , pdfinfo.title
if __name__ == '__main__' :
    pdf_in = r'C:/Users/admin/Desktop/case/测试.pdf'
    pdfinfo = pdf_info(pdf_in)
    print(pdfinfo)
# 执行结果: (7, 7, 'chen di1', 'Microsoft® Word 适用于 Microsoft 365', 'Microsoft® Word 适用于 Microsoft 365', None, None)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 插入文件信息
# write metadata
from PyPDF2 import PdfReader,PdfWriter
reader = PdfReader(r'C:\Users\Administrator\Desktop\javascript原理.pdf')
writer = PdfWriter()
for i in reader.pages:
    writer.add_page(i)
writer.add_metadata(
    {
        '/Author':'TestAuthor',
        '/Title':'TestTitle',
    }
)
with open(r'C:\Users\Administrator\Desktop\test2.pdf','wb') as wf :
    writer.write(wf)

PDF合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 简单合并pdf
from PyPDF2 import PdfMerger
def pdf_combine(pdf_in1,pdf_in2,pdf_out):
    outpdf = PdfMerger()
    for pdf in [pdf_in1,pdf_in2]:
        outpdf.append(pdf)
    outpdf.write(pdf_out)
    outpdf.close()

if __name__ == '__main__':
    pdf_in1 = 'C:/Users/admin/Desktop/case/第1个.pdf'
    pdf_in2 = 'C:/Users/admin/Desktop/case/第2个.pdf'
    pdf_out = 'C:/Users/admin/Desktop/case/合并后.pdf'
    pages = pdf_combine(pdf_in1,pdf_in2,pdf_out)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 多pdf灵活合并
from PyPDF2 import PdfMerger
merger = PdfMerger()
input1 = open(r'C:/Users/admin/Desktop/case/测试.pdf', "rb")
input2 = open(r'C:/Users/admin/Desktop/case/第6个.pdf', "rb")
input3 = open(r'C:/Users/admin/Desktop/case/第4个.pdf', "rb")
# 取input1文件的前三页
merger.append(fileobj=input1, pages=(0, 3))
# 在第二页后插入input2的第一页
merger.merge(position=2, fileobj=input2, pages=(0, 1))
# 在最后一页插入input3所有页
merger.append(input3)
# 写入新的pdf文件
output = open(r'C:/Users/admin/Desktop/case/合并测试.pdf', "wb")
merger.write(output)
merger.close()
output.close()

PDF裁剪与转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# PDF裁剪与转换
from PyPDF2 import PdfWriter, PdfReader
reader = PdfReader("example.pdf")
writer = PdfWriter()
# 添加第一页到pdf:
writer.add_page(reader.pages[0])
# 添加第二页并顺时针旋转90度到pdf:
writer.add_page(reader.pages[1].rotate(90))
# 添加第三页并截取1/4到pdf:
page3 = reader.pages[2]
page3.mediabox.upper_right = (
    page3.mediabox.right / 2,
    page3.mediabox.top / 2,
)
writer.add_page(page3)
# 添加一些JavaScript以在打开此PDF时启动“打印窗口”。:
writer.add_js("this.print({bUI:true,bSilent:false,bShrinkToFit:true});")
# 输出pdf
with open("PyPDF2-output.pdf", "wb") as fp:
    writer.write(fp)

提取PDF中的文字

1
2
3
4
5
6
from PyPDF2 import PdfReader
reader = PdfReader(r'C:/Users/Administrator/Desktop/test2.pdf')
page = reader.pages[0]
content0 = page.extract_text()
# print(page.extract_text((0, 90))) # 页面左转90度提取
print(content0)

PDF加解密

如果计划使用 PyPDF2对使用 AES 的 PDF 进行加密或解密,则需要安装一些额外的依赖项。使用常规安装支持使用 RC4进行加密。

pip install PyPDF2[crypto]

1
2
3
4
5
6
7
8
9
from PyPDF2 import PdfReader,PdfWriter
reader = PdfReader(r'C:/Users/Administrator/Desktop/test2.pdf')
writer = PdfWriter()
for i in reader.pages:
    writer.add_page(i)
# 文件加密
writer.encrypt('qwer1234')
with open(r'C:/Users/Administrator/Desktop/test3.pdf','wb') as f :
    writer.write(f)
1
2
3
4
5
6
7
8
9
10
from PyPDF2 import PdfReader,PdfWriter
reader = PdfReader(r'C:/Users/Administrator/Desktop/test3.pdf')
writer = PdfWriter()
# 文件解密
if reader.is_encrypted:
    reader.decrypt('qwer1234')
for i in reader.pages:
    writer.add_page(i)
with open(r'C:/Users/Administrator/Desktop/test4.pdf','wb') as f :
    writer.write(f)

其他

类似地,pypdf2还有翻页、缩放、添加水印、阅读/添加注释、表格处理等。具体可参照 PyPDF2官方文档


商业转载请联系作者获得授权,非商业转载请注明出处。

支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者

Python|PyPDF2实现PDF自动拆分
http://hncd1024.github.io/2022/09/05/Python_PDFCut/
作者
CHEN DI
发布于
2022-09-05
许可协议