Python自動化辦公之Excel對比工具
Python自動化辦公之Excel對比工具
以下文章來源于蘿卜大雜燴 ,作者周蘿卜
Do it by yourself!愛好Python,測試,NLP,數(shù)據(jù)分析,小程序,k8s等技術(shù),期待與你一同成長
今天我們繼續(xù)分享真實的自動化辦公案例,希望各位 Python 愛好者能夠從中得到些許啟發(fā),在自己的工作生活中更多的應用 Python,使得工作事半功倍!
需求
由于工作當中經(jīng)常需要對比前后兩個 Excel 文件,文件內(nèi)容比較多,人工肉眼對比太費勁,還容易出錯,搞個 Python 小工具,會不會事半功倍
運行腳本,可以把前后兩個 Excel 文件當中不同的內(nèi)容數(shù)據(jù)展現(xiàn)出來,不同 sheet 頁簽表示不同的數(shù)據(jù)處理結(jié)果
需求解析
不需要解析,直接干
代碼實現(xiàn)
我們先導入兩份測試數(shù)據(jù),進行 old 和 new 的處理,注意數(shù)據(jù)中 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,我們可以直接用兩份數(shù)據(jù)相減即可
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
接下來我們再將所有的數(shù)據(jù)拼接到一起,并使用 drop_duplicates 來保留被修改的數(shù)據(jù)
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 表明更改了我們需要標記的字段中的值。我們可以使用重復函數(shù)來獲取所有這些 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)]
現(xiàn)在我們將舊數(shù)據(jù)和新數(shù)據(jù)進行拆分,刪除不必要的版本列并將 account 設(shè)置為索引
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
接下來我們定義一個函數(shù)來展示從一列到另一列的變化
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)
現(xiàn)在使用 swaplevel 函數(shù)來獲取彼此相鄰的舊列和新列
最后我們使用 groupby 然后應用我們自定義 report_diff 函數(shù)將兩個相應的列相互比較
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()
接下來我們需要找出被刪除和新增的數(shù)據(jù)
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)]
我們可以使用單獨的選項卡將所有內(nèi)容輸出到 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_excel
window = 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
)
用于獲取文件和文件夾的函數(shù)
def
selectFile1
()
:
path_ = filedialog.askopenfilename()
path_file1.set(path_)
用于保存新生成文件和提示消息的函數(shù)
def
save_path
()
:
path = txt3.get()
deal_excel(path)
res =
"對比處理完成!"
messagebox.showinfo(
’蘿卜大雜燴’
, res)
這樣,一個簡單的 Excel 對比工具就完成啦
好了,這樣我們就完成了一個簡易的 GUI 拆分 PDF 文件的工具嘍
喜歡就賞、點贊,轉(zhuǎn)發(fā),三連支持一下噻!
END
推薦閱讀
牛逼!Python常用數(shù)據(jù)類型的基本操作(長文系列第①篇)
牛逼!Python的判斷、循環(huán)和各種表達式(長文系列第②篇)
牛逼!Python函數(shù)和文件操作(長文系列第③篇)
牛逼!Python錯誤、異常和模塊(長文系列第④篇)
推薦閱讀
牛逼!Python常用數(shù)據(jù)類型的基本操作(長文系列第①篇)
牛逼!Python的判斷、循環(huán)和各種表達式(長文系列第②篇)
牛逼!Python函數(shù)和文件操作(長文系列第③篇)
牛逼!Python錯誤、異常和模塊(長文系列第④篇)
-
2023年血糖新標準公布,不是3.9-6.1,快來看看你的血糖正常嗎? 2023-02-07
-
2023年各省最新電價一覽!8省中午執(zhí)行谷段電價! 2023-01-03
-
PPT導出高分辨率圖片的四種方法 2022-09-22
-
2023年最新!國家電網(wǎng)27家省級電力公司負責人大盤點 2023-03-14
-
全國消防救援總隊主官及簡歷(2023.2) 2023-02-10
-
盤點 l 中國石油大慶油田現(xiàn)任領(lǐng)導班子 2023-02-28
-
我們的前輩!歷屆全國工程勘察設(shè)計大師完整名單! 2022-11-18
-
關(guān)于某送變電公司“4·22”人身死亡事故的快報 2022-04-26
