使用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文件!

运行结果

相关推荐
w20180010 小时前
新高考答题卡模板全套PDF可打印(语文数学英语等)
pdf·高考
奋斗的老史10 小时前
LibreOffice封装文档转 PDF 工具类
java·pdf
优化控制仿真模型10 小时前
【26年最新】新高考英语大纲词汇表3500个电子版PDF(含正序版、乱序版和默写版)
经验分享·pdf
Eiceblue11 小时前
使用 C# 高效替换 PDF 中的文本:全页、区域与正则匹配
visualstudio·pdf·c#
Upsy-Daisy11 小时前
AI Agent 项目学习笔记(十):文件操作、终端执行与 PDF 生成工具
笔记·学习·pdf
霸道流氓气质11 小时前
批量收集多源 URL 并异步转 PDF 打包下载的完整实现(Spring Boot + Feign + 异步任务)
windows·spring boot·pdf
开开心心_Every13 小时前
支持自定义名单的实用随机抽签工具
运维·服务器·pdf·电脑·excel·启发式算法·宽度优先
shuaiqinke1 天前
【分享】Master PDF Editor v5.9.98便携版 多功能PDF编辑工具
智能手机·pdf
jianwuhuang821 天前
Kimi怎么导出pdf
人工智能·chatgpt·pdf·deepseek·ai导出鸭
daanpdf1 天前
四六级翻译《中国文化概况》双语批注版pdf百度网盘
pdf