利用python的PyPDF2和PyMuPDF库玩转PDF的提取、合并、旋转、缩放、加密
一、安装PyPDF2和PyMuPDF库
pip install PyPDF2
pip install pymupdf # fitz是pymupdf的子模块
二、工具类代码
from PyPDF2 import PdfFileWriter, PdfFileReader, PdfFileMerger
import fitz
import re
import os
'''
根据页码列表从pdf中取出指定的页
pdf_input_path: 原pdf路径
pdf_output_path: 输出pdf路径
page_no_list: 提取页面列表
rotate_angle: 旋转角度
'''
def pdf_separate_by_page_no_list(pdf_input_path, pdf_output_path, page_no_list, rotate_angle=0):
# 初始化一个pdf
output = PdfFileWriter()
# 读取pdf
with open(pdf_input_path, 'rb') as in_pdf:
pdf_file = PdfFileReader(in_pdf)
# 从pdf中取出指定页
for page_no in page_no_list:
output.addPage(pdf_file.getPage(page_no - 1).rotateClockwise(rotate_angle))
# 写出pdf
with open(pdf_output_path, 'ab') as out_pdf:
output.write(out_pdf)
'''
根据起止页码范围(包含开头包含结尾)从pdf中取出所需页
pdf_input_path: 原pdf路径
pdf_output_path: 输出pdf路径
start_page_no: 开始页码
end_page_no: 结束页码
rotate_angle: 旋转角度
'''
def pdf_separate_from_start_to_end(pdf_input_path, pdf_output_path, start_page_no, end_page_no, rotate_angle=0):
# 初始化一个pdf
output = PdfFileWriter()
# 读取pdf
with open(pdf_input_path, 'rb') as in_pdf:
pdf_file = PdfFileReader(in_pdf)
# 从pdf中取出指定页
for i in range(start_page_no - 1, end_page_no):
output.addPage(pdf_file.getPage(i).rotateClockwise(rotate_angle))
# 写出pdf
with open(pdf_output_path, 'ab') as out_pdf:
output.write(out_pdf)
'''
通过多个pdf路径列表,将多个pdf合并
pdf_path_list: 合并pdf路径列表
pdf_output_path: 输出pdf路径
'''
def pdf_merge_from_paths(pdf_path_list, pdf_output_path):
# 初始化一个PDF
file_merger = PdfFileMerger()
# 合并
for pdf in pdf_path_list:
file_merger.append(pdf, import_bookmarks=False) # 合并pdf文件
file_merger.write(pdf_output_path)
'''
通过多个pdf所在父目录,将多个pdf合并
pdf_dir: 合并pdf文件所在父目录
pdf_output_path: 输出pdf路径
'''
def pdf_merge_from_dir(pdf_dir, pdf_output_path):
# 初始化一个PDF
file_merger = PdfFileMerger()
# 读取PDF
pdf_lst = [f for f in os.listdir(pdf_dir) if f.endswith('.pdf')]
pdf_lst = [os.path.join(pdf_dir, filename) for filename in pdf_lst]
# 合并
for pdf in pdf_lst:
file_merger.append(pdf) # 合并pdf文件
file_merger.write(pdf_output_path)
'''
将指定页移动至目标页的前面或后面,直接修改原pdf
pdf_path: 修改pdf路径
aim_page_no: 目标页页码
move_page_no_list: 移动页页码列表
is_behind: 是否移动至目标页的后面
'''
def pdf_move_page_no_list(pdf_path, aim_page_no, move_page_no_list, is_behind=True):
# 初始化一个pdf
output = PdfFileWriter()
with open(pdf_path, 'rb') as in_pdf:
pdf_file = PdfFileReader(in_pdf)
delta = 0 if is_behind else 1
# 第1部分
for i in range(0, aim_page_no - delta):
output.addPage(pdf_file.getPage(i))
# 第2部分:移动页
for i in move_page_no_list:
output.addPage(pdf_file.getPage(i - 1))
# 第3部分:剩下的
for i in range(aim_page_no - delta, len(pdf_file.pages)):
if i + 1 not in move_page_no_list:
output.addPage(pdf_file.getPage(i))
# 写出pdf
with open(pdf_path, 'ab') as out_pdf:
output.write(out_pdf)
'''
将指定页旋转一定角度,直接修改原pdf
pdf_path: 修改pdf路径
rotate_page_no_list: 旋转页页码列表
rotate_angle: 旋转角度
'''
def pdf_rotate_page_no_list(pdf_path, rotate_page_no_list, rotate_angle=0):
# 初始化一个pdf
output = PdfFileWriter()
# 读取pdf
with open(pdf_path, 'rb') as in_pdf:
pdf_file = PdfFileReader(in_pdf)
# 遍历所有页
for i in range(len(pdf_file.pages)):
# 需要旋转页按照规定角度旋转,不需要旋转的页设定旋转角度为0
angle = 0
if i + 1 in rotate_page_no_list:
angle = rotate_angle
output.addPage(pdf_file.getPage(i).rotateClockwise(angle))
# 写出pdf
with open(pdf_path, 'ab') as out_pdf:
output.write(out_pdf)
'''
将pdf转为图片
'''
def covert2pic(doc, page_count, zoom):
if os.path.exists('.pdf'):
os.removedirs('.pdf')
os.mkdir('.pdf')
for pg in range(page_count):
page = doc.load_page(pg)
img_path = '.pdf/%s.png' % str(pg + 1)
trans = fitz.Matrix(int(zoom) / 100.0, int(zoom) / 100.0)
pm = page.get_pixmap(matrix=trans, alpha=False)
pm.save(img_path)
print(page)
doc.close()
'''
将图片转pdf
'''
def pic2pdf(pdf_output_path, page_count):
doc = fitz.open()
for pg in range(page_count):
img_path = '.pdf/%s.png' % str(pg + 1)
img_doc = fitz.open(img_path)
pdf_bytes = img_doc.convert_to_pdf()
img_pdf = fitz.open("pdf", pdf_bytes)
os.remove(img_path)
doc.insert_pdf(img_pdf)
if os.path.exists(pdf_output_path):
os.remove(pdf_output_path)
doc.save(pdf_output_path)
doc.close()
'''
对pdf大小进行缩放, 将原pdf转化为图片类型
pdf_input_path: 原pdf路径
pdf_output_path: 输出pdf路径
zoom: 缩放比例, 80, 100, 120等
'''
def pdf_zoom(pdf_input_path, pdf_output_path, zoom):
doc = fitz.open(pdf_input_path)
page_count = doc.page_count
covert2pic(doc, page_count, zoom)
pic2pdf(pdf_output_path, page_count)
os.removedirs('.pdf')
'''
对pdf进行加密
pdf_input_path: 原pdf路径
pdf_output_path: 输出pdf路径
password: 加密密码
'''
def pdf_encrypt(pdf_input_path, pdf_output_path, password):
# 初始化一个pdf
output = PdfFileWriter()
output.encrypt(password)
# 读取pdf
with open(pdf_input_path, 'rb') as in_pdf:
pdf_file = PdfFileReader(in_pdf)
# 遍历所有页
for page in pdf_file.pages:
output.addPage(page)
# 写出pdf
with open(pdf_output_path, 'ab') as out_pdf:
output.write(out_pdf)
利用python的PyPDF2和PyMuPDF库玩转PDF的提取、合并、旋转、缩放、加密的更多相关文章
- PyMuPDF库(处理PDF)
昨天在公司需要把一份PDF格式认证表转换为图片JPEG格式,所以在网上查询了一些与此相关的python库,最后看网上大多都是使用Wand和PyMuPDF,在安装了Wand库后,导入相应的模块后报错了, ...
- 利用python的requests和BeautifulSoup库爬取小说网站内容
1. 什么是Requests? Requests是用Python语言编写的,基于urllib3来改写的,采用Apache2 Licensed 来源协议的HTTP库. 它比urllib更加方便,可以节约 ...
- 利用python进行数据分析之pandas库的应用(二)
本节介绍Series和DataFrame中的数据的基本手段 重新索引 pandas对象的一个重要方法就是reindex,作用是创建一个适应新索引的新对象 >>> from panda ...
- 利用python进行数据分析之pandas库的应用(一)
一.pandas的数据结构介绍 Series Series是由一种类似于一维数组的对象,它由一组数据以及一组与之相关的数据索引构成.仅由一组数据可产生最简单的Series. obj=Series([4 ...
- 利用Python进行数据分析——数据规整化:清理、转换、合并、重塑(七)(1)
数据分析和建模方面的大量编程工作都是用在数据准备上的:载入.清理.转换以及重塑.有时候,存放在文件或数据库中的数据并不能满足你的数据处理应用的要求.很多人都选择使用通用编程语言(如Python.Per ...
- 利用Python进行数据分析 第8章 数据规整:聚合、合并和重塑.md
学习时间:2019/11/03 周日晚上23点半开始,计划1110学完 学习目标:Page218-249,共32页:目标6天学完(按每页20min.每天1小时/每天3页,需10天) 实际反馈:实际XX ...
- Python操作PDF-文本和图片提取(使用PyPDF2和PyMuPDF)
PDF文件格式 如今,可移植文档格式(PDF)属于最常用的数据格式.在1990年,PDF文档的结构由Adobe定义.PDF格式的思想是,对于通信过程中涉及的双方(创建者,作者或发送者以及接收者)而言, ...
- 利用python库twilio来免费发送短信
大家好,我是四毛,最近开通了个人公众号“用Python来编程”,欢迎大家“关注”,这样您就可以收到优质的文章了. 今天跟大家分享的主题是利用python库twilio来免费发送短信. 先放一张成品图 ...
- 利用Python进行数据分析——重要的Python库介绍
利用Python进行数据分析--重要的Python库介绍 一.NumPy 用于数组执行元素级计算及直接对数组执行数学运算 线性代数运算.傅里叶运算.随机数的生成 用于C/C++等代码的集成 二.pan ...
- 利用Python中的mock库对Python代码进行模拟测试
这篇文章主要介绍了利用Python中的mock库对Python代码进行模拟测试,mock库自从Python3.3依赖成为了Python的内置库,本文也等于介绍了该库的用法,需要的朋友可以参考下 ...
随机推荐
- DRF版本控制(源码分析)
DRF中版本控制的五种情况(源码分析) 在restful规范中要去,后端的API中需要体现版本. drf框架中支持5种版本的设置. 1. URL的GET参数传递(*) 示例: user/?versio ...
- 统计机器学习-Introduction to Statistical Learning-阅读笔记-CH4-Classification
response variable: quantitative qualitative / categorical methods for classification first predict t ...
- C# 控制系统任务栏的显示与隐藏
[DllImport("user32.dll")] public static extern int FindWindow(string lpClassName, string l ...
- Vue中关于keep-alive的使用
keep-alive是Vue提供的一个抽象组件,用来对组件进行缓存,从而节省性能,由于是一个抽象组件,所以在v页面渲染完毕后不会被渲染成一个DOM元素 当组件在keep-alive内被切换时组件的ac ...
- C# 手写识别方案整理
书写识别,网上的大佬们都有输出. 书写识别存在的2个问题: 直接拿官网的案例(将 Windows Ink 笔划识别为文本和形状 - Windows apps | Microsoft Learn),会发 ...
- C# 笔迹擦除8边形
擦除区域与橡皮大小不一致 测试反馈,擦除区域与真实的橡皮大小不一致: 上图中,橡皮显示是圆形的,但擦除效果是一个"8边形"区域. 找了一台8K屏,确实是能复现的: 看到这个诡异的8 ...
- Hugging News #0428: HuggingChat 来啦
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- 命令行编译和执行java代码
虽然现在IDE很强大又很智能,但是平常随意写点练手的代码的时候,直接在命令行中使用vim和java命令更为方便快捷,可以做到无鼠标纯键盘的操作. 首先保证将java相关指令添加到了环境变量中: 1.编 ...
- SQL Server数据库判断最近一次的备份执行结果
1 麻烦的地方 在SQL Server的官方文档里面可以看到备份和还原的表,但是这些表里面只能找到备份成功的相关信息,无法找到备份失败的记录,比如msdb.dbo.backupset.对于一些监控系统 ...
- 2021-03-06:go中,公共变量是协程安全吗?赋值操作是原子的吗?为什么?
2021-03-06:go中,公共变量是协程安全吗?赋值操作是原子的吗?为什么? 福哥答案2021-03-06: 这是面试中被问到的.实力有限,真正的答案还不知道.我的想法是a=1是原子操作,a=b不 ...