xlrd、xlwt读写excel实战
实战背景
需求给一个excel,里面有两列(一个是大类key,一个小类value)是需要按照逻辑输出值的。其中一个大类是对应多个小类的,涉及excle的合并操作。加工后的目标数据类似json格式:{‘大类’:{小类1:,小类2:}}。加工后的数据要是大类或者小类不存在 就把excle对应行标红色(大类存在小类值为空等也可以实现)
代码
import xlrd
import main
import xlwt
#返回合并excel信息
def merge_cell(sheet_info):
'''
#handle Merge transverse cells and handle Merge Vertical Cells, assign empty cells,
:param rlow:row, include row exclusive of row_range
:param rhigh:row_range
:param clow:col, include col exclusive of col_range
:param chigh:col_range
:param sheet_info:object of sheet
:return:dic contain all of empty cells value
'''
merge = {}
merge_cells = sheet_info.merged_cells
for (rlow, rhigh, clow, chigh) in merge_cells:#起始行,结束行,起始列,结束列
value_mg_cell = sheet_info.cell_value(rlow, clow)
if rhigh-rlow == 1:
# Merge transverse cells
for n in range(chigh-clow-1):
merge[(rlow, clow+n+1)] = value_mg_cell
elif chigh-clow == 1:
# Merge Vertical Cells
for n in range(rhigh-rlow-1):
merge[(rlow+n+1, clow)] = value_mg_cell
return merge
def list_dic(list1,list2):
'''
two lists merge a dict,a list as key,other list as value
:param list1:key
:param list2:value
:return:dict
'''
dic = dict(map(lambda x,y:[x,y], list1,list2))
return dic
def read_excle(filename):
'''
读excle
:param filename: 文件所在路径
:return: apply_dic;每一行作为一个字典形如:{'列名':value};结果形如:[[{}],[{}]]
'''
apply_dic = []
with xlrd.open_workbook(filename,formatting_info=True) as workbook:
name_sheets = workbook.sheet_names() # 获取Excel的sheet表列表,存储是sheet表名
for index in name_sheets: # for 循环读取每一个sheet表的内容
sheet_info = workbook.sheet_by_name(index) # 根据表名获取表中的所有内容,sheet_info也是列表,列表中的值是每个单元格里值
first_line = sheet_info.row_values(0) # 获取首行,我这里的首行是表头,我打算用表头作为字典的key,每一行数据对应表头的value,每一行组成一个字典
values_merge_cell = merge_cell(sheet_info) # 这里是调用处理合并单元格的函数
for i in range(1, sheet_info.nrows): # 开始为组成字典准备数据
other_line = sheet_info.row_values(i)
for key in values_merge_cell.keys():
if key[0] == i:
other_line[key[1]] = values_merge_cell[key]
# print(other_line)
dic = list_dic(first_line, other_line) # 调用组合字典的函数,传入key和value,字典生成
apply_dic.append(dic)
return apply_dic
def compare_dic(key,value,dic):
#判断大类是否存在目标字典:0-大类不存在;1-小类不存在;2小类为空;3小类有值
if key in dic.keys():
#判断小类是否存在字典
# if value in (dic.values())[key].keys():
if value in dic[key]:
#判断小类是否为:'',None
if str(dic[key][value]).strip()=='' or dic[key][value]==None:
#值为空
return 2
else:
return 3#有值
else:
#小类不存在
return 1
else:
#key不存在目标字典
return 0
def write_excle(filename,filename1,dic):
#8 through 63. 0 = Black, 1 = White, 2 = Red, 3 = Green, 4 = Blue, 5 = Yellow, 6 = Magenta, 7 = Cyan, 16 = Maroon, 17 = Dark Green, 18 = Dark Blue, 19 = Dark Yellow , almost brown), 20 = Dark Magenta, 21 = Teal, 22 = Light Gray, 23 = Dark Gray, the list goes on
# 创建一个workbook 设置编码
workbook = xlwt.Workbook(encoding='utf-8')
# 创建一个worksheet# 创建一个workbook 设置编码
worksheet = workbook.add_sheet('My Worksheet',cell_overwrite_ok=True) # 表名
# 写入excel
# 参数对应 行, 列, 值
pattern = xlwt.Pattern() # Create the Pattern
pattern.pattern = xlwt.Pattern.SOLID_PATTERN # May be: NO_PATTERN, SOLID_PATTERN, or 0x00 through 0x12
pattern.pattern_fore_colour = 2
# May be: 8 through 63. 0 = Black, 1 = White, 2 = Red, 3 = Green, 4 = Blue, 5 = Yellow, 6 = Magenta, 7 = Cyan, 16 = Maroon, 17 = Dark Green, 18 = Dark Blue, 19 = Dark Yellow , almost brown), 20 = Dark Magenta, 21 = Teal, 22 = Light Gray, 23 = Dark Gray, the list goes on...
style = xlwt.XFStyle() # Create the Pattern
style.pattern = pattern # Add Pattern to Style
apply_dic=read_excle(filename)
for i in range(len(apply_dic)):
for j in range(len(apply_dic[i])):
worksheet.write(0, j, tuple(apply_dic[i].keys())[j])#写表头
key=apply_dic[i]['英文分类'].strip()
value=apply_dic[i]['字段key'].strip()
comparedic=compare_dic(key,value,dic)
print(key)
print(value)
print(comparedic)
#大类存在,小类有值
if comparedic ==3:
worksheet.write(i + 1, j, tuple(apply_dic[i].values())[j]) # 表格内容
#大类存在,小类不存在 或者大类不存在
elif comparedic ==0 or comparedic==1:
worksheet.write(i + 1, j, tuple(apply_dic[i].values())[j],style)
else:
worksheet.write(i + 1, j, tuple(apply_dic[i].values())[j])
#判断大类是否存在目标字典:0-大类不存在;1-小类不存在;2小类为空;3小类有值
workbook.save(filename1)
# 保存
if __name__=='__main__':
filename=f'{main.BASE_DIR}/dataCenter/IDFY对接新增输入项0424版.xls'
filename1 = f'{main.BASE_DIR}/dataCenter/IDFY对接新增输入项0424版1.xls'
from dataCenter.compare_data import comare_data#引入实际json格式数据
write_excle(filename, filename1, comare_data)
效果
略