Python 批量处理大学校运会报名 Excel 表格,多表整合、数据汇总及统计 实例

前言:

上一篇博客,介绍了一个简单的实例:给已有Excel表格添加序号、增加新列,主要是介绍 xlrd 与 xlwt 两个模块是如何在一起工作的。

这一篇我们来介绍另外一个实例,相对来说会复杂与贴近日常工作一点。

需求:

假设:需完成一份报名工作,将已做好报名表下发到各个报名单位。他们按格式填好报名表、上交,最后由你负责信息汇总和统计。

这样一份任务其实比较简单、常见,但当报名单位众多,如有几千份报名表需要统计时,个人操作起来还是很费时费力的,也可能会出现信息统计错误的情况。

模拟的具体案例:完成校运会报名表汇总、统计工作。

假设每个班级按校运会报名表填写了该班级的学生报名信息,需要你汇总、统计成一张Excel表格。

Excel表格 汇总信息 sheet 里包含所有学生的报名信息,其他sheet表 是每个校运会运动项目学生的报名信息表。

单个的报名表截图如下:

在这里插入图片描述
作为试验,我们做了五个Excel表格,放在了项目文件下的 tables 文件夹:

在这里插入图片描述
注:Excel文件名无所谓(最好不要有中文和特殊字符)。

我们希望做成的汇总数据表如下:

在这里插入图片描述

主要思路及实现代码:

1、先获取目标文件路径下的所有Excel文件:

这里用的是 os 模块的 walk 方法来获取:

# 先遍历目录下文件
path = './tables' # 此处用的是相对路径(如自己试验,需注意自己的文件路径)
f = os.walk(path)
files = []  # xls 文件列表
# 获取目录下文件
for dir_path, dir_names, file_names in f:
    for file in file_names:
        # 筛选目录下xls格式文件
        if '.xls' in file:
            files.append(file)

print(files) # 测试获取的文件
# 打印结果:
# ['5.xls', '1.xls', '2.xls', '3.xls', '4.xls']

经过上面的代码,我们已经获取到了我们想要的Excel表格文件。

2、读取所有Excel表格数据:

分析: 因为我们要读取多个文件数据,每个文件的数据结构比较一致,后期还要进行数据汇总与统计工作。
所以在前期选好一个 数据结构来存储数据 ,是非常重要的。这里决定先设计一个包含列表的列表来存储数据,数据结构示意:
[[[第一行数据:学院班级信息],[第二行数据: 报名信息字段], [第三行数据:报名信息]…], [第二个表数据],[],…]

这里不用字典结构来存储数据,是为了后期统计数据方便。如果按照逻辑来说,用字典的键对应文件名或学院班级信息,值对应该班级报名信息更合理些。

读取数据也比较关键,先定义了一个读取单个表格数据的函数:

# 定义读取单个 excel 文件数据
def read_excel(name):
    file_path = path + '/'+ name
    work_book = xlrd.open_workbook(file_path)
    sheet = work_book.sheet_by_index(0)
    return sheet._cell_values[1:]

# 测试一下:
print(read_excel(files[0]))
# ------运行结果------
# [['学院:', '机械学院', '', '年级:', 2015.0, '专业:', '模具设计', ''], 
# ['姓名', '学号', '性别', '年龄', '参赛项目', '是否参加往届过校运会', '能否参加集训', '联系方式'], 
# ['阮小二', 150914031.0, '男', 23.0, '10000米', '否', '能', 15854441586.0], 
# ['阮小五', 150914025.0, '男', 21.0, '400米', '否', '能', 17054661590.0], 
# ['阮小七', 150914010.0, '男', 22.0, '1000米', '否', '能', 18953000549.0],
# ...
# ------运行结果------

可以看到,写的方法可以成功的读取到单个表格的数据(忽略数据内容…,人名太难想了…)。

有了这个方法读取所有表格的数据就很简单了,这里用的是列表推导式:

# 读取目录下所有数据
sign_data = [read_excel(name) for name in files]
print(sign_data)  # 测试读取到的所有数据
# ------运行结果------
# [[['学院:', '机械学院', '', '年级:', 2015.0, '专业:', '模具设计', ''], 
# ['姓名', '学号', '性别', '年龄', '参赛项目', '是否参加往届过校运会', '能否参加集训', '联系方式'], 
# ['阮小二', 150914031.0, '男', 23.0, '10000米', '否', '能', 15854441586.0], 
# ['阮小五', 150914025.0, '男', 21.0, '400米', '否', '能', 17054661590.0], 
# ['阮小七', 150914010.0, '男', 22.0, '1000米', '否', '能', 18953000549.0], 
# ['时迁', 150914034.0, '男', 22.0, '乒乓球', '否', '能', 15468081558.0], 
# ['顾大嫂', 150914042.0, '女', 21.0, '羽毛球', '否', '能', 15509431558.0], 
# ...
# ------运行结果------
3、按需求汇总数据:

在数据处理这一步,选择列表嵌套列表的数据结构优势就体现出来了:

# 按照汇总要求整理数据
summary_data = []
for data in sign_data:
    for d in data[2:]:
        # 在每条报名信息中插入学院、年级、专业信息
        d.insert(0,data[0][6])  # 专业信息
        d.insert(0,data[0][4])  # 年级信息
        d.insert(0,data[0][1])  # 学院信息
        summary_data.append(d)
print(summary_data)  # 测试汇总数据
# ------运行结果------
# [['机械学院', 2015.0, '模具设计', '阮小二', 150914031.0, '男', 23.0, '10000米', '否', '能', 15854441586.0], 
# ['机械学院', 2015.0, '模具设计', '阮小五', 150914025.0, '男', 21.0, '400米', '否', '能', 17054661590.0], 
# ['机械学院', 2015.0, '模具设计', '阮小七', 150914010.0, '男', 22.0, '1000米', '否', '能', 18953000549.0], 
# ['机械学院', 2015.0, '模具设计', '时迁', 150914034.0, '男', 22.0, '乒乓球', '否', '能', 15468081558.0], 
# ['机械学院', 2015.0, '模具设计', '顾大嫂', 150914042.0, '女', 21.0, '羽毛球', '否', '能', 15509431558.0], 
# ...
# ------运行结果------

注:这里按汇总信息sheet表的要求,已为每条报名数据加上了学院、年级、专业信息,列表所有数据相当于是独立的,即与原来的每个文件已没有关系了。

这里还用代码获取了一下 汇总sheet 表里要用到的信息名称字段:

# 报名字段列表
sign_keys = sign_data[0][1]
# 汇总表格字段操作
summary_key = sign_keys[:]
summary_key.insert(0,'专业信息')
summary_key.insert(0,'年级信息')
summary_key.insert(0,'学院信息')
print(summary_key)  # 测试汇总字段
# 打印结果
# ['学院信息', '年级信息', '专业信息', '姓名', '学号', '性别', '年龄', '参赛项目', '是否参加往届过校运会', '能否参加集训', '联系方式']
4、按照校运会运动项目统计报名信息:

1、获取校运会运动项目列表:

# 获取校运会运动项目清单
sports = []
for data in summary_data:
    if data[7] not in sports:
        sports.append(data[7])
print(sports) # 测试
# 打印结果:
# ['10000米', '400米', '1000米', '乒乓球', '羽毛球', '铅球', '跳高', '100米', '跳远', '游泳', '竞走']

因为我们没有所有运动项目的数据,所以需先获取所有报名 Excel 表格里的参赛项目信息。

2、按运动项目筛选报名信息:

选择字典来存储各个运动项目的报名信息:

# 按运动项目筛选报名信息
sport_data = {}
for sport in sports:
    sport_data[sport] = []
    for data in summary_data:
        if sport == data[7]:
            sport_data[sport].append(data)

print(sport_data) # 测试
# ------运行结果------
# {'10000米': [['机械学院', 2015.0, '模具设计', '阮小二', 150914031.0, '男', 23.0, '10000米', '否', '能', 15854441586.0], 
# ['化学学院', 2015.0, '分析化学', '孙悟空', 150813031.0, '男', 19.0, '10000米', '否', '能', 15854891586.0], 
# ['机械学院', 2016.0, '自动化', '鲁智深', 160814031.0, '男', 23.0, '10000米', '否', '能', 15854331586.0]], 
# '400米': [['机械学院', 2015.0, '模具设计', '阮小五', 150914025.0, '男', 21.0, '400米', '否', '能', 17054661590.0], 
# ['马克思学院', 2016.0, '思想政治教育', '张三', 160813025.0, '男', 20.0, '400米', '否', '能', 17054891586.0], 
# ['马克思学院', 2016.0, '思想政治教育', '曾漂亮', 160813032.0, '女', 20.0, '400米', '否', '能', 17054891586.0], 
# ...
# ------运行结果------

请忽略姓名…

5、将数据写入Excel表格

用 xlwt 模块新建一个 Excel 文件,创建 ‘汇总信息’ sheet表写入汇总信息,其他 sheet 写入相应运动项目报名者信息。

work_book = xlwt.Workbook()
sheet_0 = work_book.add_sheet('汇总信息')
sheet_0.write_merge(0,0,0,10,'xx大学校运会报名信息表')
# 写入汇总表格报名信息字段
for col,string in enumerate(summary_key):
    sheet_0.write(1,col,string)

# 写入汇总数据
for row,ds in enumerate(summary_data):
    for col,d in enumerate(ds):
        sheet_0.write(row+2,col,d)

# 写入各个运动项目的报名信息sheet表
for sport,s_ds in sport_data.items():
    # 增加sheet表
    s_sheet = work_book.add_sheet(sport)
    # 在sheet表中增加数据
    s_sheet.write_merge(0,0,0,10,'%s参赛项目报名人员信息汇总' % sport)
    for col, string in enumerate(summary_key):
        s_sheet.write(1, col, string)
    # 写入具体报名人员信息
    for row,ds in enumerate(s_ds):
        for col, d in enumerate(ds):
            s_sheet.write(row + 2, col, d)

# 保存表格
work_book.save('summary_sign.xls')

这里的代码主要是利用 xlwt 模块写入数据,逻辑比较简单,直接看最后的文件截图吧。

新建的 summary_sign.xls 文件部分数据截图:

在这里插入图片描述

全部代码:

以下是该实例的全部代码:

import xlrd
import xlwt
import os

# 获取目录下文件
# 先遍历目录下文件
path = './tables' # 此处用的是相对路径(注意自己的文件路径)
f = os.walk(path)
files = []  # xls 文件列表
# 获取目录下文件
for dir_path, dir_names, file_names in f:
    for file in file_names:
        # 筛选目录下xls格式文件
        if '.xls' in file:
            files.append(file)

# 用 xlrd 读取Excel文件数据
# 定义读取单个 excel 文件数数据
def read_excel(name):
    file_path = path + '/'+ name
    work_book = xlrd.open_workbook(file_path)
    sheet = work_book.sheet_by_index(0)
    return sheet._cell_values[1:]

# 读取目录下所有数据
sign_data = [read_excel(name) for name in files]

# 按照汇总要求整理数据
summary_data = []
for data in sign_data:
    for d in data[2:]:
        # 在每条报名信息中插入学院、年级、专业信息
        d.insert(0,data[0][6])  # 专业信息
        d.insert(0,data[0][4])  # 年级信息
        d.insert(0,data[0][1])  # 学院信息
        summary_data.append(d)

# 报名字段列表
sign_keys = sign_data[0][1]
# 汇总表格字段操作
summary_key = sign_keys[:]
summary_key.insert(0,'专业信息')
summary_key.insert(0,'年级信息')
summary_key.insert(0,'学院信息')


# 获取校运会运动项目清单
sports = []
for data in summary_data:
    if data[7] not in sports:
        sports.append(data[7])

# 按运动项目筛选报名信息
sport_data = {}
for sport in sports:
    sport_data[sport] = []
    for data in summary_data:
        if sport == data[7]:
            sport_data[sport].append(data)

# 写入数据
work_book = xlwt.Workbook()
sheet_0 = work_book.add_sheet('汇总信息')
sheet_0.write_merge(0,0,0,10,'xx大学校运会报名信息表')
# 写入汇总表格报名信息字段
for col,string in enumerate(summary_key):
    sheet_0.write(1,col,string)

# 写入汇总数据
for row,ds in enumerate(summary_data):
    for col,d in enumerate(ds):
        sheet_0.write(row+2,col,d)

# 写入各个运动项目的报名信息sheet表
for sport,s_ds in sport_data.items():
    # 增加sheet表
    s_sheet = work_book.add_sheet(sport)
    # 在sheet表中增加数据
    s_sheet.write_merge(0,0,0,10,'%s参赛项目报名人员信息汇总' % sport)
    for col, string in enumerate(summary_key):
        s_sheet.write(1, col, string)
    # 写入具体报名人员信息
    for row,ds in enumerate(s_ds):
        for col, d in enumerate(ds):
            s_sheet.write(row + 2, col, d)

# 保存表格
work_book.save('summary_sign.xls')

注:以上代码,很多信息其实未具体指定,如有哪些运动项目、班级信息、专业信息等。数据内容字段(如:学院信息, 年级信息, 专业信息…)这些都是直接从表格里获取的。也就是说 该代码的复用性是比较高的,换做其他报名信息的统计,稍微改动一下,应该就可以运行了

结尾:

以上就是本篇博客的全部内容,项目也不难,就100来行代码吧,想要原 Excel 表格文件来测试一下代码的朋友可私信、留言 ,感觉阅读。

【Python与Excel表格】专栏

着重介绍 Python xlwt、xlrd 等模块操作 Excel 表格文件的方法,也会搭配一些实例演练,强化所讲知识点的理解与运用。
感兴趣的朋友,可以点个关注或收藏。 创作不易,你的支持是我最大的动力,感谢 !

猜你喜欢

转载自blog.csdn.net/zhouz92/article/details/106962126