基于Python實現(xiàn)PDF批量轉化工具
一、開發(fā)的緣由
最近,有網(wǎng)友想讓我?guī)退鲆粋€批量把png, docx, doc, pptx, ppt, xls, xlsx文件轉化為PDF格式的軟件,完全傻瓜式的操作,把文件拖進去就進行轉化那種,簡單實用。之前,有過一個vbs的文件,可以轉docx, xlsx, pptx,但是對于圖片無能為力,為了完成這個任務還是要請出Python這個強大的利器。
二、開發(fā)的過程

1. 為了能夠實現(xiàn)拖動的功能,我首先想到要設計一個UI界面,然后可以直接接受拖動的文件。另外,因為是批量操作,需要一定的時間來完成操作,最好是可以添加一個進度條,讓用戶知道是否已經(jīng)完成了轉化。
2. 軟件的外觀本來想著簡化,但是想著得讓用戶看到轉化文件名的路徑和文件名,避免轉錯了,同時還得可以刪除選中的條目。所以我就設計了一個listbox控件,一個刪除按鈕、一個生成文件按鈕,還有一個導入文件的按鈕,為的是不習慣進行拖動的用戶設計。
3. 由于tkinter是系統(tǒng)自帶的,所以可以使軟件更小一點。另外,讀取圖片用到PIL這個模塊,而其它如docx, pptx, xlsx文件的轉化則需要依靠win32com.client這個模塊。
4. 我嘗試了多種方法來執(zhí)行拖動的功能,但是打包以后發(fā)現(xiàn)無法實現(xiàn),于時最終采用了windnd這個模塊,為了防止拖動時程序假死,我還用了多線程的方法。
三、成品介紹
我們這個軟件最終起名為PDF批量轉化器,它是一款支持多種文件格式批量轉換為PDF格式的工具,特別適用于Word、Excel、PowerPoint、圖片文件的轉換。它提供了一個直觀的界面,允許用戶通過拖拽文件或通過文件選擇器導入文件,支持多線程處理,提升了文件轉換的效率。主要特點有:
- 多文件格式支持:支持轉換Word、Excel、PowerPoint和圖片文件到PDF格式。
- 拖拽功能:用戶可以直接將文件拖拽至程序界面,簡化操作流程。
- 進度條顯示:轉換過程中,進度條實時顯示,用戶可以了解轉換的進度。
- 批量處理:一次可以處理多個文件,節(jié)省時間和操作精力。
- 文件管理:提供文件導入、刪除等操作,幫助用戶管理文件列表。
- 后臺處理:采用多線程方式處理文件轉換,避免界面卡頓。
此外,為了增強用戶體驗,我們還增加了二個小功能,一是把生成的PDF文件統(tǒng)一放在一個PDF文件夾里面,另外就是如果發(fā)現(xiàn)同名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 = root
self.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代替Checkbutton
self.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 bar
self.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", "請先選擇要刪除的文件!")
return
for 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)
return
def 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")
# 檢查目標文件是否已經(jīng)存在
if os.path.exists(pdf_path):
print(f"文件 {pdf_path} 已經(jīng)存在,跳過轉換。")
return False # 文件已經(jīng)存在,不進行轉換
# 如果文件不存在,繼續(xù)轉換
if convert_func(file_path, pdf_path, update_progress):
return True
return False
def 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 # 重置進度條當前值為0
self.label.config(text="正在處理中...") # 更新提示標簽
def update_progress():
nonlocal processed_files
processed_files += 1
self.progress_bar['value'] = processed_files
self.root.update_idletasks() # 更新UI
# 處理文件
excel_count = 0
word_count = 0
ppt_count = 0
img_count = 0
for file_path in files:
if file_path.lower().endswith((".xls", ".xlsx")): # Excel file
if self.process_file(file_path, self.excel_to_pdf, update_progress):
excel_count += 1
elif file_path.lower().endswith((".docx", ".doc")): # Word file
if self.process_file(file_path, self.word_to_pdf, update_progress):
word_count += 1
elif file_path.lower().endswith((".pptx", ".ppt")): # PowerPoint file
if self.process_file(file_path, self.ppt_to_pdf, update_progress):
ppt_count += 1
elif file_path.lower().endswith((".jpg", ".png")): # Image file
if 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 = False
wb = excel.Workbooks.Open(input_file)
wb.ExportAsFixedFormat(0, output_file)
wb.Close()
excel.Quit()
update_progress() # Update progress after conversion
return True
except Exception as e:
print(f"Error converting Excel to PDF: {e}")
return False
def 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 PDF
doc.Close()
word.Quit()
update_progress() # Update progress after conversion
return True
except Exception as e:
print(f"Error converting Word to PDF: {e}")
return False
def ppt_to_pdf(self, input_file, output_file, update_progress):
try:
ppt = win32com.client.Dispatch("PowerPoint.Application")
ppt.Visible = False
presentation = ppt.Presentations.Open(input_file)
presentation.SaveAs(output_file, 32) # 32 for PDF format
presentation.Close()
ppt.Quit()
update_progress() # Update progress after conversion
return True
except Exception as e:
print(f"Error converting PowerPoint to PDF: {e}")
return False
def 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 conversion
return True
except Exception as e:
print(f"Error converting image to PDF: {e}")
return False
if __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文件已存在,程序會跳過該文件以避免覆蓋。
以上就是基于Python實現(xiàn)PDF批量轉化工具的詳細內容,更多關于Python PDF批量轉化的資料請關注腳本之家其它相關文章!
相關文章
Pandas+Numpy+Sklearn隨機取數(shù)的實現(xiàn)示例
使用Python、pandas、numpy、scikit-learn來實現(xiàn)隨機打亂、抽取和切割數(shù)據(jù),文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧2024-03-03
python利用socketserver實現(xiàn)并發(fā)套接字功能
這篇文章主要為大家詳細介紹了python利用socketserver實現(xiàn)并發(fā)套接字功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01
使用python將csv數(shù)據(jù)導入mysql數(shù)據(jù)庫
這篇文章主要為大家詳細介紹了如何使用python將csv數(shù)據(jù)導入mysql數(shù)據(jù)庫,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2024-05-05
NumPy?創(chuàng)建數(shù)組的實現(xiàn)示例
NumPy數(shù)組是用于存儲大量數(shù)據(jù)的基本工具,它們類似于C語言中的數(shù)組,本文就來介紹一下NumPy?創(chuàng)建數(shù)組的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2026-01-01

