Python3——对比Excel表格中数据并标红不同单元格生成桌面程序(完整版)

背景介绍:
前段时间公司的一个同事突然加我,想让我给他做一个对比两个Excel文件中的指定分类下数据的差异,并将有差异的单元格中有差异的确切值进行字体标红,这时再人工记录下来(我称之为文件差异比对改善项目)
经过一段时间的聊天以及多次碰面,终于将需求确定下来,直接上一波效果图:


1.png
2.png
3.png

这里主要用到的库是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


4.png

输入>pyinstaller E:\你的要执行的py的路径 点击回车 当看到最后显示success就说明已经成功了


6.png

其中要注意的是你在敲pyinstaller的前面的路径就是你生成程序的所在位置 以我的E:\pythonpackage\carroom为例,运行成功后 生成的程序就在我的E:\pythonpackage\carroom文件夹下:


7.png

ok 这里已经成功了
执行完成后,将会生成dist和build两个文件夹。(文件生成位置与cmd起始位置有关)其中 ,build 目录是 pyinstaller存储临时文件的目录,可以安全删除。最终的打包程序在dist内部的finaldivisive文件夹下
8

这个就是我生成的exe文件了

但是当你运行程序时也会显示控制台窗口 直接影响用户体验

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

-F 表示生成单个可执行文件,执行后dist目录中出现了python_test.exe文件,没有任何依赖库,执行它即可。

-w 表示去掉控制台窗口,这在GUI界面时非常有用。不过如果是命令行程序的话那就把这个选项删除吧!

ok 这样完整版的程序就算做出来了 哈哈

如果对你有用 记得点个赞咱再走啊 么么哒

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355