本文目录导读:
我来为您提供一个完整的Python拆分PDF案例,包含几种常见的拆分方式。
安装必要的库
pip install PyPDF2 # 或 pip install pypdf
基础拆分PDF案例
按页数拆分(每页一个PDF文件)
import os
from PyPDF2 import PdfReader, PdfWriter
def split_pdf_by_page(input_pdf_path, output_dir):
"""
将PDF按页拆分成多个单独的PDF文件
参数:
input_pdf_path: 输入的PDF文件路径
output_dir: 输出目录
"""
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 读取PDF文件
pdf_reader = PdfReader(input_pdf_path)
# 获取PDF总页数
total_pages = len(pdf_reader.pages)
print(f"PDF总页数: {total_pages}")
# 逐页拆分
for page_num in range(total_pages):
pdf_writer = PdfWriter()
pdf_writer.add_page(pdf_reader.pages[page_num])
# 生成输出文件名
output_filename = f"page_{page_num + 1}.pdf"
output_path = os.path.join(output_dir, output_filename)
# 保存PDF
with open(output_path, 'wb') as output_file:
pdf_writer.write(output_file)
print(f"已保存: {output_filename}")
print(f"拆分完成!共生成 {total_pages} 个文件")
# 使用示例
split_pdf_by_page("input.pdf", "output_pages")
按范围拆分(指定页码范围)
import os
from PyPDF2 import PdfReader, PdfWriter
def split_pdf_by_range(input_pdf_path, output_dir, ranges):
"""
按指定页码范围拆分PDF
参数:
input_pdf_path: 输入的PDF文件路径
output_dir: 输出目录
ranges: 页码范围列表,如 [(1, 3), (4, 6), (7, 10)]
"""
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 读取PDF文件
pdf_reader = PdfReader(input_pdf_path)
total_pages = len(pdf_reader.pages)
# 按指定范围拆分
for idx, (start_page, end_page) in enumerate(ranges, 1):
pdf_writer = PdfWriter()
# 检查页码范围是否有效
if start_page < 1 or end_page > total_pages:
print(f"警告: 范围 {start_page}-{end_page} 超出PDF页数限制")
continue
# 添加指定范围内的页面(注意:页码从0开始)
for page_num in range(start_page - 1, end_page):
pdf_writer.add_page(pdf_reader.pages[page_num])
# 生成输出文件名
output_filename = f"section_{idx}_pages_{start_page}-{end_page}.pdf"
output_path = os.path.join(output_dir, output_filename)
# 保存PDF
with open(output_path, 'wb') as output_file:
pdf_writer.write(output_file)
print(f"已保存: {output_filename} (共 {end_page - start_page + 1} 页)")
# 使用示例
ranges = [
(1, 3), # 第1-3页
(4, 6), # 第4-6页
(7, 10) # 第7-10页
]
split_pdf_by_range("input.pdf", "output_ranges", ranges)
按指定页数拆分(每N页一个文件)
import os
from PyPDF2 import PdfReader, PdfWriter
import math
def split_pdf_by_chunks(input_pdf_path, output_dir, pages_per_chunk=5):
"""
将PDF按指定页数拆分成多个文件
参数:
input_pdf_path: 输入的PDF文件路径
output_dir: 输出目录
pages_per_chunk: 每个文件包含的页数
"""
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 读取PDF文件
pdf_reader = PdfReader(input_pdf_path)
total_pages = len(pdf_reader.pages)
# 计算需要拆分的文件数量
num_chunks = math.ceil(total_pages / pages_per_chunk)
# 按块拆分
for chunk_num in range(num_chunks):
pdf_writer = PdfWriter()
# 计算当前块的页码范围
start_page = chunk_num * pages_per_chunk
end_page = min(start_page + pages_per_chunk, total_pages)
# 添加当前块的页面
for page_num in range(start_page, end_page):
pdf_writer.add_page(pdf_reader.pages[page_num])
# 生成输出文件名
chunk_size = end_page - start_page
output_filename = f"chunk_{chunk_num + 1}_pages_{start_page + 1}-{end_page}.pdf"
output_path = os.path.join(output_dir, output_filename)
# 保存PDF
with open(output_path, 'wb') as output_file:
pdf_writer.write(output_file)
print(f"已保存: {output_filename} (共 {chunk_size} 页)")
print(f"拆分完成!共生成 {num_chunks} 个文件")
# 使用示例
split_pdf_by_chunks("input.pdf", "output_chunks", pages_per_chunk=5)
交互式拆分工具
import os
from PyPDF2 import PdfReader, PdfWriter
class PDFSplitter:
def __init__(self, input_pdf_path):
self.input_pdf_path = input_pdf_path
self.pdf_reader = PdfReader(input_pdf_path)
self.total_pages = len(self.pdf_reader.pages)
print(f"PDF总页数: {self.total_pages}")
def split_by_page_numbers(self, page_numbers, output_dir="output"):
"""
按指定的页码列表拆分
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for idx, page_num in enumerate(page_numbers, 1):
if page_num < 1 or page_num > self.total_pages:
print(f"警告: 页码 {page_num} 无效")
continue
pdf_writer = PdfWriter()
pdf_writer.add_page(self.pdf_reader.pages[page_num - 1])
output_filename = f"page_{page_num}.pdf"
output_path = os.path.join(output_dir, output_filename)
with open(output_path, 'wb') as output_file:
pdf_writer.write(output_file)
print(f"已保存: {output_filename}")
def split_even_odd_pages(self, output_dir="output"):
"""
将奇数和偶数页分开
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 奇数页
odd_writer = PdfWriter()
for page_num in range(0, self.total_pages, 2):
odd_writer.add_page(self.pdf_reader.pages[page_num])
with open(os.path.join(output_dir, "odd_pages.pdf"), 'wb') as f:
odd_writer.write(f)
print("已保存: odd_pages.pdf")
# 偶数页
even_writer = PdfWriter()
for page_num in range(1, self.total_pages, 2):
even_writer.add_page(self.pdf_reader.pages[page_num])
with open(os.path.join(output_dir, "even_pages.pdf"), 'wb') as f:
even_writer.write(f)
print("已保存: even_pages.pdf")
# 使用示例
splitter = PDFSplitter("input.pdf")
# 拆分特定页码
splitter.split_by_page_numbers([1, 3, 5, 7], "specific_pages")
# 拆分奇偶页
splitter.split_even_odd_pages("odd_even_pages")
高级用法:批量处理多个PDF
import os
from PyPDF2 import PdfReader, PdfWriter
from pathlib import Path
def batch_split_pdfs(input_dir, output_dir, pages_per_file=1):
"""
批量处理目录中的所有PDF文件
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 获取所有PDF文件
pdf_files = list(Path(input_dir).glob("*.pdf"))
for pdf_file in pdf_files:
print(f"正在处理: {pdf_file.name}")
# 创建该PDF的输出子目录
pdf_output_dir = os.path.join(output_dir, pdf_file.stem)
if not os.path.exists(pdf_output_dir):
os.makedirs(pdf_output_dir)
# 读取PDF
pdf_reader = PdfReader(str(pdf_file))
total_pages = len(pdf_reader.pages)
# 按指定页数拆分
for page_num in range(0, total_pages, pages_per_file):
pdf_writer = PdfWriter()
# 添加页面
end_page = min(page_num + pages_per_file, total_pages)
for i in range(page_num, end_page):
pdf_writer.add_page(pdf_reader.pages[i])
# 保存文件
output_filename = f"{pdf_file.stem}_pages_{page_num+1}-{end_page}.pdf"
output_path = os.path.join(pdf_output_dir, output_filename)
with open(output_path, 'wb') as output_file:
pdf_writer.write(output_file)
print(f"完成: {pdf_file.name} -> {pdf_output_dir}")
# 使用示例
batch_split_pdfs("input_folder", "output_folder", pages_per_file=3)
错误处理和异常处理
import os
from PyPDF2 import PdfReader, PdfWriter
def safe_split_pdf(input_pdf_path, output_dir, **kwargs):
"""
带有错误处理的PDF拆分函数
"""
try:
# 检查文件是否存在
if not os.path.exists(input_pdf_path):
raise FileNotFoundError(f"文件不存在: {input_pdf_path}")
# 检查文件是否为PDF
if not input_pdf_path.lower().endswith('.pdf'):
raise ValueError("文件必须是PDF格式")
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 读取PDF
pdf_reader = PdfReader(input_pdf_path)
# 检查PDF是否加密
if pdf_reader.is_encrypted:
print("PDF文件已加密,尝试解密...")
try:
pdf_reader.decrypt('') # 尝试空密码
except:
raise Exception("无法解密PDF文件")
# 获取拆分方式并执行
split_method = kwargs.get('method', 'page')
if split_method == 'page':
# 逐页拆分
for page_num in range(len(pdf_reader.pages)):
writer = PdfWriter()
writer.add_page(pdf_reader.pages[page_num])
output_path = os.path.join(output_dir, f"page_{page_num+1}.pdf")
with open(output_path, 'wb') as f:
writer.write(f)
elif split_method == 'range':
# 范围拆分
ranges = kwargs.get('ranges', [(1, len(pdf_reader.pages))])
# ... 实现范围拆分逻辑
print("拆分成功完成!")
except FileNotFoundError as e:
print(f"文件错误: {e}")
except ValueError as e:
print(f"格式错误: {e}")
except Exception as e:
print(f"未知错误: {e}")
finally:
print("程序执行完毕")
# 使用示例
safe_split_pdf("input.pdf", "output_safe", method='page')
使用建议
-
选择合适的拆分方式:
- 逐页拆分:适合需要单独处理每一页的情况
- 范围拆分:适合有明确章节划分的文档
- 按页数拆分:适合需要控制文件大小的情况
-
文件命名:
- 建议包含页码信息,方便后续查找
- 可以使用原文件名作为前缀
-
性能优化:
- 对于大型PDF文件,建议分批处理
- 考虑使用异步处理提高效率
-
错误处理:
- 总是包含异常处理
- 检查文件是否存在和格式是否正确
这些示例涵盖了大多数PDF拆分需求,您可以根据具体需求选择合适的方案进行修改和使用。