Python自动化办公之Excel对比工具
今天我們繼續分享真實的自動化辦公案例,希望各位 Python 愛好者能夠從中得到些許啟發,在自己的工作生活中更多的應用 Python,使得工作事半功倍!
需求
由于工作當中經常需要對比前后兩個 Excel 文件,文件內容比較多,人工肉眼對比太費勁,還容易出錯,搞個 Python 小工具,會不會事半功倍
運行腳本,可以把前后兩個 Excel 文件當中不同的內容數據展現出來,不同 sheet 頁簽表示不同的數據處理結果
需求解析
不需要解析,直接干
代碼實現
我們先導入兩份測試數據,進行 old 和 new 的處理,注意數據中 account number 是唯一索引
old?=?pd.read_excel('sample-address-1.xlsx',?'Sheet1',?na_values=['NA']) new?=?pd.read_excel('sample-address-2.xlsx',?'Sheet1',?na_values=['NA']) old['version']?=?"old" new['version']?=?"new"對于我們這個小工具,主要考慮三種變化類型
哪些是新增的 account
哪些是被刪除的 account
哪些是被修改的 account
對于新增和刪除的 account,我們可以直接用兩份數據相減即可
old_accts_all?=?set(old['account?number']) new_accts_all?=?set(new['account?number'])dropped_accts?=?old_accts_all?-?new_accts_all added_accts?=?new_accts_all?-?old_accts_all接下來我們再將所有的數據拼接到一起,并使用 drop_duplicates 來保留被修改的數據
all_data?=?pd.concat([old,new],ignore_index=True) changes?=?all_data.drop_duplicates(subset=["account?number","name",?"street","city","state","postal?code"],?keep='last')接下來,我們需要找出哪些 account 有重復的條目,重復的 account 表明更改了我們需要標記的字段中的值。我們可以使用重復函數來獲取所有這些 account 的列表,并僅過濾掉那些重復的 account
dupe_accts?=?changes[changes['account?number'].duplicated()?==?True]['account?number'].tolist() dupes?=?changes[changes["account?number"].isin(dupe_accts)]dupe_accts?=?changes[changes['account?number'].duplicated()?==?True]['account?number'].tolist()dupes?=?changes[changes["account?number"].isin(dupe_accts)]現在我們將舊數據和新數據進行拆分,刪除不必要的版本列并將 account 設置為索引
change_new?=?dupes[(dupes["version"]?==?"new")] change_old?=?dupes[(dupes["version"]?==?"old")] change_new?=?change_new.drop(['version'],?axis=1) change_old?=?change_old.drop(['version'],?axis=1) change_new.set_index('account?number',?inplace=True) change_old.set_index('account?number',?inplace=True) df_all_changes?=?pd.concat([change_old,?change_new],axis='columns',keys=['old',?'new'],join='outer') df_all_changes接下來我們定義一個函數來展示從一列到另一列的變化
def?report_diff(x):return?x[0]?if?x[0]?==?x[1]?else?'{}?--->?{}'.format(*x)def?report_diff(x):????return?x[0]?if?x[0]?==?x[1]?else?'{}?--->?{}'.format(*x)現在使用 swaplevel 函數來獲取彼此相鄰的舊列和新列
最后我們使用 groupby 然后應用我們自定義 report_diff 函數將兩個相應的列相互比較
df_changed?=?df_all_changes.groupby(level=0,?axis=1).apply(lambda?frame:?frame.apply(report_diff,?axis=1)) df_changed?=?df_changed.reset_index()df_changed?=?df_all_changes.groupby(level=0,?axis=1).apply(lambda?frame:?frame.apply(report_diff,?axis=1))df_changed?=?df_changed.reset_index()接下來我們需要找出被刪除和新增的數據
df_removed?=?changes[changes["account?number"].isin(dropped_accts)] df_added?=?changes[changes["account?number"].isin(added_accts)]df_removed?=?changes[changes["account?number"].isin(dropped_accts)]df_added?=?changes[changes["account?number"].isin(added_accts)]我們可以使用單獨的選項卡將所有內容輸出到 Excel 文件,對應于更改、添加和刪除
output_columns?=?["account?number",?"name",?"street",?"city",?"state",?"postal?code"] writer?=?pd.ExcelWriter("my-diff.xlsx") df_changed.to_excel(writer,"changed",?index=False,?columns=output_columns) df_removed.to_excel(writer,"removed",index=False,?columns=output_columns) df_added.to_excel(writer,"added",index=False,?columns=output_columns) writer.save()最后,我們就得到了最開始的效果圖片展示的一個新的 Excel 文件
當然上面的代碼對于毫無編程的人來說還是有一點點復雜,我們還是做成 GUI 小程序吧,這次我們使用 Tkinter 來編寫 GUI 程序
我們首先導入 Tkinter 庫并進行初始化
import?tkinter from?tkinter?import?* from?tkinter?import?Label,?Button,?Entry,?messagebox from?tkinter?import?filedialog from?deal?import?deal_excelwindow?=?tkinter.Tk() path_file1?=?StringVar() path_file2?=?StringVar() path_path?=?StringVar() window.geometry('380x150')這里我們定義了三個 String 類型的變量,用來保存文件地址和文件夾路徑
然后我們進行簡單的頁面排版,只需要用到 Label,Entry 和 Button 就夠了
label1?=?Label(window,?text="文件1:").grid(column=0,?row=0) txt1?=?Entry(window,?width="30",?textvariable=path_file1).grid(column=1,?row=0) button1?=?Button(window,?text="文件選擇1",?command=selectFile1).grid(column=2,?row=0)label2?=?Label(window,?text="文件2:").grid(column=0,?row=1) txt2?=?Entry(window,?width="30",?textvariable=path_file2).grid(column=1,?row=1) button2?=?Button(window,?text="文件選擇2",?command=selectFile2).grid(row=1,?column=2)label3?=?Label(window,?text="新文件路徑:").grid(column=0,?row=2) txt3?=?Entry(window,?width="30",?textvariable=path_path) txt3.grid(column=1,?row=2) button3?=?Button(window,?text="新文件路徑",?command=selectPath).grid(row=2,?column=2)button4?=?Button(window,?text="開始處理",?command=save_path).grid(row=3,?column=1)用于獲取文件和文件夾的函數
def?selectFile1():path_?=?filedialog.askopenfilename()path_file1.set(path_)用于保存新生成文件和提示消息的函數
def?save_path():path?=?txt3.get()deal_excel(path)res?=?"對比處理完成!"messagebox.showinfo('蘿卜大雜燴',?res)這樣,一個簡單的 Excel 對比工具就完成啦
好了,這樣我們就完成了一個簡易的 GUI 拆分 PDF 文件的工具嘍
喜歡就在看、點贊,轉發,三連支持一下噻!
END
推薦閱讀牛逼!Python常用數據類型的基本操作(長文系列第①篇) 牛逼!Python的判斷、循環和各種表達式(長文系列第②篇)牛逼!Python函數和文件操作(長文系列第③篇)牛逼!Python錯誤、異常和模塊(長文系列第④篇)總結
以上是生活随笔為你收集整理的Python自动化办公之Excel对比工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 又一个4000字肝货,详解tkinter
- 下一篇: 著名数据库状告分支,法院:100%开源为