使用Python打造高效的PDF文件管理应用(合并以及分割)
在日常工作和学习中,我们经常需要处理大量PDF文件。手动合并、分割PDF不仅耗时,还容易出错。今天,我们将使用Python的wxPython和PyMuPDF库,开发一个强大且易用的PDF文件管理工具。
C:\pythoncode\new\mergeAndsplitPdf.py
所有代码
import os
import wx
import fitz # PyMuPDF
class PDFManagerApp(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='PDF文件管理器')
# 主面板
panel = wx.Panel(self)
# 垂直布局
main_sizer = wx.BoxSizer(wx.VERTICAL)
# 文件夹选择行
folder_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.folder_path = wx.TextCtrl(panel, style=wx.TE_READONLY)
select_folder_btn = wx.Button(panel, label='选择文件夹')
select_folder_btn.Bind(wx.EVT_BUTTON, self.on_select_folder)
folder_sizer.Add(self.folder_path, proportion=1, flag=wx.EXPAND|wx.ALL, border=5)
folder_sizer.Add(select_folder_btn, flag=wx.ALL, border=5)
# PDF文件列表
self.pdf_list = wx.ListBox(panel, style=wx.LB_MULTIPLE)
# 操作按钮行
btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
merge_btn = wx.Button(panel, label='合并PDF')
split_btn = wx.Button(panel, label='分割PDF')
merge_btn.Bind(wx.EVT_BUTTON, self.merge_pdfs)
split_btn.Bind(wx.EVT_BUTTON, self.split_pdfs)
btn_sizer.Add(merge_btn, flag=wx.ALL, border=5)
btn_sizer.Add(split_btn, flag=wx.ALL, border=5)
# 将所有部件添加到主布局
main_sizer.Add(folder_sizer, flag=wx.EXPAND)
main_sizer.Add(self.pdf_list, proportion=1, flag=wx.EXPAND|wx.ALL, border=5)
main_sizer.Add(btn_sizer, flag=wx.CENTER)
panel.SetSizer(main_sizer)
# 设置窗口大小和居中
self.SetSize((500, 600))
self.Centre()
def on_select_folder(self, event):
"""选择文件夹并列出PDF文件"""
with wx.DirDialog(self, "选择包含PDF文件的文件夹") as dlg:
if dlg.ShowModal() == wx.ID_OK:
folder_path = dlg.GetPath()
self.folder_path.SetValue(folder_path)
# 清空并重新加载PDF文件列表
self.pdf_list.Clear()
# 获取文件夹中的所有PDF文件
pdf_files = [f for f in os.listdir(folder_path) if f.lower().endswith('.pdf')]
pdf_files.sort() # 按文件名排序
# 添加到列表框
for pdf in pdf_files:
self.pdf_list.Append(pdf)
def merge_pdfs(self, event):
"""合并选中的PDF文件"""
# 获取选中的文件索引
selections = self.pdf_list.GetSelections()
if not selections:
wx.MessageBox('请先选择要合并的PDF文件', '提示', wx.OK | wx.ICON_INFORMATION)
return
# 准备保存文件对话框
with wx.FileDialog(self, "保存合并后的PDF", wildcard="PDF files (*.pdf)|*.pdf",
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as saveDialog:
if saveDialog.ShowModal() == wx.ID_OK:
output_path = saveDialog.GetPath()
# 获取文件夹路径和选中的文件名
folder_path = self.folder_path.GetValue()
selected_files = [self.pdf_list.GetString(idx) for idx in selections]
try:
# 打开所有PDF
pdf_docs = [fitz.open(os.path.join(folder_path, f)) for f in selected_files]
# 创建一个新的PDF文档
merged_pdf = fitz.open()
# 逐个合并文档
for doc in pdf_docs:
merged_pdf.insert_pdf(doc)
# 保存合并后的PDF
merged_pdf.save(output_path)
merged_pdf.close()
# 关闭所有打开的文档
for doc in pdf_docs:
doc.close()
wx.MessageBox('PDF文件合并成功!', '成功', wx.OK | wx.ICON_INFORMATION)
except Exception as e:
wx.MessageBox(f'合并PDF时发生错误:{str(e)}', '错误', wx.OK | wx.ICON_ERROR)
def split_pdfs(self, event):
"""将选中的PDF文件按页分割"""
# 获取选中的文件索引
selections = self.pdf_list.GetSelections()
if not selections:
wx.MessageBox('请先选择要分割的PDF文件', '提示', wx.OK | wx.ICON_INFORMATION)
return
# 选择输出文件夹
with wx.DirDialog(self, "选择PDF页面输出文件夹") as dlg:
if dlg.ShowModal() == wx.ID_OK:
output_folder = dlg.GetPath()
# 获取文件夹路径和选中的文件名
folder_path = self.folder_path.GetValue()
selected_files = [self.pdf_list.GetString(idx) for idx in selections]
try:
# 处理每个选中的PDF文件
for filename in selected_files:
input_path = os.path.join(folder_path, filename)
pdf_doc = fitz.open(input_path)
# 为每一页创建单独的PDF
for page_num in range(len(pdf_doc)):
# 创建只包含当前页的新PDF
single_page_pdf = fitz.open()
single_page_pdf.insert_pdf(pdf_doc, from_page=page_num, to_page=page_num)
# 生成输出文件名
base_name = os.path.splitext(filename)[0]
output_filename = f"{base_name}_page_{page_num+1}.pdf"
output_path = os.path.join(output_folder, output_filename)
# 保存单页PDF
single_page_pdf.save(output_path)
single_page_pdf.close()
pdf_doc.close()
wx.MessageBox('PDF文件已成功分割!', '成功', wx.OK | wx.ICON_INFORMATION)
except Exception as e:
wx.MessageBox(f'分割PDF时发生错误:{str(e)}', '错误', wx.OK | wx.ICON_ERROR)
def main():
app = wx.App()
frame = PDFManagerApp()
frame.Show()
app.MainLoop()
if __name__ == '__main__':
main()
项目背景
随着数字文档的普及,PDF已成为最常用的文档格式之一。然而,对PDF文件的管理和处理往往让人感到繁琐。市面上的PDF工具要么功能单一,要么操作复杂,价格高昂。
技术选型
我们选择了以下技术栈:
- wxPython:跨平台的GUI框架,提供原生的用户界面体验
- PyMuPDF:高性能的PDF处理库,支持文档合并、分割等操作
- Python:简洁且强大的编程语言
核心功能
1. 文件夹选择与PDF列表
应用程序提供了直观的文件夹选择功能。用户只需点击"选择文件夹"按钮,即可浏览并选择包含PDF文件的目录。所有PDF文件将按文件名自动排序显示在列表中。
def on_select_folder(self, event):
with wx.DirDialog(self, "选择包含PDF文件的文件夹") as dlg:
if dlg.ShowModal() == wx.ID_OK:
folder_path = dlg.GetPath()
# 获取并排序PDF文件列表
pdf_files = [f for f in os.listdir(folder_path) if f.lower().endswith('.pdf')]
pdf_files.sort()
2. PDF文件合并
再也不用担心手动合并多个PDF文件了!我们的应用支持多文件选择和快速合并。用户可以:
- 选择多个PDF文件
- 点击"合并PDF"按钮
- 选择合并后文件的保存位置
核心合并逻辑如下:
def merge_pdfs(self, event):
# 获取选中的文件
selected_files = [self.pdf_list.GetString(idx) for idx in selections]
# 使用PyMuPDF合并PDF
pdf_docs = [fitz.open(os.path.join(folder_path, f)) for f in selected_files]
merged_pdf = fitz.open()
for doc in pdf_docs:
merged_pdf.insert_pdf(doc)
merged_pdf.save(output_path)
3. PDF文件分割
需要将一个PDF文件按页拆分?轻松搞定!
- 选择要分割的PDF文件
- 点击"分割PDF"按钮
- 选择输出文件夹
- 应用程序将自动为每一页生成独立的PDF文件
分割实现代码:
def split_pdfs(self, event):
for filename in selected_files:
pdf_doc = fitz.open(input_path)
for page_num in range(len(pdf_doc)):
# 创建单页PDF
single_page_pdf = fitz.open()
single_page_pdf.insert_pdf(pdf_doc, from_page=page_num, to_page=page_num)
# 保存单页PDF
output_filename = f"{base_name}_page_{page_num+1}.pdf"
single_page_pdf.save(output_path)
使用指南
环境准备
安装必要的依赖:
pip install wxPython pymupdf
运行应用
- 克隆项目代码
- 执行
python mergeAndsplitPdf.py
- 选择文件夹,开始管理您的PDF文件!