最近用 Python 的 xlwings 庫處理了幾個 Excel 表格,感覺很有用,所以做一點總結。
基本操作
安裝:
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