吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12655|回复: 58
收起左侧

[Python 原创] 简单使用python做excel多文件批量搜索(带图形界面)(已更新)

  [复制链接]
悠度科技 发表于 2020-1-10 10:41
本帖最后由 悠度科技 于 2020-3-9 22:17 编辑

公司里大部分文件除了录入数据库外还会有excel表格原始数据上传
而今天公司数据库因不明原因缺失一条数据,这条数据可能存在在数百个excel任何一个之中。。。。

因此简单的写了一个excel批量查询脚本
excel作为最常用的办公工具之一有很多数据都是储存在excel之中,比如财务报表等等,当涉及到较多文件搜索某一个内容时还是比较麻烦的
比如我的同事用wps居然文件只能一个个打开,office的可以通过一些方法打开多文件,但是一次打开几百个内存直接爆了,并且搜索都是只能一个文件一个文件搜索
通过这个脚本可以从数百上千的excel几十几百万行数据中快速找到我们需要的数据,精准定位到相关文件,提升办公效率

为了方便使用也简单的用tkinter配置了一下图形界面

主要使用到以下
xlwings   ----   处理excel
tkinter    ----   处理图形界面
tkinter.filedialog  ----   调用文件上传接口
threading   ----   处理多线程

常规的有
math、string

代码如下(做了详细注释,可以大概看出处理逻辑):
[Python] 纯文本查看 复制代码
import xlwings as xw #引入xlwings处理excel
from tkinter import * #引入tkinter处理界面
import tkinter.filedialog #调用上传文件窗口类
import math
import threading #多线程
import string

#基本变量
files=[]
result=[]

def search(file,word):
    app = xw.App(visible=False,add_book=False) #初始化    visible=False表示不在用户界面打开该excel   add_book=False只打开不新建工作薄
    wb = app.books.open(file) #打开已有excel文件
    sheets = wb.sheets #读取工作簿
    for sht in sheets:
        rng = sht.range('a1').expand('table')
        nrows = rng.rows.count #获取行数
        ncols = rng.columns.count #获取列数
        print("正在比对:%s"%(file))
        #文本转字符
        A=math.floor(ncols/26) #首字母
        A=chr((A-1)+97) if (A-1)>=0 else "" #如26以内首字母为空   27首字母为A  55首字母为B
        B=math.floor(ncols%26) #第二个字母 取26的余                按这个算法 B为第2列  Z为第26列    AA 为第27列    AB为第28列    BA为第53列
        B=chr(B+97) if B>=0 else ""
        col=("%s%s"%(A,B)) #合并
        val=sht.range('a1:%s%d'%(col,nrows)).value #获取区域内容
        for ii,i in enumerate(val): #遍历区域内容
            for jj,j in enumerate(i):
                if str(j).find(str(word))!=-1: #搜索该字符串
                    mess="成功找到数据位于表:%s 工作簿:%s 行:%d 列:%d 内容:%s"%(file,sht,ii+1,jj+1,j)
                    result.append(mess)
                    print(mess)
    app.quit() #退出excel

def MyThreading(num1,num2,searchText): #线程执行
    for i in range(num1,num2):
        print("打开文件%s"%(files[i]))
        search(files[i],searchText)
    return 0

def FileSelect():#文件选择
    files.clear()
    filename = tkinter.filedialog.askopenfilenames() #弹出多文件选择窗
    if(len(filename)==0):
        textbox.insert('end', "未选择任何文件!\n")
        root.update()
        print("未选择任何文件!\n")
    else:
        textbox.insert('end', "已选择文件\n")
        for i in filename:
            files.append(i)
            print("\t\t%s\n"%(i))
            textbox.insert('end', "%s\n"%(i))
            textbox.see(tkinter.END)
            root.update()
    return 0

def start():
    searchText=e.get() #从钩子获取内容
    if len(files)==0:
        print("未上传文件")
        textbox.insert('end', "错误:未上传文件\n")
        root.update()
        return 0
    if (not searchText) or searchText=="请输入需要搜索的字符串":
        print("未输入需查询内容")
        textbox.insert('end', "错误:未输入需查询内容\n")
        root.update()
        return 0
    print("正在执行")
    textbox.insert('end', "正在执行,页面可能稍有卡顿,请耐心等待\n")
    root.update()

    ThreadLen=10 if len(files)>10 else 1 #文件数量若小于10则只开一个线程
    ThreadArr=[]
    if ThreadLen>1:
        for i in range(ThreadLen):#追加十个线程(若需要)
            bei=math.floor(len(files)/ThreadLen)
            print("执行线程%d至%d"%((i*bei),(i*bei+bei)))
            t=threading.Thread(target=MyThreading,args=((i*bei),(i*bei+bei),searchText))
            ThreadArr.append(t)

    #追加线程执行剩余文件搜索
    print("执行线程%d至%d"%(0,len(files)))
    t=threading.Thread(target=MyThreading,args=(0,len(files),searchText))
    ThreadArr.append(t)
    for i in ThreadArr:
        i.start() #循环执行所有线程
    for i in ThreadArr:
        i.join() #循环等待所有线程执行结束

    print("执行结束")

    if len(result)==0:
            textbox.insert('end', "没有找到该字符串\n")
    else:
        textbox.insert('end', "执行结束,执行结果如下:\n")
    for i in result:
        textbox.insert('end', "%s\n"%(i))
    result.clear()
    textbox.see(tkinter.END) #查看文本框底部
    root.update() #更新文本框




#构建用户界面
root=Tk()
root.title("excel内容搜索") #窗口标题
root.geometry('450x300+585+265') #初始化窗口大小和位置
root.resizable(0, 0) #设置窗口大小不可更改

#输入框
e = StringVar()#字符串钩子
enrty=Entry(root,width=20,textvariable=e).grid(row=0,column=0,columnspan=2,padx=40,pady=5)
e.set("请输入需要搜索的字符串")

#上传文件按钮
getFile = Button(root,text="点击选择文件",command= FileSelect).grid(row=1,column=0,columnspan=2,padx=40,pady=5)

#开始按钮
startBtn = Button(root,text="START",command= start).grid(row=2,column=0,columnspan=2,padx=40,pady=5)

#消息框
textbox = Text(root,width=50,height=10)
textbox.grid(row=3,column=0,columnspan=2,padx=40,pady=5)
textbox.insert("end", "日志消息:\n")

root.mainloop() #执行





安装对应类库后执行py可以直接运行图形界面

需要编译的可以先执行
[Asm] 纯文本查看 复制代码
pip3 install pyinstaller
安装pyinstaller
然后执行  
[Asm] 纯文本查看 复制代码
pyinstaller -F -w pyExcelSearch.py

pyinstaller -F选项指定生成单独的 EXE 文件
pyinstaller -w选项指定程序运行时不显示命令行窗口(仅对 Windows 有效,可选)


附上压缩包含py文件和编译好的exe文件
下载路径:下载


附上运行图(界面优化无能,勿怪):


image.png


image.png


最后的最后,喜欢的话评个分吧[狗头]
下载路径:下载

更新了多sheets搜索,之前的确没有想到
另外由于xlwings的特性,只能读取到连续的单元格,也就是如果某个单元格与其他单元格相对独立则无法搜索到,这也就是很多朋友回复搜索不到的原因
目前正在找办法解决

免费评分

参与人数 23吾爱币 +24 热心值 +19 收起 理由
伽蓝听雨 + 1 + 1 谢谢@Thanks!
小狐狸爱小兔子 + 1 我很赞同!
IT早安 + 1 用心讨论,共获提升!
huguo002 + 1 + 1 我很赞同!牛气,牛气!!!
猫灵夜一 + 1 + 1 谢谢@Thanks!
sange451 + 1 谢谢分享,希望完善
航宇bbb + 1 + 1 我很赞同!
hshcompass + 1 + 1 谢谢@Thanks!
Xma666 + 1 + 1 我很赞同!
fsrank + 1 + 1 谢谢@Thanks!
pinhai + 1 用心讨论,共获提升!
phipe + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
pibyaya + 1 谢谢@Thanks!
newbie2019 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Futuresing + 1 用心讨论,共获提升!
wushaominkk + 5 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
chadd + 1 + 1 谢谢@Thanks!
ymhld + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
imqiuge + 1 + 1 热心回复!
飞行堡垒 + 1 + 1 用心讨论,共获提升!
qunumab + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
MichaelWin + 1 热心回复!
weliong + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

shubiao05 发表于 2020-1-14 22:52
本帖最后由 shubiao05 于 2020-1-15 14:33 编辑
悠度科技 发表于 2020-1-14 13:58
不好意思,之前的确没有考虑到多工作簿,已更新

我测试了一下,可以支持多个sheet的情况了,good job!

测试中我又发现了一个小bug,我增加了三行,完美运行:第8行、第15 行及第38行,同时把增加的源码连同您的源码一块贴到这里,方便朋友的改进:


[Python] 纯文本查看 复制代码
import xlwings as xw #引入xlwings处理excel
from tkinter import * #引入tkinter处理界面
import tkinter.filedialog #调用上传文件窗口类
import math
import threading #多线程
import string
#导入下面的库
import pythoncom

#基本变量
files=[]
result=[]
 
def search(file,word):
    pythoncom.CoInitialize()#函数开头初始化,否则会出现' 尚未调用coinitialize'错误
    app = xw.App(visible=False,add_book=False) #初始化    visible=False表示不在用户界面打开该excel   add_book=False只打开不新建工作薄
    wb = app.books.open(file) #打开已有excel文件
    sheets = wb.sheets #读取工作簿
    for sht in sheets:
        rng = sht.range('a1').expand('table')
        nrows = rng.rows.count #获取行数
        ncols = rng.columns.count #获取列数
        print("正在比对:%s"%(file))
        #文本转字符
        A=math.floor(ncols/26) #首字母
        A=chr((A-1)+97) if (A-1)>=0 else "" #如26以内首字母为空   27首字母为A  55首字母为B
        B=math.floor(ncols%26) #第二个字母 取26的余                按这个算法 B为第2列  Z为第26列    AA 为第27列    AB为第28列    BA为第53列
        B=chr(B+97) if B>=0 else ""
        col=("%s%s"%(A,B)) #合并
        val=sht.range('a1:%s%d'%(col,nrows)).value #获取区域内容
        for ii,i in enumerate(val): #遍历区域内容
            for jj,j in enumerate(i):
                if str(j).find(str(word))!=-1: #搜索该字符串
                    mess="成功找到数据位于表:%s 工作簿:%s 行:%d 列:%d 内容:%s"%(file,sht,ii+1,jj+1,j)
                    result.append(mess)
                    print(mess)
    wb.close()#不加的话,Excel一直处于使用状态,无法打开Excel文件查看
    app.quit() #退出excel
 
def MyThreading(num1,num2,searchText): #线程执行
    for i in range(num1,num2):
        print("打开文件%s"%(files[i]))
        search(files[i],searchText)
    return 0
 
def FileSelect():#文件选择
    files.clear()
    filename = tkinter.filedialog.askopenfilenames() #弹出多文件选择窗
    if(len(filename)==0):
        textbox.insert('end', "未选择任何文件!\n")
        root.update()
        print("未选择任何文件!\n")
    else:
        textbox.insert('end', "已选择文件\n")
        for i in filename:
            files.append(i)
            print("\t\t%s\n"%(i))
            textbox.insert('end', "%s\n"%(i))
            textbox.see(tkinter.END)
            root.update()
    return 0
 
def start():
    searchText=e.get() #从钩子获取内容
    if len(files)==0:
        print("未上传文件")
        textbox.insert('end', "错误:未上传文件\n")
        root.update()
        return 0
    if (not searchText) or searchText=="请输入需要搜索的字符串":
        print("未输入需查询内容")
        textbox.insert('end', "错误:未输入需查询内容\n")
        root.update()
        return 0
    print("正在执行")
    textbox.insert('end', "正在执行,页面可能稍有卡顿,请耐心等待\n")
    root.update()
 
    ThreadLen=10 if len(files)>10 else 1 #文件数量若小于10则只开一个线程
    ThreadArr=[]
    if ThreadLen>1:
        for i in range(ThreadLen):#追加十个线程(若需要)
            bei=math.floor(len(files)/ThreadLen)
            print("执行线程%d至%d"%((i*bei),(i*bei+bei)))
            t=threading.Thread(target=MyThreading,args=((i*bei),(i*bei+bei),searchText))
            ThreadArr.append(t)
 
    #追加线程执行剩余文件搜索
    print("执行线程%d至%d"%(0,len(files)))
    t=threading.Thread(target=MyThreading,args=(0,len(files),searchText))
    ThreadArr.append(t)
    for i in ThreadArr:
        i.start() #循环执行所有线程
    for i in ThreadArr:
        i.join() #循环等待所有线程执行结束
 
    print("执行结束")
 
    if len(result)==0:
            textbox.insert('end', "没有找到该字符串\n")
    else:
        textbox.insert('end', "执行结束,执行结果如下:\n")
    for i in result:
        textbox.insert('end', "%s\n"%(i))
    result.clear()
    textbox.see(tkinter.END) #查看文本框底部
    root.update() #更新文本框
 
 
 
 
#构建用户界面
root=Tk()
root.title("excel内容搜索") #窗口标题
root.geometry('450x300+585+265') #初始化窗口大小和位置
root.resizable(0, 0) #设置窗口大小不可更改
 
#输入框
e = StringVar()#字符串钩子
enrty=Entry(root,width=20,textvariable=e).grid(row=0,column=0,columnspan=2,padx=40,pady=5)
e.set("请输入需要搜索的字符串")
 
#上传文件按钮
getFile = Button(root,text="点击选择文件",command= FileSelect).grid(row=1,column=0,columnspan=2,padx=40,pady=5)
 
#开始按钮
startBtn = Button(root,text="START",command= start).grid(row=2,column=0,columnspan=2,padx=40,pady=5)
 
#消息框
textbox = Text(root,width=50,height=10)
textbox.grid(row=3,column=0,columnspan=2,padx=40,pady=5)
textbox.insert("end", "日志消息:\n")
 
root.mainloop() #执行
shubiao05 发表于 2020-1-13 10:24
悠度科技 发表于 2020-1-11 19:20
你好   excel内容里有的是吗?   可否截图看下

打开附近件,比如搜索Sheet2中的“海淀",则提示找不到该字符串


还没仔细研究源码,可能没有考虑一张表中有多个sheetr的情况?

test.zip

6.7 KB, 下载次数: 52, 下载积分: 吾爱币 -1 CB

weliong 发表于 2020-1-10 10:46
booms 发表于 2020-1-10 10:58
正在学习,努力吧
zqfyjd 发表于 2020-1-10 10:59
一直想学,到现在还没学会。哎,觉得自己脑子不行。
怂怂 发表于 2020-1-10 11:02
希望有一天我也可以跟楼主一样厉害
我现在只会print ("hello world")
a526600908 发表于 2020-1-10 11:28
我现在只会print ("hello world")
gaoxiaoao 发表于 2020-1-10 11:37
这么优秀额的帖子,没人看,楼主厉害
shubiao05 发表于 2020-1-10 15:10
试了一下,可以正确执行,但有些内容搜不出来,不知道为什么!


谢谢楼主的分享!
 楼主| 悠度科技 发表于 2020-1-10 17:31
shubiao05 发表于 2020-1-10 15:10
试了一下,可以正确执行,但有些内容搜不出来,不知道为什么!

你好,可以说下具体情况嘛,我再优化优化
theday123 发表于 2020-1-10 18:06
变秃了也变强了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 12:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表