使用Python打造高效的PDF文件管理应用(合并以及分割)

在日常工作和学习中,我们经常需要处理大量PDF文件。手动合并、分割PDF不仅耗时,还容易出错。今天,我们将使用Python的wxPython和PyMuPDF库,开发一个强大且易用的PDF文件管理工具。

C:\pythoncode\new\mergeAndsplitPdf.py

所有代码

python 复制代码
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文件将按文件名自动排序显示在列表中。

python 复制代码
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"按钮
  • 选择合并后文件的保存位置

核心合并逻辑如下:

python 复制代码
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文件

分割实现代码:

python 复制代码
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)

使用指南

环境准备

安装必要的依赖:

bash 复制代码
pip install wxPython pymupdf

运行应用

  1. 克隆项目代码
  2. 执行 python mergeAndsplitPdf.py
  3. 选择文件夹,开始管理您的PDF文件!

运行结果

相关推荐
葡萄城技术团队1 小时前
SpreadJS 中“打印”和“导出 PDF”到底该选哪个?
pdf
优化控制仿真模型2 小时前
2025年12月英语六级真题及答案解析完整版(第一、二、三套全PDF)
经验分享·pdf
芒果大胖砸2 小时前
uniapp 在h5中预览pdf hybrid方法
pdf·uni-app
大傻^2 小时前
Spring AI Alibaba 文档智能处理:PDF、Markdown知识入库全链路
java·人工智能·spring·pdf·知识图谱·springai·springaialibaba
zzh940775 小时前
2026年AI文件上传功能实战:聚合站处理图片、PDF、PPT全指南
人工智能·pdf·powerpoint
鹏大师运维1 天前
统信UOS上使用WPS PDF独立版
linux·运维·windows·pdf·wps·统信uos·wine
ttod_qzstudio1 天前
PDF 生成与本地文件操作:浏览器原生文件系统 API 实战
pdf
asdzx671 天前
使用 Python 比较 PDF 文件差异(简单方法)
python·pdf·文档比较
开开心心就好1 天前
免费轻量级PDF阅读器,打开速度快
windows·计算机视觉·visualstudio·pdf·计算机外设·excel·myeclipse
A_nanda1 天前
一款前端PDF插件
前端·学习·pdf·vue