最近用 Python 的 xlwings 库处理了几个 Excel 表格,感觉很不错,以后会优先考虑用它来进行 Excel 自动化处理,现在总结一下这次处理过程中用到的 xlwings 知识,方便以后参考。
基本操作
首先安装 xlwings:
pip install xlwings
引入库:
import xlwings as xw
实例化 Excel,相当于打开 Excel 软件:
app = xw.App(visible=True,add_book=False)
# visible=True 显示 Excel 软件界面
# add_book=False 不新建工作簿(即不新建 Excel 文件)
打开已有工作簿(支持绝对路径和相对路径):
wb = app.books.open('test.xlsx')
# wb = xw.Book('test.xlsx')
# app.books.open 方式只在 app 这一个 Excel 实例中打开工作簿,即只打开一个 Excel 窗口
# xw.Book 方式则会打开多个窗口,即创建多个 Excel 实例,每个实例中打开一个工作簿
保存工作簿:
wb.save() # 保存当前文件
wb.save('test2.xlsx') # 另存为其他文件
退出工作簿:
wb.close()
退出 Excel:
app.quit()
常见写法
下面是一个 xlwings 程序的常见写法:
# 导入xlwings模块
import xlwings as xw
# 导入 traceback 用来打印错误堆栈
import traceback
# 设置为全局变量,方便错误处理
app = None
wb = None
def test(file_path):
global app
global wb
# 打开 Excel 程序(程序不可见,只打开不新建工作薄,屏幕更新关闭)
app=xw.App(visible=False,add_book=False)
app.display_alerts=False
app.screen_updating=False
# 打开 file_path 位置的文档
wb=app.books.open(file_path)
# 在这里写进行数据处理的代码
#保存,关闭,结束程序
wb.save()
wb.close()
app.quit()
if __name__ == '__main__':
file_path = 'test.xlsx'
try:
test(file_path)
except Exception as ex:
# 打印错误堆栈
traceback.print_exc()
# 关闭文件、退出 Excel 程序
wb.close()
app.quit()
注意到 app 和 wb 被设置为全局变量,以方便使用 try-except 捕获 test 函数中可能发生的错误,并在捕获错误时关闭工作簿并退出 Excel 实例。如果程序在处理 Excel 文件的过程中因遇到错误而终止运行且没有进行错误处理,那么 Excel 文件将一直在 Excel 中保持打开状态,此时如果想手动打开文件进行编辑,程序将显示 Excel 被锁定:
同样,如果尝试使用 xlwings 重新处理被锁定的文件,xlwings 也将会报错。
如果你已经遇到了文件被锁定的状态,需要进入到任务管理器,手动结束 Excel 的进程,同时注意是在“后台进程”而不是“应用”里面找:
当然,为了能够在出错时退出程序,也可以在 xlwings 里面设置 visible 为 True,这样你就能在出错时手动关闭 Excel,不过,这样程序运行起来一般会慢一点,而且操作起来也不太方便。
读写数据
获取 sheet
sheet1 = wb.sheets['sheet1']
获取单元格
1、range 获取单个单元格:
sheet1.range('A1')
2、sheet 获取单个单元格:
sheet1[0,1] # 在第1行,第2列的单元格,即 B1 单元格
3、sheet 获取多个单元格
# C2:D4
rng = sheet1[1:4,2:4] # 前一个切片为行范围([1,4)),后一个切片为列范围([2,4))
读取/改变单元格中的值
1、获取/修改单个单元格中的值:
val = sheet1.range('A1').value # 获取
sheet1.range('A1').value = 1 # 修改
# val = sheet1[0,0].value # 获取
# sheet1[0,0].value = 1 # 修改
2、获取/修改一行/一列数据
# 读取/修改行
row_val = sheet1[0,2:4].value # 读取 C1:D1 为一维列表
sheet1[0,2:4].value = [2,3] # 修改
"""
最后 C1:D1 中的数据为:
2 3
"""
# 读取/修改列
col_val = sheet1[1:4,2].value # 读取 C2:C4 为一维列表
sheet1[1:4,2].value = [2,3,4] # 修改
"""
最后 C2:C4 中的数据为:
2
3
4
"""
3、获取/修改多个单元格中的值:
rng_val = rng.value # 读取 C2:D4 为二维列表
rng.value = [[2,3],[4,5],[6,7]] # 修改
"""
最后 rng (C2:D4)中的数据为:
2 3
4 5
6 7
"""
4、快速赋值一行数据
sheet1[0,2] = [1,2,3] # C1:E1 被赋值为 [1,2,3]
5、快速赋值一列数据
sheet1[0,2].options(transpose=True).value = [1,2,3] # C1:C3 被赋值为 [1,2,3]
6、快速赋值一批数据
sheet1[1,2] = [[2,3],[4,5],[6,7]] # C2:D4 被赋值为 [[2,3],[4,5],[6,7]]
# 相当于将数据复制到剪切板,然后在 C2 处粘贴数据,Excel 自动将数据平铺到单元格
6、清除数据和格式
rng.clear()
获取行数列数
info = sheet1.used_range
nrows = info.last_cell.row
ncols = info.last_cell.column
编辑格式
1、获取/修改背景色
color = sheet1[0,2].color # 获取
sheet1[0,2].color = (225,225,225) #修改
sheet1[0,2].color = None # 清空背景色
2、修改格式为文本
可用于解决身份证号码在单元格中以科学计数法显示的问题
rng.api.NumberFormat = '@'
# 或 rng.number_format = '@'
3、表格列宽自适应
whole_range = sheet[0:nrows, 0:ncols]
whole_range.autofit()
其他
尽量通过建立列表将数据一次性写入,一次性写入比将数据分多次分别写入快得多。
参考
xlwings(App.books.open/Book 方式打开文件)-艺赛旗社区
formatting string to number while writing back to Excel · Issue #436 · xlwings/xlwings