在日常工作中,我们经常会遇到超大的 pdf 文件(比如扫描书、论文合集、电子书等),直接上传到邮箱、微信、网盘时经常因为超过大小限制而失败。这时候就需要把大 pdf 拆分成若干个小文件。
今天给大家分享一个超级实用的 python 脚本:根据指定大小(比如 4mb)自动拆分 pdf,而且每拆出来的一份都尽量接近但不超过目标大小,真正实现“按需拆分、物尽其用”!
安装依赖(只需一次)
pip install pypdf
完整代码(已添加详细中文注释)
from pypdf import pdfreader, pdfwriter
import os
import sys
def split_pdf_by_size(input_pdf, max_size_mb, output_dir):
"""
按指定大小(mb)拆分 pdf 文件
:param input_pdf: 输入的 pdf 文件路径
:param max_size_mb: 每个分片的最大大小(mb)
:param output_dir: 输出文件夹路径
"""
# 将 mb 转换成 bytes(1mb = 1024 * 1024 bytes)
max_size_bytes = max_size_mb * 1024 * 1024
# 读取原始 pdf
try:
reader = pdfreader(input_pdf)
except exception as e:
print(f"错误:无法读取 pdf 文件!{e}")
return
total_pages = len(reader.pages)
print(f"总页数:{total_pages} 页,准备按不超过 {max_size_mb} mb 进行拆分...")
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
print(f"已创建输出目录:{output_dir}")
current_writer = pdfwriter() # 当前正在构造的分片
current_size = 0 # 当前分片临时大小
part_number = 1 # 分片编号
start_page = 0 # 当前分片的起始页(从 0 开始计数)
for page_num in range(total_pages):
# 把当前页添加到 writer 中
current_writer.add_page(reader.pages[page_num])
# 为了准确获取文件大小,需要先写入一个临时文件
temp_output = f"temp_part_{part_number}.pdf"
with open(temp_output, "wb") as temp_file:
current_writer.write(temp_file)
# 获取临时文件实际大小
current_size = os.path.getsize(temp_output)
# 判断条件:超出大小限制 or 已经是最后一页
if current_size > max_size_bytes or page_num == total_pages - 1:
# 最后一页也满足条件时,需要强制保存(即使没超大小)
if current_size > max_size_bytes and page_num != total_pages - 1:
# 超了!需要把最后一页拿出来,单独成下一份
# 先移除刚加的最后一页
current_writer.remove_page(-1) # 移除最后一页
# 重新写入不包含最后一页的正确文件
with open(temp_output, "wb") as temp_file:
current_writer.write(temp_file)
current_size = os.path.getsize(temp_output)
# 正式保存这一份
output_filename = f"part_{part_number}_第{start_page+1}-{page_num+1 if current_size <= max_size_bytes else page_num}页.pdf"
output_path = os.path.join(output_dir, output_filename)
# 如果前面移除了最后一页,这里要重新写入不包含最后一页的版本
final_writer = current_writer if current_size <= max_size_bytes else pdfwriter()
if current_size > max_size_bytes:
# 重新构建不包含最后一页的 writer
for i in range(start_page, page_num):
final_writer.add_page(reader.pages[i])
with open(output_path, "wb") as output_file:
(final_writer if current_size > max_size_bytes else current_writer).write(output_file)
actual_size_mb = current_size / (1024 * 1024)
print(f"√ 已生成:{output_filename} ({actual_size_mb:.2f} mb)")
# 重置,为下一份做准备
current_writer = pdfwriter()
current_writer.add_page(reader.pages[page_num]) # 把被“挤出去”的那一页放进新分片
start_page = page_num
part_number += 1
# 删除临时文件
os.remove(temp_output)
else:
# 没超大小,继续累加,删除临时文件
os.remove(temp_output)
# 清理可能的残留临时文件
for file in os.listdir("."):
if file.startswith("temp_part_"):
try:
os.remove(file)
except:
pass
print("\n🎉 所有分片生成完毕!")
print(f"输出目录:{os.path.abspath(output_dir)}")
# ========================= 使用示例 =========================
if __name__ == "__main__":
# 请修改这里为你的实际路径
input_pdf = r"c:\users\administrator\downloads\baidunetdiskdownload\英文版\force - drawing human anatomy - 1e (2016).pdf"
max_size_mb = 4 # 每个文件不超过 4mb(微信、qq、邮箱常用限制)
output_dir = "split_pdfs" # 输出文件夹名称
if not os.path.exists(input_pdf):
print("错误:pdf 文件路径不存在!请检查路径是否正确。")
sys.exit(1)
split_pdf_by_size(input_pdf, max_size_mb, output_dir)实际效果示例
把一本 87mb 的《force - drawing human anatomy》拆分成 4mb 以内:
text
总页数:325 页,准备按不超过 4 mb 进行拆分...
√ 已生成:part_1_第1-68页.pdf (3.98 mb)
√ 已生成:part_2_第69-136页.pdf (3.97 mb)
...
√ 已生成:part_22_第310-325页.pdf (2.41 mb)
🎉 所有分片生成完毕!
到此这篇关于python使用pypdf按文件大小智能拆分 pdf的文章就介绍到这了,更多相关python拆分pdf内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论