Python使用Tkinter+openpyxl處理Excel文件并顯示實時進(jìn)度條
在項目開發(fā)或數(shù)據(jù)處理中,經(jīng)常需要批量處理 Excel 文件,例如將所有單元格的值強(qiáng)制轉(zhuǎn)換為字符串(特別是處理合并單元格時,避免讀取到 None)。如果文件行數(shù)較多,處理時間較長,用戶很容易誤以為程序卡死。這時,添加一個實時進(jìn)度條就能極大提升用戶體驗。
本文分享一個完整示例:使用 openpyxl 正確處理合并單元格并將單元格轉(zhuǎn)為字符串,同時結(jié)合 Tkinter 實現(xiàn)帶進(jìn)度條的圖形界面,實時顯示處理進(jìn)度、當(dāng)前工作表和已處理行數(shù)。
環(huán)境準(zhǔn)備
pip install openpyxl
Tkinter 是 Python 標(biāo)準(zhǔn)庫,無需額外安裝。
完整代碼
import tkinter as tk
from tkinter import ttk
import openpyxl
def update_progress(progress_var, processed, total):
"""更新進(jìn)度條百分比"""
if total > 0:
progress = (processed / total) * 100
progress_var.set(progress)
def process_sheet(sheet, progress_var, root, progress_label, accumulated_rows, total_all_rows):
"""
處理單個工作表
正確處理合并單元格,將所有單元格值轉(zhuǎn)換為字符串
"""
current_processed = 0 # 當(dāng)前工作表已處理行數(shù)
for row in sheet.iter_rows():
for cell in row:
# 判斷是否在合并單元格內(nèi)
if cell.coordinate in sheet.merged_cells:
# 查找對應(yīng)的合并區(qū)域,取出左上角單元格的值
for merged_range in sheet.merged_cells.ranges:
if cell.coordinate in merged_range:
top_left = sheet.cell(merged_range.min_row, merged_range.min_col)
value = top_left.value
break
else:
value = cell.value
# 統(tǒng)一轉(zhuǎn)為字符串,None 轉(zhuǎn)為空字符串
cell.value = str(value) if value is not None else ''
current_processed += 1
total_processed = accumulated_rows + current_processed
# 更新進(jìn)度條和文字
update_progress(progress_var, total_processed, total_all_rows)
progress_label.config(
text=f"正在處理工作表:{sheet.title} "
f"進(jìn)度:{progress_var.get():.2f}% "
f"已處理行數(shù):{total_processed}/{total_all_rows}"
)
root.update_idletasks() # 強(qiáng)制刷新界面
return accumulated_rows + current_processed
if __name__ == "__main__":
# 請修改為你的實際 Excel 文件路徑
file_path = "output_file.xlsx"
workbook = openpyxl.load_workbook(file_path)
# 計算所有工作表的總行數(shù),用于整體進(jìn)度顯示
total_all_rows = sum(sheet.max_row for sheet in workbook.worksheets)
# 創(chuàng)建主窗口
root = tk.Tk()
root.title("Excel 單元格轉(zhuǎn)字符串工具(帶進(jìn)度條)")
root.geometry("600x200")
root.resizable(False, False)
# 進(jìn)度變量
progress_var = tk.DoubleVar(value=0)
# 標(biāo)題
title_label = tk.Label(root, text="正在處理 Excel 文件,請稍候...", font=("微軟雅黑", 12))
title_label.pack(pady=20)
# 進(jìn)度條
progress_bar = ttk.Progressbar(root, mode="determinate", variable=progress_var, maximum=100)
progress_bar.pack(padx=50, pady=10, fill=tk.X)
# 進(jìn)度文字
progress_label = tk.Label(root, text="進(jìn)度:0.00% 已處理行數(shù):0/0", font=("微軟雅黑", 10))
progress_label.pack(pady=5)
accumulated_rows = 0 # 已累計處理行數(shù)
# 逐個處理工作表
for sheet_name in workbook.sheetnames:
sheet = workbook[sheet_name]
accumulated_rows = process_sheet(
sheet, progress_var, root, progress_label, accumulated_rows, total_all_rows
)
# 處理完成
progress_var.set(100)
title_label.config(text="所有工作表處理完成!")
progress_label.config(text=f"處理完成!100.00% 總計處理行數(shù):{total_all_rows}/{total_all_rows}")
# 保存文件
workbook.save(file_path)
print(f"處理完成,文件已保存:{file_path}")
# 保持窗口打開,直到用戶手動關(guān)閉
root.mainloop()

核心功能詳解
合并單元格正確處理:合并區(qū)域內(nèi)除左上角外的單元格讀取時會返回 None,代碼通過遍歷 merged_cells.ranges 找到對應(yīng)區(qū)域的左上角值,確保數(shù)據(jù)不丟失。
實時進(jìn)度條:每處理完一行就調(diào)用 root.update_idletasks() 強(qiáng)制刷新界面,讓進(jìn)度條和文字實時更新,視覺反饋流暢。
多工作表整體進(jìn)度:預(yù)先統(tǒng)計所有 sheet 的總行數(shù),實現(xiàn)整個文件的統(tǒng)一進(jìn)度顯示,同時顯示當(dāng)前正在處理的工作表名稱。
使用注意事項
- 對于超大 Excel 文件(數(shù)十萬行),每行都刷新界面可能會略微影響性能??筛臑槊?10 行或 50 行更新一次。
- 處理前建議備份原文件,以防萬一。
- 本例將所有值強(qiáng)制轉(zhuǎn)為字符串(包括數(shù)字、日期等),如有特殊需求可自行調(diào)整轉(zhuǎn)換邏輯。
總結(jié)
通過 Tkinter 與 openpyxl 的結(jié)合,我們輕松實現(xiàn)了一個帶圖形化進(jìn)度條的 Excel 處理工具,用戶體驗友好,代碼清晰易擴(kuò)展。后續(xù)還可以加入文件選擇對話框、日志輸出、錯誤處理等功能。
到此這篇關(guān)于Python使用Tkinter+openpyxl處理Excel文件并顯示實時進(jìn)度條的文章就介紹到這了,更多相關(guān)Python處理Excel文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python 中開發(fā)pattern的string模板(template) 實例詳解
這篇文章主要介紹了Python 中開發(fā)pattern的string模板(template) 實例詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04
python中tkinter窗口位置\坐標(biāo)\大小等實現(xiàn)示例
這篇文章主要介紹了python中tkinter窗口位置\坐標(biāo)\大小等實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

