首页  >  文章  >  后端开发  >  技巧 | 80行代码自己动手写一个表格拆分与合并小工具

技巧 | 80行代码自己动手写一个表格拆分与合并小工具

Python当打之年
Python当打之年转载
2023-08-10 16:02:481284浏览


最近有新朋友看到之前《Python对比VBA实现excel表格合并与拆分》,想问下有没有免费的小工具,可以进行表格的拆分与合并。其实wps是有这两个功能的,而且效果还非常不错。不过,考虑到大家不一定都习惯wps,这里我们简单写个小工具满足大家。

我们来先看看小工具操作流程吧!

合并与拆分效果如下:

技巧 | 80行代码自己动手写一个表格拆分与合并小工具
合并——拆分

接下来,我们试试自己动手写这个工具吧!

1. 前期准备

由于我们采用的是python进行工具编写,并最终需要打包成一个exe文件供我们使用。为了降低包体大小,我们需要先创建一个虚拟环境备用。python进行工具编写,并最终需要打包成一个exe文件供我们使用。为了降低包体大小,我们需要先创建一个虚拟环境备用。

另外,在进行表格拆分与合并操作中采用的是第三方库pandas,同时关于gui我们用的是pysimplegui,打包成exe采用的是pyinstaller

另外,在进行表格拆分与合并操作中采用的是第三方库pandas,同时关于gui我们用的是pysimplegui,打包成exe采用的是pyinstaller。在创建虚拟环境后,我们将这些需要用到的第三方库也一一安装吧。

# 创建虚拟环境
conda create -n env_1 python=3.8.8

# 激活虚拟环境
conda  activate env_1

# 安装三个库 (pandas一些操作需要依赖openpyxl和xlrd,建议加上)
pip install pandas
pip install openpyxl
pip install xlrd
pip install pysimplegui
pip install pyinstaller

关于这三个库,大家可以查阅官方文档了解更多:

pandas : https://pandas.pydata.org/

pysimplegui:https://pysimplegui.readthedocs.io/en/latest/

pyinstaller:http://www.pyinstaller.org/

前期准备工具就绪,我们开始进入工具编写阶段。🎜

2. 表格拆分

Python实现表格拆分的逻辑比较简单,就是利用pandas分组然后将每组的数据单独导出存表即可

原表数据长这样:

技巧 | 80行代码自己动手写一个表格拆分与合并小工具
汇总表
# 拆分表格
def splitTable(df,_key):
    print('----------正在进行表格拆分----------')
    df = df.astype('str')
    # 按照字段_key进行分组
    grouped = df.groupby(by = _key)
    # 输出分组数据导出成单表
    for num , (i, data) in enumerate(grouped):
        data.to_excel(f'.\\{i}.xlsx',index = False,sheet_name = i)
        print(f'已经拆成{num+1}张表格...')

导出结果如下:

技巧 | 80行代码自己动手写一个表格拆分与合并小工具
拆分

3. 表格合并

Python实现表格合并的本质是 遍历全部表格数据,然后采用concat方法进行数据合并Pandas学习笔记02-数据合并

因此,在这里我们主要用到两个库:ospandas,其中os用于获取文件夹下全部满足要求的文件信息,pandas用于读取表格数据并进行concat

# 合并表格
def concatTable(folder):
    print('----------正在进行表格合并----------')
    # 新建一个空列表,用于存储表格数据
    fileList = []
    # 把文件夹下表格数据放在一个列表里
    for fileName in os.walk(folder):
        for table in fileName[2]:
            path = fileName[0] + '\\' + table
            if os.path.splitext(path)[1] in ('.xlsx','.xls'):
                li = pd.read_excel(path)
                fileList.append(li)
                print(f'已读取{len(fileList)}个表格...')
            else:
                continue
    # 用concat方法合并表单数据
    result = pd.concat(fileList)
    # 导出数据
    result.to_excel(r'.\合并后文件.xlsx',index=False,sheet_name='汇总')

4. GUI设计

因为要支持表格拆分和合并,我们已经在2和3部分将这两个功能封装为函数了。

关于GUI的功能部分,需要支持以下功能。

对于表格拆分部分,功能点:

  • 选取文件:<code style='font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;line-height: 1.6 !important;'><span style="font-size: 14px;">Text</span><span style="font-size: 14px;">InputText</span><span style="font-size: 14px;">FileBrowse</span>
  • 读取文件后的拆分字段选取:<code style='font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;line-height: 1.6 !important;'><span style="font-size: 14px;">Text</span><span style="font-size: 14px;">Combo</span>
  • 拆分:<span style="font-size: 14px;">Button</span>Text
<p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;line-height: 1.6 !important;">InputText</p>🎜、🎜🎜FileBrowse🎜🎜🎜🎜🎜🎜读取文件后的拆分字段选取:🎜🎜Text🎜🎜、🎜🎜Combo🎜🎜🎜🎜🎜🎜拆分:🎜🎜Button🎜🎜🎜🎜🎜对于表格合并部分,功能点:🎜
  • 选取文件夹:<code style='font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;line-height: 1.6 !important;'><span style="font-size: 14px;">Text</span><span style="font-size: 14px;">InputText</span><span style="font-size: 14px;">FolderBrowse</span>
  • 合并:<span style="font-size: 14px;">Button</span>

此外,我们还需要有用于展示 程序操作记录的输出框、工具操作说明文本以及关闭程序按钮。

基于以上需求,我们可以构建GUI布局如下:

# 布局设置
layout = [[sg.Text(&#39;选择待拆分的文件:&#39;,font=("微软雅黑", 12)),sg.InputText(key=&#39;file&#39;,size=(60,1),font=("微软雅黑", 10),enable_events=True) ,sg.FileBrowse(&#39;打开&#39;,file_types=(("Text Files", "*.xls*"),),font=("微软雅黑", 12))],
          [sg.Text(&#39;选择待拆分的字段:&#39;,font=("微软雅黑", 12)),sg.Combo(&#39;&#39;,tooltip=&#39;选择用于拆分的字段&#39;,font=("微软雅黑", 10), default_value=&#39;&#39;,auto_size_text=True,size=(15, 5),key=&#39;-keys-&#39;),sg.Button(&#39;开始拆分&#39;,font=("微软雅黑", 12))],
          [sg.Text(&#39;选择待合并文件夹:&#39;,font=("微软雅黑", 12)),sg.InputText(key=&#39;Folder&#39;,size=(60,1),font=("微软雅黑", 10),enable_events=True) ,sg.FolderBrowse(&#39;打开文件夹&#39;,font=("微软雅黑", 12)),sg.Button(&#39;开始合并&#39;,font=("微软雅黑", 12))],
          [sg.Text(&#39;程序操作记录:&#39;,justification=&#39;center&#39;)],
          [sg.Output(size=(100, 10),font=("微软雅黑", 10))],  
          [sg.Text(&#39;操作说明:&#39;,font=("微软雅黑", 12))],
          [sg.Text(&#39;表格拆分指引:选择文件—>选择用于拆分的字段—>开始拆分\n表格合并指引:选择需要合并的表格所在文件夹—>开始合并&#39;,font=("微软雅黑", 10)),sg.Text(&#39;&#39;,font=("微软雅黑", 12),size=(35, 1)),sg.Button(&#39;关闭程序&#39;,font=("微软雅黑", 12),button_color =&#39;red&#39;)]
          ]

由于我们在进行表格拆分时需要先选定文件及拆分字段,而拆分字段是在选定文件后读取到的文件数据的表头,所以需要在sg.InputText()中将参数enable_events设置为True,这样选定文件操作就是一个事件,可以触发某些操作。

接下来,我们编写循环事件功能如下:

# 事件循环
while True:
    event, values = window.read()
    if event in (None, &#39;关闭程序&#39;):
        break
    if event == &#39;file&#39;:
        fileName = values[&#39;file&#39;]
        if os.path.exists(fileName):
            df = pd.read_excel(fileName)
            keys = df.columns.to_list()
            window["-keys-"].Update(values = keys,font=("微软雅黑", 10),size=(15, 8))
        else:
            print(&#39;文件不存在\n请先选择正确文件&#39;)
    if event == &#39;开始拆分&#39;:
        if values[&#39;-keys-&#39;]:
            _key = values[&#39;-keys-&#39;]
            splitTable(df,_key)
            print(&#39;----------拆分工作已经完成----------\n&#39;)
        else:
            print(&#39;字段未选择-请先选择字段\n或文件未选取-请先选择文件&#39;)
    if event == &#39;开始合并&#39;:
        if values[&#39;Folder&#39;]:
            folder = values[&#39;Folder&#39;]
            concatTable(folder)
            print(&#39;----------合并工作已经完成----------\n&#39;)
        else:
            print(&#39;待合并文件所在文件夹未选择&#39;)

window.close()

根据需求,我们将事件类型分为三种:

  • 当我们选定待拆分文件后,先读取文件内容,然后获取文件数据的表头,从而刷新( window["-keys-"].Update)拆分字段的下拉框为表头内容;
  • 当我们点击开始拆分按钮时,需要判断拆分字段是否选取(默认为空),若有选定字段则进行拆分操作,否则会进行错误操作提示;
  • 当我们点击开始合并按钮时,需要判断是否选定了文件夹,若是则调用合并数据函数进行合并操作,否则会进行错误操作提示。

5. 打包代码

这里采用的是pyinstaller进行程序代码打包,操作指令如下:

pyinstaller -F -w 表格拆分合并工具.py

部分参数含义:

-F   表示生成单个可执行文件

-w  表示去掉控制台窗口,这在GUI界面时非常有用

-p   表示你自己自定义需要加载的类路径,一般情况下用不到

-i   表示可执行文件的图标

以上是技巧 | 80行代码自己动手写一个表格拆分与合并小工具的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:Python当打之年。如有侵权,请联系admin@php.cn删除