Python——對比Excel表格中數據並標紅不同單元格生成桌面程序(完整版)

背景介紹:

前段時間公司的一個同事突然加我,想讓我給他做一個對比兩個Excel文件中的指定分類下數據的差異,並將有差異的單元格中有差異的確切值進行字體標紅,這時再人工記錄下來(我稱之爲文件差異比對改善項目)
經過一段時間的聊天以及多次碰面,終於將需求確定下來,直接上一波效果圖:在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述
這裏主要用到的庫是openpyxl(python的一個強大的操作Excel的庫)和tkinter(GUI簡單的桌面程序化)

需求可行性分析:

再跟他進行需求確認時,他的需求是分別讀取兩個excel表格中的指定列中的數據,其中每個表格中的指定列的數據都是雜亂的,所以無法以指定的某個表當作參照來比對其中的不同,我這裏的處理方法是分別將表1作爲參照去比對錶2,然後再拿表2去比對錶一,確保能夠找到表一對比表二時數據的不同以及表二對錶一,確保數據的準確性,以及他想要將比對過的有不同的單元格內不同的指定值給標紅,這裏我也做了幾個測試,無法實現在單元格內指定部分文字的字體顏色,所以我這裏直接將比對完成後不同的數據進行顯示,標紅整個單元格內的字體以及單元格背景顏色,以及其中C列爲兩個表中的唯一值,先拿表一中的C列值去和表二中的C列進行比對 ,確定表一表二共有的一行,然後再拿共有的這一行去進行F,G列數據比對,如果表一有表二沒有,直接標紅不再進行比對處理,同樣道理,再拿表二的C列值和表一的。

項目實施:
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列的子件規格的每一個和 sheet2中的 C列的子件規格進行對比
            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:
                # 對比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('提示', '已處理完成,可在已選擇的文件位置進行查看。')
        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()
    # 設置窗體標題
    root.title('文件比對器')
    # 設置窗口大小和位置
    root.geometry('500x300+570+200')
    label1 = Label(root, text='請選擇要比對的文件:')
    text1 = Entry(root, bg='white', width=40)
    button1 = Button(root, text='瀏覽', width=4, height=1, command=selectExcelfile)
    label2 = Label(root, text='請選擇要保存的位置:')
    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()

歐克,這裏已經時所有的代碼了 ,你可以將我的代碼試着運行看看如果對你有用的話

生成桌面程序

當你運行代碼時就會生成和我上面效果圖一樣的效果,但是如何將用戶去體驗呢,這裏就用到了我們的打包生成桌面小程序

操作步驟:
如果你是第一次打包是要將pip的路徑設置到你電腦的環境變量中,否則無法進行打包操作 這裏就不做這個操作 不懂得可以問度娘 直接上重點:
簡單的打包方式:
win+R 輸入cmd
在這裏插入圖片描述
輸入>pyinstaller E:\你的要執行的py的路徑 點擊回車 當看到最後顯示success就說明已經成功了
在這裏插入圖片描述

其中要注意的是你在敲pyinstaller的前面的路徑就是你生成程序的所在位置 以我的E:\pythonpackage\carroom爲例,運行成功後 生成的程序就在我的E:\pythonpackage\carroom文件夾下:
在這裏插入圖片描述
ok 這裏已經成功了
執行完成後,將會生成dist和build兩個文件夾。(文件生成位置與cmd起始位置有關)其中 ,build 目錄是 pyinstaller存儲臨時文件的目錄,可以安全刪除。最終的打包程序在dist內部的finaldivisive文件夾下
在這裏插入圖片描述
這個就是我生成的exe文件了

但是當你運行程序時也會顯示控制檯窗口 直接影響用戶體驗

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

-F 表示生成單個可執行文件,執行後dist目錄中出現了python_test.exe文件,沒有任何依賴庫,執行它即可。

-w 表示去掉控制檯窗口,這在GUI界面時非常有用。不過如果是命令行程序的話那就把這個選項刪除吧!

ok 這樣完整版的程序就算做出來了 哈哈

如果對你有用 記得點個贊咱再走啊 麼麼噠

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章