基于Python的PDF批量转化工具

一、开发的缘由

最近,有网友想让我帮他做一个批量把png, docx, doc, pptx, ppt, xls, xlsx文件转化为PDF格式的软件,完全傻瓜式的操作,把文件拖进去就进行转化那种,简单实用。之前,有过一个vbs的文件,可以转docx, xlsx, pptx,但是对于图片无能为力,为了完成这个任务还是要请出Python这个强大的利器。

二、开发的过程

1. 为了能够实现拖动的功能,我首先想到要设计一个UI界面,然后可以直接接受拖动的文件。另外,因为是批量操作,需要一定的时间来完成操作,最好是可以添加一个进度条,让用户知道是否已经完成了转化。

2. 软件的外观本来想着简化,但是想着得让用户看到转化文件名的路径和文件名,避免转错了,同时还得可以删除选中的条目。所以我就设计了一个listbox控件,一个删除按钮、一个生成文件按钮,还有一个导入文件的按钮,为的是不习惯进行拖动的用户设计。

3. 由于tkinter是系统自带的,所以可以使软件更小一点。另外,读取图片用到PIL这个模块,而其它如docx, pptx, xlsx文件的转化则需要依靠win32com.client这个模块。

4. 我尝试了多种方法来执行拖动的功能,但是打包以后发现无法实现,于时最终采用了windnd这个模块,为了防止拖动时程序假死,我还用了多线程的方法。

三、成品介绍

我们这个软件最终起名为PDF批量转化器,它是一款支持多种文件格式批量转换为PDF格式的工具,特别适用于Word、Excel、PowerPoint、图片文件的转换。它提供了一个直观的界面,允许用户通过拖拽文件或通过文件选择器导入文件,支持多线程处理,提升了文件转换的效率。主要特点有:

多文件格式支持:支持转换Word、Excel、PowerPoint和图片文件到PDF格式。
拖拽功能:用户可以直接将文件拖拽至程序界面,简化操作流程。
进度条显示:转换过程中,进度条实时显示,用户可以了解转换的进度。
批量处理:一次可以处理多个文件,节省时间和操作精力。
文件管理:提供文件导入、删除等操作,帮助用户管理文件列表。
后台处理:采用多线程方式处理文件转换,避免界面卡顿。

此外,为了增强用户体验,我们还增加了二个小功能,一是把生成的PDF文件统一放在一个PDF文件夹里面,另外就是如果发现同名PDF文件,就自动跳过这个文件,从而避免重复操作。

四、程序源码

为了帮助大家,特地放上这个源码,供大家调试使用,里面有丰富的知识点,认真学习或许还会有意想不到的收获。

import tkinter as tk
from tkinter import messagebox,ttk,filedialog
from PIL import Image
import os
import windnd
from threading import Thread
import win32com.client  # pywin32 for Word, Excel, PPT processing
class WordProcessorApp:def __init__(self, root):self.root = rootself.root.title("PDF批量转化器 V1.2 Gordon ")self.root.attributes("-topmost", True)windnd.hook_dropfiles(self.root,func=self.drop_files)self.file_list = []self.create_widgets()os.makedirs("PDF文件", exist_ok=True)self.path = "PDF文件"def create_widgets(self):self.frame = tk.Frame()self.frame.pack()# 使用Combobox代替Checkbuttonself.label = tk.Label(self.frame, text = "请把文件拖拽到本界面上,然后点生成文件", font=("宋体", 11), width=38)self.label.pack(side=tk.LEFT)self.file_listbox = tk.Listbox(self.root,width=48,font = ("宋体",11))self.file_listbox.pack()self.import_button = tk.Button(self.frame, text="导入文件",font = ("宋体",11), command=self.import_file)self.import_button.pack(sid=tk.LEFT)frame1 = tk.Frame()frame1.pack()# Progress barself.progress_bar = ttk.Progressbar(frame1, orient="horizontal", length=400, mode="determinate")self.progress_bar.pack()self.delete_button = tk.Button(frame1, text="删除选中", font=("宋体", 11), command=self.delete_selected)self.delete_button.pack(side=tk.LEFT,padx = 30)self.generate_button = tk.Button(frame1, text="生成文件",font = ("宋体",11), command=self.generate_files)self.generate_button.pack(side=tk.LEFT,padx = 30)self.quit_button = tk.Button(frame1, text="退出程序",font = ("宋体",11), command=self.ui_quit)self.quit_button.pack(side=tk.LEFT,padx = 30)def ui_quit(self):self.root.destroy()def delete_selected(self):selected_indices = self.file_listbox.curselection()if not selected_indices:messagebox.showwarning("Warning", "请先选择要删除的文件!")returnfor index in reversed(selected_indices):self.file_listbox.delete(index)del self.file_list[index]def thread_it(self,func,*args):self.thread1=Thread(target=func,args=args)self.thread1.setDaemon(True) self.thread1.start()#---------------定义一个drop_files,然后用thread_it-------------def drop_files(self,files):self.thread_it(self.drop_files2,files)#--------------找开文件对话框的代码--------------def drop_files2(self,files=None):for file_path in files:file_path=file_path.decode("gbk") file_path = file_path.replace('\\', '/')if file_path not in self.file_listbox.get(0, tk.END):# 将文件路径添加到Listbox中self.file_listbox.insert(tk.END, file_path)self.file_list.append(file_path)returndef import_file(self):filename = filedialog.askopenfilename(filetypes=[("Word files", "*.docx")])if filename:self.file_list.append(filename)self.file_listbox.insert(tk.END, filename)def generate_files(self):if not self.file_list:messagebox.showerror("Error", "文件列表为空!")return#         for filename in self.file_list:else:self.convert_files()def process_file(self, file_path, convert_func, update_progress):path_without_extension = os.path.splitext(os.path.basename(file_path))[0]pdf_path = os.path.join(os.path.abspath(self.path), path_without_extension + ".pdf")# 检查目标文件是否已经存在if os.path.exists(pdf_path):print(f"文件 {pdf_path} 已经存在,跳过转换。")return False  # 文件已经存在,不进行转换# 如果文件不存在,继续转换if convert_func(file_path, pdf_path, update_progress):return Truereturn Falsedef convert_files(self):files = self.file_listbox.get(0, tk.END)  # 获取列表框中的所有文件total_files = len(files)processed_files = 0# 重置进度条self.progress_bar['maximum'] = total_files  # 设置进度条最大值self.progress_bar['value'] = 0  # 重置进度条当前值为0self.label.config(text="正在处理中...")  # 更新提示标签def update_progress():nonlocal processed_filesprocessed_files += 1self.progress_bar['value'] = processed_filesself.root.update_idletasks()  # 更新UI# 处理文件excel_count = 0word_count = 0ppt_count = 0img_count = 0for file_path in files:if file_path.lower().endswith((".xls", ".xlsx")):  # Excel fileif self.process_file(file_path, self.excel_to_pdf, update_progress):excel_count += 1elif file_path.lower().endswith((".docx", ".doc")):  # Word fileif self.process_file(file_path, self.word_to_pdf, update_progress):word_count += 1elif file_path.lower().endswith((".pptx", ".ppt")):  # PowerPoint fileif self.process_file(file_path, self.ppt_to_pdf, update_progress):ppt_count += 1elif file_path.lower().endswith((".jpg", ".png")):  # Image fileif self.process_file(file_path, self.img_to_pdf, update_progress):img_count += 1# 更新处理结果self.label.config(text=f"转化{excel_count}个Excel,{word_count}个Word,"f"{ppt_count}个PPT,{img_count}个图 ")def excel_to_pdf(self, input_file, output_file, update_progress):try:excel = win32com.client.Dispatch("Excel.Application")excel.Visible = Falsewb = excel.Workbooks.Open(input_file)wb.ExportAsFixedFormat(0, output_file)wb.Close()excel.Quit()update_progress()  # Update progress after conversionreturn Trueexcept Exception as e:print(f"Error converting Excel to PDF: {e}")return Falsedef word_to_pdf(self, input_file, output_file, update_progress):try:word = win32com.client.Dispatch("Word.Application")doc = word.Documents.Open(input_file)doc.SaveAs(output_file, FileFormat=17)  # FileFormat=17 for PDFdoc.Close()word.Quit()update_progress()  # Update progress after conversionreturn Trueexcept Exception as e:print(f"Error converting Word to PDF: {e}")return Falsedef ppt_to_pdf(self, input_file, output_file, update_progress):try:ppt = win32com.client.Dispatch("PowerPoint.Application")ppt.Visible = Falsepresentation = ppt.Presentations.Open(input_file)presentation.SaveAs(output_file, 32)  # 32 for PDF formatpresentation.Close()ppt.Quit()update_progress()  # Update progress after conversionreturn Trueexcept Exception as e:print(f"Error converting PowerPoint to PDF: {e}")return Falsedef img_to_pdf(self, input_file, output_file, update_progress):try:img = Image.open(input_file)img.save(output_file, "PDF", resolution=100.0)update_progress()  # Update progress after conversionreturn Trueexcept Exception as e:print(f"Error converting image to PDF: {e}")return Falseif __name__ == "__main__":root = tk.Tk()app = WordProcessorApp(root)root.mainloop()

五、注意事项

1. 文件类型限制:仅支持特定文件类型的转换,如:doc, docx, ppt, pptx, xls, xlsx和常见图片格式png,jpg格式,其他文件类型暂不适用。

2. 软件依赖:需要安装pywin32和Pillow库,且转换Word、Excel、PowerPoint等文件格式时依赖安装Microsoft Office。

3. 路径问题:确保文件路径不包含特殊字符,否则可能导致路径无法识别。

4. 文件覆盖:如果转换后的PDF文件已存在,程序会跳过该文件以避免覆盖。

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

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

相关文章

模型案例:| 手机识别模型!

导读 2023年以ChatGPT为代表的大语言模型横空出世,它的出现标志着自然语言处理领域取得了重大突破。它在文本生成、对话系统和语言理解等方面展现出了强大的能力,为人工智能技术的发展开辟了新的可能性。同时,人工智能技术正在进入各种应用领…

【Copilot 】TAB keybinding not working on JetBrains Client

pycharm ssh 远程到ubuntu24.04 发现tab就是tab,无法输出copilot给出的自动补全到便捷器里。禁用host的copilot插件,重新启动ide就好了。解决办法 参考大神的办法删除主机和客户端插件中的 Copilot插件。 仅在客户端中重新安装 Copilot 插件。 我只是禁用也可以 对比了键盘映…

【Linux】程序的编译过程

程序的翻译过程 预处理(头文件展开,条件编译,宏替换,去注释)编译 :把c变成汇编语言汇编 :把汇编变成二进制(不可执行,二进制目标文件)链接 :把自…

Trunk链路操作题

Trunk链路操作题 论证:

【计算机网络】实验7:默认路由和特定主机路由以及路由环路问题

实验 7:默认路由和特定主机路由以及路由环路问题 一、 实验目的 了解默认路由以及特定主机路由。 了解静态路由配置错误导致的路由环路问题。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实验内容 1、默认路由以及特定主机路由 (1) 第一步&#xff…

特殊的数学性质

一个数模9的结果等于它的每一位数相加和模9

JSP知识点总结

jsp九大对象 在jsp中内置了9个对象,无需创建该对象即可使用。其名称为固定名称。 1.out输出对象 - 属于JspWriter print(): 输出 flush(): 刷新 close(): 关闭 2.request请求对象 - 属于HttpServletRequest getParameter(): 获取请求的参数 setCharacterEncodin…

电子信息工程自动化 基于单片机的居室安全报警系统

摘要 本课题设计了基于STM32F103C6T6单片机为主控核心的居室安全报警系统。为了解决家庭居室的安全监控,通过温湿度芯片SHT30、烟雾传感器MQ-2、天然气传感器MQ-4来获取居室的温湿度、烟雾、天然气含量,使用了一个热释电传感器、菲涅耳透镜、红外传感信…

【vue3 for beginner】Pinia基本用法:存储user的信息

🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 Pinia 简介 Pinia 是一个用于 Vue.js 应用的状态管理库,是 Vuex 的…

使用Goland对6.5840项目进行go build出现异常

使用Goland对6.5840项目进行go build出现异常 Lab地址: https://pdos.csail.mit.edu/6.824/labs/lab-mr.html项目地址: git://g.csail.mit.edu/6.5840-golabs-2024 6.5840运行环境: mac系统 goland git clone git://g.csail.mit.edu/6.5840-golabs-2024 6.5840 cd 6.5840/src…

React基础知识四 Hooks

什么是hooks? (coderwhy) hooks是react 16.8(2019年)出的新特性。 react有两种形式来创建组件——类式和函数式。在hooks之前类式组件就是react最主流的编程方式。 这个时候,函数式组件是非常鸡肋的,几乎没什么用。因…

电子病历静态数据脱敏路径探索

一、引言 数据脱敏(Data Masking),屏蔽敏感数据,对某些敏感信息(比如patient_name、ip_no、ad、no、icd11、drug等等 )通过脱敏规则进行数据的变形,实现隐私数据的可靠保护。电子病历作为医疗领…

AIGC 012-Video LDM-更进一步,SD作者将LDM扩展到视频生成任务!

AIGC 012-Video LDM-Stable Video diffusion前身,将LDM扩展到视频生成任务! 文章目录 0 论文工作1论文方法实验结果 0 论文工作 Video LDM作者也是Stable diffusion的作者,作者在SD的架构上进行扩展,实现了视频的生成。后续在Vid…

ABAP DIALOG屏幕编程1

一、DIALOG屏幕编程 DIALOG屏幕编程是SAP ABAP中用于创建用户交互界面的一种技术,主要用于开发事务性应用程序。它允许用户通过屏幕输入或操作数据,程序根据用户的操作执行逻辑处理。 1、DIALOG编程的主要组件 a、屏幕 (Screen) DIALOG程序的核心部分…

青训营-豆包MarsCode技术训练营试题解析二十七

介绍 ‌豆包青训营‌是由字节跳动和稀土掘金社区共同发起的技术培训和人才选拔项目。该项目的目标是培养具有职业竞争力的优秀开发工程师,并提供全程免费的课程,不收取任何费用‌。 课程内容和方向 豆包青训营的课程涵盖前端、后端和AI方向。在这个飞…

人工智能学习用的电脑安装cuda、torch、conda等软件,版本的选择以及多版本切换

接触人工智能的学习三个月了,每天与各种安装包作斗争,缺少依赖包、版本高了、版本低了、不兼容了、系统做一半从头再来了。。。这些都是常态。三个月把单位几台电脑折腾了不下几十次安装,是时候总结一下踩过的坑和积累的经验了。 以一个典型的…

华为关键词覆盖应用市场ASO优化覆盖技巧

在我国的消费者群体当中,华为的品牌形象较高,且产品质量过硬,因此用户基数也大。与此同时,随着影响力的增大,华为不断向外扩张,也逐渐成为了海外市场的香饽饽。作为开发者和运营者,我们要认识到…

Vue+Vite 组件开发的环境配置(超级简单)

vite是什么 Vite 是一个现代化的前端构建工具和开发服务器,它特别适用于构建大型的单页面应用(SPA)。Vite 旨在提供极快的冷启动速度,并且能够即时地(几乎实时地)更新模块,这得益于其利用原生 …

从仪表盘探索 MongoDB 关键指标

这是 MongoDB 监控系列文章的第七篇,前面几篇文章的链接如下: MongoDB 监控(一)MongoDB 监控(二)MongoDB 监控(三)MongoDB 监控(四)MongoDB 监控&#xff08…

mac安装php和xdebug调试

要在Mac上安装PHP 7.4,你可以通过几种方式来完成,但鉴于PHP7.4官方已不再维护,并且Homebrew默认仓库中不再提供此版本,我们需要从第三方仓库或直接从源代码进行安装。本文以brew方式安装,如果安装的是8.0以上&#xff…