1、问题
对成绩单信息进行统计,包括试卷中各个题目的得分情况。由于手动统计太过费时,因此想到使用python进行处理,处理文件类型为.xlsx
2、使用python库
①xlrd
:读取excel数据(只能读取)
如果只想读excel文件可以使用,安装时不要使用pip install xlrd
,存在版本不一致问题。
正确安装:进入python官网下载http://pypi.python.org/pypi/xlrd模块安装,但需要注意版本,我在使用xlrd2.0.1读取文件(xlrd.open_workbook())时报错:xlrd.biffh.XLRDError: Excel xlsx file; not supported
。其实是版本不一致,xlrd版本过高。
最终下载的xlrd3,也是从官网下载的安装包:https://pypi.org/project/xlrd3/,利用pip install xxxxx.whl
安装使用时import xlrd3
,python版本为3.7
②xlwt
:写入excel文件,同样,在使用pip install xlwt时安装失败,进入官网下载安装包:https://pypi.org/project/xlwt
以上两个库只能单独读取或写入excel文件,对于既读又写很麻烦,因此我最终使用的是openpyxl。
**③openpyxl
:**直接使用pip install安装失败,进入https://pypi.org/project/openpyxl下载安装包。
3、使用:只对单元格的数据进行读取和写入
①xlrd3
:xlrd3.open_workbook(path)
打开xlsx文件;sheet_by_index(0)
根据索引找到第一个工作簿,也可以根据工作表的名字定位;.cell_value(j+1, i+3))
根据行-列定位单元格,读取单元格数据,注意从0开始。
import xlrd3
test_score = [5., 10., 20., 20., 15., 6., 6., 6., 6., 6.] # 每小题分数
path = 'XXXXX\\成绩单.xlsx'
excel_ = xlrd3.open_workbook(path) # 打开文件
table_1 = excel_.sheet_by_index(0) # 也可以直接根据工作表的名字读取
person_ = [[] for i in range(11)] # 存单元格数据
for i in range(11): # 题号/ 列号
for j in range(6): # 人数
print(table_1.cell_value(j+1, i+3)) # 按单元格读取数据
if table_1.cell_value(j+1, i+3) != '' and table_1.cell_value(j+1, i+3) != '旷考':
person_[i].append(table_1.cell_value(j+1, i+3))
# 统计
count = 0
for k in range(len(person_[i])):
if person_[i][k] <= test_score[i] * 1.0 and person_[i][k] >= test_score[i] * 0.9: # 统计
count += 1
由于我只是做简单的统计,涉及用法不多,其他的可以参考:
https://blog.csdn.net/miaoca/article/details/120129553
https://blog.csdn.net/u013250071/article/details/81911434
②openpyxl
:
load_workbook(path)
打开xlsx文件;excel_['Sheet1']
根据工作簿名字定位;cell(j, i).value
根据行-列定位单元格,读取单元格数据,注意从1开始。想要在k行m列写入新的数据时,直接对单元格进行赋值,cell(k,m).value=x
。更改后直接使用save保存文件就可以,为避免覆盖原文件可以重命名。
from openpyxl import workbook, load_workbook
test_score = [5., 10., 20., 20., 15., 6., 6., 6., 6., 6., 100., 100., 100., 100.]
path = 'XXXXX\\成绩单.xlsx'
excel_ = load_workbook(path) # 载入文件
table_1 = excel_['Sheet1'] # 根据工作表名字定位
person_ = [[] for i in range(14)]
print(person_)
for i in range(14): # 列号
if i != 11:
for j in range(82): # 行号
# print(table_1.cell(j+2, i+4).value)
if table_1.cell(j+2, i+4).value != '' and table_1.cell(j+2, i+4).value != '旷考' and table_1.cell(j+2, i+4).value != None:
person_[i].append(float(table_1.cell(j+2, i+4).value))
# 统计
# 0.9 - 1.0
count = 0
for k in range(len(person_[i])):
if person_[i][k] <= test_score[i] * 1.0 and person_[i][k] >= test_score[i] * 0.9:
count += 1
# print(j, count)
table_1.cell(j+3, i+4).value = count # 写入数据
# 0.8 - 0.9
count = 0
for k in range(len(person_[i])):
if person_[i][k] < test_score[i] * 0.9 and person_[i][k] >= test_score[i] * 0.8:
count += 1
# print(j, count)
table_1.cell(j+4, i+4).value = count
# 0.7 - 0.8
count = 0
for k in range(len(person_[i])):
if person_[i][k] < test_score[i] * 0.8 and person_[i][k] >= test_score[i] * 0.7:
count += 1
# print(j, count)
table_1.cell(j + 5, i + 4).value = count
# 0.6 - 0.7
count = 0
for k in range(len(person_[i])):
if person_[i][k] < test_score[i] * 0.7 and person_[i][k] >= test_score[i] * 0.6:
count += 1
# print(j, count)
table_1.cell(j + 6, i + 4).value = count
# 0. - 0.6
count = 0
for k in range(len(person_[i])):
if person_[i][k] < test_score[i] * 0.6:
count += 1
# print(j, count)
table_1.cell(j + 7, i + 4).value = count
# max
max_ = max(person_[i])
table_1.cell(j + 8, i + 4).value = max_
# min
min_ = min(person_[i])
table_1.cell(j + 9, i + 4).value = min_
# average
average = sum(person_[i])/len(person_[i])
table_1.cell(j + 10, i + 4).value = average
excel_.save('XXXXX\\成绩单(副本).xlsx') # 更新工作表,为避免覆盖原工作表,可以另存
其他关于单元格处理、绘图、样式设置可参见:
https://blog.csdn.net/weixin_41546513/article/details/109555832
4、其他:
①在处理通过公式计算得到的单元格时,读取时读到的并不是数据,而是公式,如(2,3)=(2,1)*0.9+(2,2)*0.1,在读(2,3)时得到的是(2,1)*0.9+(2,2)*0.1,此时可以先复制数据→清空单元格内容→只粘贴数值。