【Python】openpyxl统计2019年数学建模获奖情况【1】

  1 import openpyxl
  2 
  3 class ExceltoExcel():
  4 
  5     def __init__(self, file):
  6         self.universityData = {}
  7         self.wb = openpyxl.load_workbook(file)
  8         self.wb_new =openpyxl.Workbook()  # 新建一个表格来存储生成的数据
  9         self.sheet = self.wb.active
 10         self.new_sheet = self.wb_new.active  # 新表单
 11         self.maxrow = self.sheet.max_row
 12         self.maxcol = self.sheet.max_column
 13 
 14 
 15     def todict(self):
 16         '''
 17         统计每个大学全部的获奖数量,分别列出是几等奖和对应的数量
 18         {'同济大学':{'一等奖':{'team':1,'num'=3},'二等奖':{'team':2,'num'=6},'三等奖':{'team':1,'num'=3},'成功参与奖':{'team':1,'num'=3}},
 19         '清华大学':{'一等奖':{'team':1,'num'=3},'二等奖':{'team':1,'num'=3},'三等奖':{'team':1,'num'=3},'成功参与奖':{'team':1,'num'=3}},...}
 20         统计所有人数
 21         Fill in universityData with each rewardship‘s popularity
 22         '''
 23         # tolal_team = self.maxrow
 24         for row in range(2, self.maxrow + 1):
 25             # 取每个单元格的数据
 26             sheet_col = ['F', 'H', 'J']
 27             rewardcell = self.sheet['D' + str(row)].value  # D列奖项
 28             rewards = ['一等奖', '二等奖', '三等奖', '成功参与奖']
 29             for k in sheet_col:
 30                 university = self.sheet[k + str(row)].value  # 每列大学的名称
 31                 # team = self.sheet['C' + str(row)].value  # C列队伍
 32                 # 确定键值
 33                 self.universityData.setdefault(university, {})
 34                 for reward in rewards:
 35                     if reward == rewardcell:
 36                         self.universityData[university].setdefault(rewardcell, {'team': 0, 'num': 0})
 37                         self.universityData[university][rewardcell]['num'] += 1  # 统计各个奖项的所有人数
 38                     else:
 39                         self.universityData[university].setdefault(reward, {'team': 0, 'num': 0})
 40 
 41                 if k == 'F':
 42                     self.universityData[university][rewardcell]['team'] += 1  # 只统计队长所在大学
 43         self.universityData = sorted(self.universityData.items(), key=lambda item: item[0])  # 按照键值排序返回元祖
 44         self.universityData = dict(self.universityData)  # 将元祖转换成字典
 45         # print('universityData', self.universityData)
 46         # print(type(self.universityData))
 47         return self.universityData
 48 
 49     # 查找单个键
 50     def find(self, target, dictData, notFound='没找到'):
 51         # 倒序查找第一个出现的需要查找的键的值
 52         queue = [dictData]  # 将字典存入列表
 53         while len(queue) > 0:
 54             data = queue.pop()  # data是在queue中取出的最后一个元素,也就是原始字典;此时的queue为空列表[]
 55             print('data', data)
 56             for key, value in data.items():
 57                 if key == target:
 58                     return value
 59                 elif type(value) == dict:
 60                     queue.append(value)
 61         return notFound
 62 
 63     # 有多个同名键在字典里时,可以用这个方法
 64     def findAll(self, target, dictData, notFound=[]):
 65         # 倒序查找所有出现的需要查找的键的值
 66         queue = [dictData]
 67         result = []
 68         while len(queue) > 0:
 69             data = queue.pop()
 70             for key, value in data.items():
 71                 if key == target:
 72                     result.append(value)
 73                 elif type(value) == dict:
 74                     queue.append(value)
 75         if not result: result = notFound
 76         return result
 77 
 78     def write_list_to_excel(self, dictData, num_list, team_list):
 79         list_slice = []  # 人数切片
 80         team_slice = []  # 队伍切片
 81         sublist_sum = []  # 每个人数切片的和
 82         team_sum = []  # 每个队伍切片的和
 83         k = 0
 84         row_1 = ['学校名称','一等奖','二等奖','三等奖','成功参与奖','总人数','队伍数量']
 85         for i in range(len(row_1)):
 86             self.new_sheet.cell(row=1,column=i+1,value=row_1[i])
 87         university_name = []
 88         for key in dictData.keys():
 89             university_name.append(key)
 90         for index, name in enumerate(university_name):
 91             self.new_sheet['A'+str(index+2)] = name
 92         while k < len(num_list):
 93             sub_list = num_list[k:k+4]  # 人数子集
 94             team_sub = team_list[k:k+4]  # 队伍子集
 95             list_slice.append(sub_list)  # 切片后存入列表
 96             team_slice.append(team_sub)
 97             sumlist = sum(sub_list)  # 计算每个子集的和
 98             teamsum = sum(team_sub)
 99             sublist_sum.append(sumlist)  # 将每个子集的和加入列表
100             team_sum.append(teamsum)
101             k += 4
102             if k > len(num_list):
103                 break
104         for row in range(2, len(university_name)+2):
105             for col in range(2, 6):
106                 self.new_sheet.cell(column=col, row=row, value=list_slice[row-2][col-2])
107             self.new_sheet.cell(column=6, row=row, value=sublist_sum[row-2])
108             self.new_sheet.cell(column=7, row=row, value=team_sum[row - 2])
109         self.wb_new.save('result.xlsx')
110         print('共有{}支队伍参赛'.format(sum(team_sum)))
111         return university_name, list_slice, sublist_sum
112 
113 
114 if __name__ == '__main__':
115     excel1 = ExceltoExcel('example_A.xlsx')
116     dictData = excel1.todict()
117     # find_one = excel1.find('team', dictData)
118     find_num = excel1.findAll('num', dictData)
119     find_team = excel1.findAll('team', dictData)
120     find_num.reverse()
121     find_team.reverse()
122     # print(find_num)
123     # print(find_team)
124     university, list_slice, sublist_sum = excel1.write_list_to_excel(dictData,find_num, find_team)
125     # print('university name', university)
126     # print('list_slice', list_slice)
127     # print('sublist_sum', sublist_sum)

保存新的表格(部分):

统计了一个表格中每个大学每个奖项的获奖人数与队伍数量,队伍只统计队长所在的学校

以下代码读取某一文件夹下的所有Excel表格(比如读取A~F题获奖名单总共6个Excel表格),统计每道题也就是每个表格中每个大学的获奖情况并将其写入同一个Excel结果文件中:

  1 import openpyxl
  2 import os
  3 
  4 class ExceltoExcel():
  5 
  6     def __init__(self, file, new_sheet):
  7         self.universityData = {}
  8         self.wb = openpyxl.load_workbook(file)
  9         # self.wb_new =openpyxl.Workbook()  # 新建一个表格来存储生成的数据
 10         self.sheet = self.wb.active
 11         self.new_sheet = new_sheet  # 新表单
 12         self.maxrow = self.sheet.max_row
 13         self.maxcol = self.sheet.max_column
 14 
 15 
 16     def todict(self):
 17         '''
 18         统计每个大学全部的获奖数量,分别列出是几等奖和对应的数量
 19         {'同济大学':{'一等奖':{'team':1,'num'=3},'二等奖':{'team':2,'num'=6},'三等奖':{'team':1,'num'=3},'成功参与奖':{'team':1,'num'=3}},
 20         '清华大学':{'一等奖':{'team':1,'num'=3},'二等奖':{'team':1,'num'=3},'三等奖':{'team':1,'num'=3},'成功参与奖':{'team':1,'num'=3}},...}
 21         统计所有人数
 22         Fill in universityData with each rewardship‘s popularity
 23         '''
 24         # tolal_team = self.maxrow
 25         for row in range(2, self.maxrow + 1):
 26             # 取每个单元格的数据
 27             sheet_col = ['F', 'H', 'J']
 28             rewardcell = self.sheet['D' + str(row)].value  # D列奖项
 29             rewards = ['一等奖', '二等奖', '三等奖', '成功参与奖']
 30             for k in sheet_col:
 31                 university = self.sheet[k + str(row)].value  # 每列大学的名称
 32                 # team = self.sheet['C' + str(row)].value  # C列队伍
 33                 # 确定键值
 34                 self.universityData.setdefault(university, {})
 35                 for reward in rewards:
 36                     if reward == rewardcell:
 37                         self.universityData[university].setdefault(rewardcell, {'team': 0, 'num': 0})
 38                         self.universityData[university][rewardcell]['num'] += 1  # 统计各个奖项的所有人数
 39                     else:
 40                         self.universityData[university].setdefault(reward, {'team': 0, 'num': 0})
 41 
 42                 if k == 'F':
 43                     self.universityData[university][rewardcell]['team'] += 1  # 只统计队长所在大学
 44         self.universityData = sorted(self.universityData.items(), key=lambda item: item[0])  # 按照键值排序返回元祖
 45         self.universityData = dict(self.universityData)  # 将元祖转换成字典
 46         # print('universityData', self.universityData)
 47         # print(type(self.universityData))
 48         return self.universityData
 49 
 50     # 查找单个键
 51     def find(self, target, dictData, notFound='没找到'):
 52         # 倒序查找第一个出现的需要查找的键的值
 53         queue = [dictData]  # 将字典存入列表
 54         while len(queue) > 0:
 55             data = queue.pop()  # data是在queue中取出的最后一个元素,也就是原始字典;此时的queue为空列表[]
 56             print('data', data)
 57             for key, value in data.items():
 58                 if key == target:
 59                     return value
 60                 elif type(value) == dict:
 61                     queue.append(value)
 62         return notFound
 63 
 64     # 有多个同名键在字典里时,可以用这个方法
 65     def findAll(self, target, dictData, notFound=[]):
 66         # 倒序查找所有出现的需要查找的键的值
 67         queue = [dictData]
 68         result = []
 69         while len(queue) > 0:
 70             data = queue.pop()
 71             for key, value in data.items():
 72                 if key == target:
 73                     result.append(value)
 74                 elif type(value) == dict:
 75                     queue.append(value)
 76         if not result: result = notFound
 77         return result
 78 
 79     def write_list_to_excel(self, dictData, num_list, team_list):
 80         list_slice = []  # 人数切片
 81         team_slice = []  # 队伍切片
 82         sublist_sum = []  # 每个人数切片的和
 83         team_sum = []  # 每个队伍切片的和
 84         k = 0
 85         row_1 = ['学校名称','一等奖','二等奖','三等奖','成功参与奖','总人数','队伍数量']
 86         for i in range(len(row_1)):
 87             self.new_sheet.cell(row=1,column=i+1,value=row_1[i])
 88         university_name = []
 89         for key in dictData.keys():
 90             university_name.append(key)
 91         for index, name in enumerate(university_name):
 92             self.new_sheet['A'+str(index+2)] = name
 93         while k < len(num_list):
 94             sub_list = num_list[k:k+4]  # 人数子集
 95             team_sub = team_list[k:k+4]  # 队伍子集
 96             list_slice.append(sub_list)  # 切片后存入列表
 97             team_slice.append(team_sub)
 98             sumlist = sum(sub_list)  # 计算每个子集的和
 99             teamsum = sum(team_sub)
100             sublist_sum.append(sumlist)  # 将每个子集的和加入列表
101             team_sum.append(teamsum)
102             k += 4
103             if k > len(num_list):
104                 break
105         for row in range(2, len(university_name)+2):
106             for col in range(2, 6):
107                 self.new_sheet.cell(column=col, row=row, value=list_slice[row-2][col-2])
108             self.new_sheet.cell(column=6, row=row, value=sublist_sum[row-2])
109             self.new_sheet.cell(column=7, row=row, value=team_sum[row - 2])
110         return university_name, list_slice, sublist_sum, team_sum
111 
112 
113 if __name__ == '__main__':
114     file_path = './file'  # excel文件路径
115     files = []  # 存储excel文件名
116     list = os.listdir(file_path)  # 列出excel文件路径下所有的文件
117     list.sort(key=lambda x: x[4:5])  # 按照题目顺序排序
118     # print('list', list)
119     for i in range(len(list)):
120         item = os.path.join(file_path, list[i])
121         files.append(item)
122     # print('files', files)
123     wb_new = openpyxl.Workbook()  # 新建一个表格来存储生成的数据
124     f = open('result.txt', 'w')
125     for k,file in enumerate(files):
126         new_sheet = wb_new.create_sheet('list', index=k)  # 插入新表单
127         excel = ExceltoExcel(file, new_sheet)
128         dictData = excel.todict()  # 得到当前表格排序后的字典
129         # find_one = excel1.find('team', dictData)
130         find_num = excel.findAll('num', dictData)  # 查找当前表格每个大学每个奖项的获奖人数
131         find_team = excel.findAll('team', dictData)  # # 查找当前表格每个大学每个奖项的获奖队伍数,只统计队长所在的学校
132         find_num.reverse()  # 正序排列
133         find_team.reverse()  # 正序排列
134         # print(find_num)
135         # print(find_team)
136         _, _, _, team_sum = excel.write_list_to_excel(dictData,find_num, find_team)
137         wb_new.save('result.xlsx')
138         # print('university name', university)
139         # print('list_slice', list_slice)
140         # print('sublist_sum', sublist_sum)
141         title = file.split('/')[2][4:5]  # 字符串分割提取题目,原标题为'./file/2019A.xlsx'
142         print('{}题共有{}支队伍获奖'.format(title, sum(team_sum)))
143         f.write('{}题共有{}支队伍获奖\n'.format(title, sum(team_sum)))
1 A题共有781支队伍获奖
2 B题共有888支队伍获奖
3 C题共有1057支队伍获奖
4 D题共有4259支队伍获奖
5 E题共有4193支队伍获奖
6 F题共有781支队伍获奖

我这里的F题获奖名单和A题是相同的,所以A和F的统计结果相同。

 

posted @ 2020-04-18 15:51  DJames23  阅读(395)  评论(0编辑  收藏  举报