关于python操作excel的库,实在太多了。但是各有千秋。下面俺根据实际经验,说一下xlwings库与openpyxl库这两个库的综合使用心得。
因为在实际的工作中,我们可能会遇到很多电子表格。有xls格式的,也有xlsx格式的。目前还难找到完美的操作这两种格式的库。
我的困境是:需要针对大量的xls格式和xlsx格式文件进行扫描并逐一对每个工作薄的所有工作表的所有单元格进行逐一校验,因此,即要解决格式问题,还要解决速度上的效率问题。
经过实战,唯有使用xlwings库与openpyxl库这两个库相结合,方能解决问的问题。
一、xlwings库
能同时打开xls格式和xlsx格式,并且还能打开xls格式后另存为xlsx格式,这样就解决了我的很多问题,至少能解决统一格式的问题。
但是,如果使用这个库逐一扫描工作薄的所有工作表的每一个单元格的话,速度相当慢。因此,该问题靠openpyxl库l来解决。
二、openpyxl库
优点是逐一扫描工作薄的所有工作表的每一个单元格的话,速度快很多。缺点是只能操作xlsx格式。因此,唯有两张配合使用,方能解决问题。
三、配合使用
A、使用xlwings库
使用这个库的目的是校验哪些表格能打开,哪些不能打开。排除不能打开的,而能打开的那些,另存为xlsx格式的。下面是一些示例代码
ExcelNewpath = '原始目录/'
UpdateExcelPath = '排查后的目录/'
app = xw.App(visible=False, add_book=False)
# 显示警报
app.display_alerts = True
# 屏幕更新(应用中)
app.screen_updating = False
m=0
for excelname in excel_names_list:#将xls格式转为xlsx格式,方便后面的openpyxl的操作
try:
m+=1
print('正在分析:',excelname,'当前是第',m,'个','共',len(excel_names_list),'个')
mybook = app.books.open(ExcelNewpath+excelname)
if excelname.split('.')[1].upper()=='XLS':
mybook.save(UpdateExcelPath+excelname.split('.')[0]+'.xlsx')#另存为xlsx格式并保存到新目录UpdateExcelPath
print('已完成',excelname,'转为xlsx格式的转换')
else:
mybook.save(UpdateExcelPath+excelname)#如果是xlsx则按原格式保存
#mybook.save()
print('已完成',excelname,'原格式的保存,不需要转换')
mybook.close()
except Exception as e:
print(excelname,'打开失败,文件已损坏',e)#文件损坏的进行提示并作记录
f=open('openfail.txt','a',encoding='utf-8')
f.write(str(excelname)+';打开失败,文件已损坏')
f.write('\n')
f.close()
else:
app.kill()
B、openpyxl库
使用该库的目的,就是扫描文件夹内的所有.xlsx的文件,逐一打开并对当前的工作薄的所有工作表的每一个有效单元格进行日期格式的排查及更改。
示例代码如下:
n=0
xlsx_names_list = os.listdir(UpdateExcelPath)#扫描该路径下的xlsx文件名,得到一个列表
for myxlsx in xlsx_names_list:
n+=1
print(myxlsx,'正在处理第',n,'个,共有',len(xlsx_names_list),'个')
mybook = load_workbook(UpdateExcelPath+myxlsx)
for sheetname in mybook.sheetnames:
mysheet = mybook[sheetname]
#print(sheetname,'最大行',mysheet.max_row,'最大列',mysheet.max_column)
for r in range(1,mysheet.max_row+1):
for c in range(1,mysheet.max_column+1):
if '/' in str(mysheet.cell(r,c).value) or '-' in str(mysheet.cell(r,c).value) or '/' in str(mysheet.cell(r,c).value) or '_' in str(mysheet.cell(r,c).value):
mysheet.cell(r,c).value=mysheet.cell(r,c).value.replace('/','-').replace('-','-').replace('/','-').replace('_','-')
print(myxlsx,sheetname,'日期格式错误,正在修改…')
mybook.save(UpdateExcelPath+myxlsx)