使用Python打造高效的PDF文件管理应用

 更新时间:2024年12月19日 09:00:00   作者:winfredzhang  
在日常工作和学习中,我们经常需要处理大量PDF文件,本文将使用Python的wxPython和PyMuPDF库,开发一个强大且易用的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文件!

运行结果

以上就是使用Python打造高效的PDF文件管理应用的详细内容,更多关于Python PDF文件管理的资料请关注脚本之家其它相关文章!

相关文章

  • 基于Tensorflow批量数据的输入实现方式

    基于Tensorflow批量数据的输入实现方式

    今天小编就为大家分享一篇基于Tensorflow批量数据的输入实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • Python入门教程(二十一)Python的数组

    Python入门教程(二十一)Python的数组

    这篇文章主要介绍了Python入门教程(二十一)Python的数组,数组是一种特殊变量,数组可以在单个名称下保存多个值,我们可以通过引用索引号来访问这些值,需要的朋友可以参考下
    2023-04-04
  • 使用Python实现可恢复式多线程下载器

    使用Python实现可恢复式多线程下载器

    在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下
    2025-06-06
  • libreoffice python 操作word及excel文档的方法

    libreoffice python 操作word及excel文档的方法

    这篇文章主要介绍了libreoffice python 操作word及excel文档的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • 在PyCharm中使用Git和Gitee进行版本控制的操作流程

    在PyCharm中使用Git和Gitee进行版本控制的操作流程

    该文章详细介绍了在PyCharm中使用Git与Gitee进行版本控制的全过程,包括环境准备、基本操作、分支管理、拉取与克隆、以及避免冲突的IDE操作等步骤,设置Git路径和Gitee插件是基础,之后可以进行项目初始化、添加、推送等,需要的朋友可以参考下
    2026-05-05
  • 在FastAPI中改变响应状态码的两种方法

    在FastAPI中改变响应状态码的两种方法

    FastAPI,顾名思义,是一个快速、现代、高性能的web框架,用于用Python构建后端api,响应状态码是一个三位数,表示请求的结果,在这篇简明的基于示例的博文中,我将向你展示在FastAPI中更改响应状态代码的两种不同方法,需要的朋友可以参考下
    2025-02-02
  • 关于pygame自定义窗口创建及相关操作指南

    关于pygame自定义窗口创建及相关操作指南

    对于开发一个游戏来说,窗口的显示肯定是前提中的前提,对于pygame来说,只需要一小段代码就可以初始化窗口,下面这篇文章主要给大家介绍了关于pygame自定义窗口创建及相关操作的相关资料,需要的朋友可以参考下
    2022-07-07
  • Python对集合使用sort()排序报错AttributeError的解决方法

    Python对集合使用sort()排序报错AttributeError的解决方法

    这篇文章主要为大家详细介绍了 Python对集合使用sort()排序报错AttributeError的解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2025-11-11
  • python 读取.nii格式图像实例

    python 读取.nii格式图像实例

    这篇文章主要介绍了python 读取.nii格式图像实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • 一文教你PyCharm如何有效地添加源与库

    一文教你PyCharm如何有效地添加源与库

    在使用PyCharm进行Python开发的时候,很多时候我们需要添加库或者设置源,下面我们就来和大家详细介绍一下如何在PyCharm中添加源和库吧
    2025-03-03

最新评论