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

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

所有代码

import os
import wx
import fitz  # PyMuPDFclass 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:# 打开所有PDFpdf_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)# 保存合并后的PDFmerged_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)# 为每一页创建单独的PDFfor page_num in range(len(pdf_doc)):# 创建只包含当前页的新PDFsingle_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)# 保存单页PDFsingle_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合并PDFpdf_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)):# 创建单页PDFsingle_page_pdf = fitz.open()single_page_pdf.insert_pdf(pdf_doc, from_page=page_num, to_page=page_num)# 保存单页PDFoutput_filename = f"{base_name}_page_{page_num+1}.pdf"single_page_pdf.save(output_path)

使用指南

环境准备

安装必要的依赖:

pip install wxPython pymupdf

运行应用

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

运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/889992.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言程序设计——入门】C语言程序开发环境(头歌实践教学平台习题)【合集】

目录&#x1f60b; <第1关&#xff1a;程序改错> 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果&#xff1a; <第2关&#xff1a;scanf 函数> 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果&#xff1a; <第1关&a…

皮肤伤口分割数据集labelme格式248张5类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;284 标注数量(json文件个数)&#xff1a;284 标注类别数&#xff1a;5 标注类别名称:["bruises","burns","cu…

JVM系列之内存区域

每日禅语 有一位年轻和尚&#xff0c;一心求道&#xff0c;多年苦修参禅&#xff0c;但一直没有开悟。有一天&#xff0c;他打听到深山中有一古寺&#xff0c;住持和尚修炼圆通&#xff0c;是得道高僧。于是&#xff0c;年轻和尚打点行装&#xff0c;跋山涉水&#xff0c;千辛万…

大腾智能CAD:国产云原生三维设计新选择

在快速发展的工业设计领域&#xff0c;CAD软件已成为不可或缺的核心工具。它通过强大的建模、分析、优化等功能&#xff0c;不仅显著提升了设计效率与精度&#xff0c;还促进了设计思维的创新与拓展&#xff0c;为产品从概念构想到实体制造的全过程提供了强有力的技术支持。然而…

leetcode 3195.包含所有1的最小矩形面积I

1.题目要求: 2.解题步骤: class Solution { public:int minimumArea(vector<vector<int>>& grid) {//设置二维数组deque<deque<int>> row_distance;for(int i 0;i < grid.size();i){//遍历数组&#xff0c;把每行头部1的小标和尾部1的下标代…

搭建Tomcat(三)---重写service方法

目录 引入 一、在Java中创建一个新的空项目&#xff08;初步搭建&#xff09; 问题&#xff1a; 要求在tomcat软件包下的MyTomcat类中编写main文件&#xff0c;实现在MyTomcat中扫描myweb软件包中的所有Java文件&#xff0c;并返回“WebServlet(url"myFirst")”中…

Linux介绍与安装CentOS 7操作系统

什么是操作系统 操作系统&#xff0c;英⽂名称 Operating System&#xff0c;简称 OS&#xff0c;是计算机系统中必不 可少的基础系统软件&#xff0c;它是 应⽤程序运⾏以及⽤户操作必备的基础环境 ⽀撑&#xff0c;是计算机系统的核⼼。 操作系统的作⽤是管理和控制计算机系…

【Linux】深入理解进程信号机制:信号的产生、捕获与阻塞

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 时间不语&#xff0c;却回答了所有问题 目录 &#x1f4da;前言 &#x1f4da;一、信号的本质 &#x1f4d6;1.异步通信 &#x1f4d6;2.信…

【西门子PLC.博途】——面向对象编程及输入输出映射FC块

当我们做面向对象编程的时候&#xff0c;需要用到输入输出的映射。这样建立的变量就能够被复用&#xff0c;从而最大化利用了我们建立的udt对象。 下面就来讲讲映射是什么。 从本质上来说&#xff0c;映射就是拿实际物理对象对应程序虚拟对象&#xff0c;假设程序对象是I0.0&…

MySQL索引的理解

MySQL与磁盘的交互 根据冯诺依曼结构体系&#xff0c;我们知道我们任何上层的应用想要去访问磁盘就必须要通过内存来访问&#xff0c;MySQL作为一款储存数据的服务&#xff0c;肯定是很多时间要用来访问磁盘。而大量访问磁盘一定会影响运行效率的在innoDB的存储引擎下为了减少…

分布式全文检索引擎ElasticSearch-数据的写入存储底层原理

一、数据写入的核心流程 当向 ES 索引写入数据时&#xff0c;整体流程如下&#xff1a; 1、客户端发送写入请求 客户端向 ES 集群的任意节点&#xff08;称为协调节点&#xff0c;Coordinating Node&#xff09;发送一个写入请求&#xff0c;比如 index&#xff08;插入或更…

Maven 生命周期

文章目录 Maven 生命周期- Clean 生命周期- Build 生命周期- Site 生命周期 Maven 生命周期 Maven 有以下三个标准的生命周期&#xff1a; Clean 生命周期&#xff1a; clean&#xff1a;删除目标目录中的编译输出文件。这通常是在构建之前执行的&#xff0c;以确保项目从一个…

Android Studio AI助手---Gemini

从金丝雀频道下载最新版 Android Studio&#xff0c;以利用所有这些新功能&#xff0c;并继续阅读以了解新增内容。 Gemini 现在可以编写、重构和记录 Android 代码 Gemini 不仅仅是提供指导。它可以编辑您的代码&#xff0c;帮助您快速从原型转向实现&#xff0c;实现常见的…

#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍04-盲SQL注入(Blind SQL Injection)

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

Scala 的迭代器

迭代器定义&#xff1a;迭代器不是一种集合&#xff0c;它是一种用于访问集合的方法。 迭代器需要通过集合对应的迭代器调用迭代器的方法来访问。 支持函数式编程风格&#xff0c;便于链式操作。 创建一个迭代器&#xff0c;相关代码如下&#xff1a; object Test {def mai…

底层理论基础(单片机)

计算机基础 IO逻辑 计算机系统中的高低电平逻辑1和0&#xff0c;数据在计算机中的存储、传输、运算都是以二进制形式进行的。 数据的传输通过总线真正传递的是电信号&#xff0c;高低电平&#xff08;0、1&#xff09;。运算在电路中进行&#xff0c;集成电路中运算。 计算机的…

B站bilibili视频转文字字幕下载方法

本文将讲述介绍一种使用本地工具如何快速的下载B站的字幕为本地文本文件的方法。 通常获取B站字幕需要在浏览器中安装第三方插件&#xff0c;通过插件获取字幕。随着大模型&#xff0c;生成式AI&#xff0c;ChatGPT的应用&#xff0c;B站也提供了AI小助手对视频的内容进行总结…

ROS+PX4+Gazebo仿真环境配置全流程解析

上一期文章介绍了我们即将发布的仿真平台&#xff0c;并提到后续需要在Ubuntu系统上进行PX4软件在环仿真。本期文章将为大家详细介绍如何配置Ubuntu环境以及安装ROS和PX4仿真环境。具体配置包括&#xff1a;Ubuntu 20.04 ROS Noetic PX4 Python3。 需要注意的是&#xff0c…

基础入门-APP应用微信小程序原生态开发H5+Vue技术WEB封装打包反编译抓包点

知识点&#xff1a; 1、基础入门-APP应用-开发架构安全问题 2、基础入门-小程序应用-开发架构安全问题 通用&#xff1a; 1、反编译-得到源码-源码提取资产&#xff08;泄漏的配置信息&#xff09;-安全测试 2、抓包-资产-安全测试 一、演示案例-移动App-开发架构-原生&H…

Elasticsearch:使用 Open Crawler 和 semantic text 进行语义搜索

作者&#xff1a;来自 Elastic Jeff Vestal 了解如何使用开放爬虫与 semantic text 字段结合来轻松抓取网站并使其可进行语义搜索。 Elastic Open Crawler 演练 我们在这里要做什么&#xff1f; Elastic Open Crawler 是 Elastic 托管爬虫的后继者。 Semantic text 是 Elasti…