Python3——對(duì)比Excel表格中數(shù)據(jù)并標(biāo)紅不同單元格生成桌面程序(完整版)

背景介紹:
前段時(shí)間公司的一個(gè)同事突然加我,想讓我給他做一個(gè)對(duì)比兩個(gè)Excel文件中的指定分類下數(shù)據(jù)的差異郭怪,并將有差異的單元格中有差異的確切值進(jìn)行字體標(biāo)紅,這時(shí)再人工記錄下來(lái)(我稱之為文件差異比對(duì)改善項(xiàng)目)
經(jīng)過(guò)一段時(shí)間的聊天以及多次碰面,終于將需求確定下來(lái),直接上一波效果圖:


1.png
2.png
3.png

這里主要用到的庫(kù)是openpyxl(python的一個(gè)強(qiáng)大的操作Excel的庫(kù))和tkinter(GUI簡(jiǎn)單的桌面程序化)

需求可行性分析:

再跟他進(jìn)行需求確認(rèn)時(shí)陋率,他的需求是分別讀取兩個(gè)excel表格中的指定列中的數(shù)據(jù),其中每個(gè)表格中的指定列的數(shù)據(jù)都是雜亂的秽晚,所以無(wú)法以指定的某個(gè)表當(dāng)作參照來(lái)比對(duì)其中的不同瓦糟,我這里的處理方法是分別將表1作為參照去比對(duì)表2,然后再拿表2去比對(duì)表一赴蝇,確保能夠找到表一對(duì)比表二時(shí)數(shù)據(jù)的不同以及表二對(duì)表一菩浙,確保數(shù)據(jù)的準(zhǔn)確性,以及他想要將比對(duì)過(guò)的有不同的單元格內(nèi)不同的指定值給標(biāo)紅句伶,這里我也做了幾個(gè)測(cè)試芍耘,無(wú)法實(shí)現(xiàn)在單元格內(nèi)指定部分文字的字體顏色,所以我這里直接將比對(duì)完成后不同的數(shù)據(jù)進(jìn)行顯示熄阻,標(biāo)紅整個(gè)單元格內(nèi)的字體以及單元格背景顏色,以及其中C列為兩個(gè)表中的唯一值倔约,先拿表一中的C列值去和表二中的C列進(jìn)行比對(duì) 秃殉,確定表一表二共有的一行,然后再拿共有的這一行去進(jìn)行F,G列數(shù)據(jù)比對(duì),如果表一有表二沒(méi)有钾军,直接標(biāo)紅不再進(jìn)行比對(duì)處理鳄袍,同樣道理,再拿表二的C列值和表一的吏恭。

項(xiàng)目實(shí)施:
from tkinter import *
from tkinter import filedialog
import openpyxl
from openpyxl.styles import Font, Border, Side, PatternFill, colors, Alignment
import tkinter.messagebox

font_false = Font(size=9, bold=True, color="FF0000")
red_fill = PatternFill("solid", fgColor="C1CDCD")


def main():

    def fun_finish(shift, currentrow):
        data = ""
        if len(shift) > 0:
            for i in shift:
                data += str(i) + "."
        currentrow.fill = red_fill
        currentrow.font = font_false
        currentrow.value = data

    def fun_diff(start, end):
        arrShirt2 = []
        for i in start:
            a = 0
            for j in end:
                if i == j:
                    a += 1
            if a == 0:
                arrShirt2.append(i)
        return arrShirt2

    def selectExcelfile():
        text1.delete(0, END)
        sfname = filedialog.askopenfilename(title='選擇Excel文件', filetypes=[('Excel', '*.xlsx'), ('All Files', '*')])
        text1.insert(INSERT, sfname)

    def doProcess():
        startFile = text1.get()
        endFile = text2.get()
        wb = openpyxl.load_workbook(startFile)
        # get workbook every son
        sheet1 = wb['sheet1']
        sheet2 = wb['sheet2']
        for rows in range(7, sheet2.max_row - 4):
            guige2 = sheet2['C' + str(rows)].value
            ishave = False
            for anorows in range(7, sheet1.max_row - 4):
                guige1 = sheet1['C' + str(anorows)].value
                if guige2 == guige1:
                    ishave = True
            if not ishave:
                sheet2['C' + str(rows)].fill = red_fill
                sheet2['C' + str(rows)].font = font_false
                sheet2['F' + str(rows)].fill = red_fill
                sheet2['F' + str(rows)].font = font_false
                sheet2['G' + str(rows)].fill = red_fill
                sheet2['G' + str(rows)].font = font_false

        for row in range(7, sheet1.max_row - 4):
            # 先判斷sheet1 C列的子件規(guī)格的每一個(gè)和 sheet2中的 C列的子件規(guī)格進(jìn)行對(duì)比
            guige1 = sheet1['C' + str(row)].value
            ishave = False
            currentAnoRow = -1
            for anorow in range(7, sheet2.max_row - 4):
                guige2 = sheet2['C' + str(anorow)].value
                if guige1 == guige2:
                    ishave = True
                    currentAnoRow = anorow
            if ishave:
                # 對(duì)比F/G的差異
                tp1 = sheet1['F' + str(row)].value
                tp2 = sheet2['F' + str(currentAnoRow)].value
                bm1 = sheet1['G' + str(row)].value
                bm2 = sheet2['G' + str(currentAnoRow)].value
                if tp1 is None or tp2 is None:
                    print('loading')
                else:
                    if tp1 != tp2:
                        print(type(tp1))
                        top1 = tp1.split(".")
                        top2 = tp2.split(".")
                        topshift1 = fun_diff(top1, top2)
                        topshift2 = fun_diff(top2, top1)
                        fun_finish(topshift1, sheet1['F' + str(row)])
                        fun_finish(topshift2, sheet2['F' + str(currentAnoRow)])
                if bm1 is None or bm2 is None:
                      print('loadnig again')
                else:
                    if bm1 != bm2:
                        bottom1 = bm1.split(".")
                        bottom2 = bm2.split(".")
                        bottomshift1 = fun_diff(bottom1, bottom2)
                        bottomshift2 = fun_diff(bottom2, bottom1)
                        fun_finish(bottomshift1, sheet1['G' + str(row)])
                        fun_finish(bottomshift2, sheet2['G' + str(currentAnoRow)])
            else:
                sheet1['C' + str(row)].fill = red_fill
                sheet1['C' + str(row)].font = font_false
                sheet1['F' + str(row)].fill = red_fill
                sheet1['F' + str(row)].font = font_false
                sheet1['G' + str(row)].fill = red_fill
                sheet1['G' + str(row)].font = font_false
        else:
            tkinter.messagebox.showinfo('提示', '已處理完成,可在已選擇的文件位置進(jìn)行查看拗小。')
        wb.save(endFile)

    def closeThisWindow():
        root.destroy()

    def saveExcelfile():
        text2.delete(0, END)
        sfname = filedialog.asksaveasfilename(title='選擇保存的文件位置', filetype=[('Excel', '*.xlsx')])
        sfname = sfname + ".xlsx"
        text2.insert(INSERT, sfname)

    root = Tk()
    # 設(shè)置窗體標(biāo)題
    root.title('文件比對(duì)器')
    # 設(shè)置窗口大小和位置
    root.geometry('500x300+570+200')
    label1 = Label(root, text='請(qǐng)選擇要比對(duì)的文件:')
    text1 = Entry(root, bg='white', width=40)
    button1 = Button(root, text='瀏覽', width=4, height=1, command=selectExcelfile)
    label2 = Label(root, text='請(qǐng)選擇要保存的位置:')
    text2 = Entry(root, bg='white', width=40)
    button2 = Button(root, text='選擇', width=4, height=1, command=saveExcelfile)
    button3 = Button(root, text='處理', width=8, command=doProcess)
    button4 = Button(root, text='退出', width=8, command=closeThisWindow)

    label1.pack()
    text1.pack()
    button1.pack()
    label2.pack()
    button2.pack()
    button3.pack()

    label1.place(x=5, y=30)
    text1.place(x=120, y=30)
    button1.place(x=400, y=26)
    label2.place(x=5, y=80)
    text2.place(x=120, y=80)
    button2.place(x=400, y=74)
    button3.place(x=80, y=150)
    button4.place(x=360, y=150)
    root.mainloop()


if __name__ == "__main__":
    main()

歐克,這里已經(jīng)時(shí)所有的代碼了 樱哼,你可以將我的代碼試著運(yùn)行看看如果對(duì)你有用的話

生成桌面程序
當(dāng)你運(yùn)行代碼時(shí)就會(huì)生成和我上面效果圖一樣的效果哀九,但是如何將用戶去體驗(yàn)?zāi)兀@里就用到了我們的打包生成桌面小程序

操作步驟:
如果你是第一次打包是要將pip的路徑設(shè)置到你電腦的環(huán)境變量中搅幅,否則無(wú)法進(jìn)行打包操作 這里就不做這個(gè)操作 不懂得可以問(wèn)度娘 直接上重點(diǎn):
簡(jiǎn)單的打包方式:
win+R 輸入cmd


4.png

輸入>pyinstaller E:\你的要執(zhí)行的py的路徑 點(diǎn)擊回車 當(dāng)看到最后顯示success就說(shuō)明已經(jīng)成功了


6.png

其中要注意的是你在敲pyinstaller的前面的路徑就是你生成程序的所在位置 以我的E:\pythonpackage\carroom為例阅束,運(yùn)行成功后 生成的程序就在我的E:\pythonpackage\carroom文件夾下:


7.png

ok 這里已經(jīng)成功了
執(zhí)行完成后,將會(huì)生成dist和build兩個(gè)文件夾茄唐。(文件生成位置與cmd起始位置有關(guān))其中 息裸,build 目錄是 pyinstaller存儲(chǔ)臨時(shí)文件的目錄,可以安全刪除沪编。最終的打包程序在dist內(nèi)部的finaldivisive文件夾下
8

這個(gè)就是我生成的exe文件了

但是當(dāng)你運(yùn)行程序時(shí)也會(huì)顯示控制臺(tái)窗口 直接影響用戶體驗(yàn)

pyinstaller -F -w E:\pythonapp\tkinter\wodiu\finaldivisive.py

-F 表示生成單個(gè)可執(zhí)行文件,執(zhí)行后dist目錄中出現(xiàn)了python_test.exe文件呼盆,沒(méi)有任何依賴庫(kù),執(zhí)行它即可蚁廓。

-w 表示去掉控制臺(tái)窗口访圃,這在GUI界面時(shí)非常有用。不過(guò)如果是命令行程序的話那就把這個(gè)選項(xiàng)刪除吧纳令!

ok 這樣完整版的程序就算做出來(lái)了 哈哈

如果對(duì)你有用 記得點(diǎn)個(gè)贊咱再走啊 么么噠

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挽荠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子平绩,更是在濱河造成了極大的恐慌圈匆,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捏雌,死亡現(xiàn)場(chǎng)離奇詭異跃赚,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)性湿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)纬傲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人肤频,你說(shuō)我怎么就攤上這事叹括。” “怎么了宵荒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵汁雷,是天一觀的道長(zhǎng)净嘀。 經(jīng)常有香客問(wèn)我,道長(zhǎng)侠讯,這世上最難降的妖魔是什么挖藏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮厢漩,結(jié)果婚禮上膜眠,老公的妹妹穿的比我還像新娘。我一直安慰自己溜嗜,他們只是感情好宵膨,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著粱胜,像睡著了一般柄驻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上焙压,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天鸿脓,我揣著相機(jī)與錄音,去河邊找鬼涯曲。 笑死野哭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的幻件。 我是一名探鬼主播拨黔,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼绰沥!你這毒婦竟也來(lái)了篱蝇?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤徽曲,失蹤者是張志新(化名)和其女友劉穎零截,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體秃臣,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涧衙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奥此。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弧哎。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖稚虎,靈堂內(nèi)的尸體忽然破棺而出撤嫩,到底是詐尸還是另有隱情,我是刑警寧澤蠢终,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布序攘,位于F島的核電站鸭限,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏两踏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一兜喻、第九天 我趴在偏房一處隱蔽的房頂上張望梦染。 院中可真熱鬧,春花似錦朴皆、人聲如沸帕识。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)肮疗。三九已至,卻和暖如春扒接,著一層夾襖步出監(jiān)牢的瞬間伪货,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工钾怔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碱呼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓宗侦,卻偏偏與公主長(zhǎng)得像愚臀,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子矾利,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345