Python操作Excel工作簿的示例代碼(\*.xlsx)
前言
Excel 作為流行的個(gè)人計(jì)算機(jī)數(shù)據(jù)處理軟件,混跡于各個(gè)領(lǐng)域,在程序員這里也是常常被處理的對(duì)象,可以處理 Excel 格式文件的 Python 庫(kù)還是挺多的,比如 xlrd、xlwt、xlutils、openpyxl、xlwings 等等,但是每個(gè)庫(kù)處理 Excel 的方式不同,有些庫(kù)在處理時(shí)還會(huì)有一些局限性。
接下來對(duì)比一下幾個(gè)庫(kù)的不同,然后主要記錄一下 xlwings 這個(gè)庫(kù)的使用,目前這是個(gè)人感覺使用起來比較方便的一個(gè)庫(kù)了,其他的幾個(gè)庫(kù)在使用過程中總是有這樣或那樣的問題,不過在特定情況下使用也是挺不錯(cuò)的。
EXCEL文件
Excel 被稱為電子表格,其實(shí)際可以保存的格式分為很多種,但是“Excel 工作簿(*.xlsx)”和“Excel 97-2003 工作簿(*.xls)”是其中比較常用的兩種,可以認(rèn)為 .xls 格式的表格是 03版Excel 之前常用的格式,而 .xlsx 是 03版之后,一般指 07版Excel 之后常用的格式。
一般的 Excel 程序?qū)τ谏鲜龅膬煞N格式都可以打開編輯,也可以相互轉(zhuǎn)化存儲(chǔ),不過還是建議在沒有特殊要求的情況下使用新版本的格式,一方面新的穩(wěn)定版本可能會(huì)修復(fù)之前的一些BUG,同時(shí)也會(huì)帶來進(jìn)行一些優(yōu)化。
我也是在寫這篇總結(jié)之前才發(fā)現(xiàn),一個(gè)空的 .xlsx 格式的文件大小有 7KB,而一個(gè)空的 .xls 格式的文件大小有 24KB,當(dāng)我分別寫入一個(gè)相同的漢字后,兩個(gè)文件大小變成了 10KB 和 30KB,差距還是不小的,還有一個(gè)問題就是在將 .xlsx 格式的文件另存為 .xls 格式時(shí)還會(huì)有兼容性提示,提醒用戶有些設(shè)置可能會(huì)丟失,所以能選新版本還是盡量用新版本吧。
測(cè)試環(huán)境
因?yàn)楹芏鄳?yīng)用程序是不斷迭代的,相對(duì)應(yīng)的 Python 庫(kù)也是不斷迭代的,這里盡可能的給出版本號(hào),不同的版本可能會(huì)有不同的問題:
- 操作系統(tǒng): Windows 10 隨意版
- Python: 3.75
- xlrd: 1.2.0
- xlwt: 1.3.0
- xlutils: 2.0.0
- openpyxl: 3.0.3
- xlwings: 0.18.0
以上各個(gè)程序庫(kù)使用之前自行安裝就行,安裝方法就不贅述了,不過可以提供一個(gè)可以快速安裝鏡像源,使用 pip install -i https://pypi.doubanio.com/simple 庫(kù)名 可以盡可能解決下載安裝緩慢的問題。
Excel具體操作
關(guān)于使用 Python 具體操作 Excel 的方法可以分為三組,配合使用 xlrd、xlwt、xlutils 操作作為第一組,使用庫(kù) openpyxl 作為第二組,而 xlwings 作為第三組,這篇總結(jié)重點(diǎn)總結(jié) xlwings 的使用,其他兩組簡(jiǎn)單了解。
xlrd、xlwt、xlutils
這一組操作 Excel 的庫(kù)名字很形象,一個(gè)讀、一個(gè)寫、一個(gè)小工具,湊到一起就可以對(duì) Excel 肆意妄為了,下面做個(gè)小練習(xí),打開一個(gè) Excel 文件然后修改第一個(gè)單元格的值,再另存為一個(gè)新文件,代碼如下:
import xlrd import xlwt import xlutils.copy def save_as_new_file(file_name, new_file_name): # 打開Excel文件 rb = xlrd.open_workbook(file_name) # 創(chuàng)建一個(gè)可寫入的副本 wb = xlutils.copy.copy(rb) # 獲得第一個(gè)sheet頁(yè)簽 ws = wb.get_sheet(0) # 第一個(gè)單元格寫入測(cè)試值 ws.write(0, 0, 'test value') # 另存為一個(gè)新文件 wb.save(new_file_name)
上述代碼無論是操作 .xlsx 文件還是操作 .xls 文件都不會(huì)報(bào)錯(cuò),但是另存為的 .xlsx 格式的文件會(huì)打不開,同時(shí)你會(huì)發(fā)現(xiàn)正常存儲(chǔ)的 .xls 文件打開后格式全都沒了,怎么辦,改個(gè)參數(shù)試試,將打開文件的代碼修改如下:
rb = xlrd.open_workbook(file_name, formatting_info=True)
其中參數(shù) formatting_info=True 就表示打開Excel時(shí)保留原有的格式,但是這是相對(duì)于 .xls 格式的文件,對(duì)于 .xlsx 格式的文件直接跑出異常 raise NotImplementedError("formatting_info=True not yet implemented"),就因?yàn)樘幚聿涣?.xlsx 格式的文件,我暫時(shí)沒有使用這幾個(gè)庫(kù)操作 Excel。
還有一點(diǎn),這幾個(gè)庫(kù)操作單元格時(shí),行和列的索引是從0開始的。
openpyxl
首先說這個(gè)庫(kù)主要用來操作 .xlsx 格式的文件,對(duì)于 .xls 格式的文件無法打開,會(huì)報(bào) openpyxl does not support the old .xls file format 這樣的錯(cuò)誤,但是可以存儲(chǔ)成這樣的格式,再次打開時(shí)會(huì)有格式不匹配的警告,但是基礎(chǔ)的數(shù)據(jù)還在,所以還是優(yōu)先用來操作 .xls 格式的文件吧。
寫一個(gè)新文件的常見用法:
from openpyxl import Workbook from openpyxl import load_workbook from openpyxl.styles import Font, Fill, Alignment, PatternFill def write_new_excel(file_name): # 創(chuàng)建一個(gè)excel文檔 wb = Workbook() # 獲得當(dāng)前激活的sheet對(duì)象 ws = wb.active # 給A2單元格賦值 ws['A2'] = 'This is A2 cell' # 一行添加多列數(shù)據(jù) ws.append([1, 2, 'hello']) # 添加新的sheet ws = wb.create_sheet(title='NewInfo',index=0) # 設(shè)置單元格的值 ws['A1'] = 'This is new sheet' # 保存excel wb.save(file_name)
讀取和改寫一個(gè)原有文件的常見用法:
def read_update_excel(file_name):
# 加載Excel表
wb = load_workbook(file_name)
# 打印sheet數(shù)量
print('sheet count:', len(wb.sheetnames))
# 打印所有sheet名字
print('sheet name list:', wb.sheetnames)
# 獲取第一個(gè)sheet對(duì)象
ws = wb[wb.sheetnames[0]]
# 打印sheet表行數(shù)和列數(shù)
print('rows count:', ws.max_row, 'cols count:', ws.max_column)
# 更新單元格A1的內(nèi)容
ws['A1'] = 'this is A1'
# 在第二行位置插入一行
ws.insert_rows(2)
# 刪除第五行
ws.delete_rows(5)
# 獲取單元格對(duì)象,對(duì)應(yīng)B2單元格
cell = ws.cell(2,2)
# 設(shè)置單元格內(nèi)容
cell.value = 'this is B2'
# 修改字體格式為粗體
cell.font = Font(bold=True)
# 修改單元格格式
cell.fill = PatternFill("solid", fgColor="F0CDCD")
# 保存原文件或另存一個(gè)文件
wb.save(file_name)
使用這個(gè)庫(kù)遇到的情況,存儲(chǔ)帶有樣式的數(shù)據(jù)沒有發(fā)現(xiàn)問題,但是當(dāng)加入一個(gè)計(jì)算公式后,另存為一個(gè)文件時(shí)明顯文件尺寸變小了,但是數(shù)據(jù)和公式?jīng)]有發(fā)現(xiàn)有問題。
有資料說處理速度真的很慢,因?yàn)槲姨幚淼奈募容^小,但是沒有發(fā)現(xiàn)這方面的問題,還有一個(gè)問題就是說Excel中的宏全部丟失,這個(gè)測(cè)試的時(shí)候確實(shí)是丟了,只不過這個(gè)好像和文件格式有關(guān),要想保存宏需要存儲(chǔ)為 .xlsm 格式,但是 openpyxl 使用來操作 .xlsx 文件的,存儲(chǔ)時(shí)會(huì)導(dǎo)致宏丟失,強(qiáng)行存儲(chǔ)為 .xlsm 格式會(huì)導(dǎo)致最終的文件打不開。
還有一點(diǎn),這個(gè)庫(kù)操作單元格時(shí),行和列的索引是從1開始的。
xlwings
這個(gè)庫(kù)在操作的首先要?jiǎng)?chuàng)建一個(gè) App,通過這個(gè)創(chuàng)建出來的 App 對(duì)象來操作 Excel,非常像把 Excel 的各種操作 api 封裝到一起,然后通過這個(gè) App 對(duì)象來調(diào)用,如果在創(chuàng)建 App 的時(shí)候不設(shè)置隱藏參數(shù),是會(huì)正常打開 Excel 程序的。
使用 xlwings 的基本方式:
import xlwings as xw # 設(shè)置Excel程序不可見 app = xw.App(visible=False, add_book=False) # 通過 app 操作 Excel文件 # app.bala bala bala ..... # app.bala bala bala ..... # 優(yōu)雅的退出 app.quit()
創(chuàng)建一個(gè)新的 Excel 文件并寫入數(shù)據(jù):
def write_new_excel(app, file_name):
# 創(chuàng)建新的 Excel 表
wb = app.books.add()
# 獲取當(dāng)前活動(dòng)的sheet
ws = wb.sheets.active
# 初始化二維區(qū)域的值
arr_data = [[1, 2, 3], [4, 5, 6], [7, 8, 'end']]
# 設(shè)置到新建的Excel中
ws.range('A1:B3').value=arr_data
# 設(shè)置單獨(dú)一個(gè)單元格的值
ws.range('A4').value='this is A4'
# 設(shè)置單獨(dú)一個(gè)單元格的值
ws[3,1].value='this is B4'
# 保存Excel文件
wb.save(file_name)
wb.close()
需要注意的是通過行索引和列索引修改單元格時(shí),起始索引是0。
讀入已有 Excel 表格并修改
def read_update_excel(app, file_name):
# 加載已有的表格
load_wb = app.books.open(file_name)
# 獲取Excel表中第一個(gè)sheet
load_ws = load_wb.sheets[0]
# 打印sheet的名字
print(load_ws.name)
# 根據(jù)sheet名字獲取sheet對(duì)象
load_ws = load_wb.sheets[load_ws.name]
# 獲取當(dāng)前活動(dòng)的sheet
load_ws = load_wb.sheets.active
# 獲取存在數(shù)據(jù)的行數(shù)和列數(shù)
rows = load_ws.api.UsedRange.Rows.count
cols = load_ws.api.UsedRange.Columns.count
print('rows count:', rows, 'cols count:', cols)
# 修改指定單元格數(shù)據(jù)(A1單元格)
load_ws[0,0].value='this is A1'
# 有空行或空列時(shí)獲取準(zhǔn)確的行列數(shù)量
print(load_ws.used_range.shape)
# 從A1單元格開始擴(kuò)展到非空行空列,最后的行數(shù)和列數(shù)
print((load_ws.range('A1').expand().last_cell.row,
load_ws.range('A1').expand().last_cell.column))
# 從A1單元格開始擴(kuò)展到非空行空列,最后的行數(shù)和列數(shù)
print((load_ws.range('A1').expand().last_cell.row,
load_ws.range('A1').expand().last_cell.column))
# 從A1單元格開始擴(kuò)展到非空行空列,最后形狀
print(load_ws.range(1,1).expand().shape)
# 從A1單元格開始擴(kuò)展到非空行空列,最后的行數(shù)和列數(shù)
print((load_ws.range('A1').expand('table').rows.count,
load_ws.range('A1').expand('table').columns.count))
# 保存修改后的Excel
load_wb.save(file_name)
load_wb.close()
Excel 增加刪除行和列
def insert_delete_rowscols(app, file_name):
# 加載已有的表格
load_wb = app.books.open(file_name)
# 獲取當(dāng)前活動(dòng)的sheet
load_ws = load_wb.sheets.active
# 從第2行開始插入4行,也就是說2-5行變成新插入的空行
load_ws.api.rows('2:5').insert
# 刪除第6行和第7行
load_ws.api.rows('6:7').delete
# 插入一個(gè)單元格,實(shí)際測(cè)試效果是B列從B2開始向下移動(dòng),B2為新添加的單元格
load_ws.range('B2').api.insert
# 插入新的一列
load_ws.api.columns('B').insert
# 刪除一列
load_ws.api.columns('C').delete
# 保存修改后的Excel
load_wb.save(file_name)
load_wb.close()
單元格寬高查詢?cè)O(shè)置與合并
def cell_operation(app, file_name):
# 加載已有的表格
load_wb = app.books.open(FILE_PATH_ROOT + file_name)
# 獲取當(dāng)前活動(dòng)的sheet
load_ws = load_wb.sheets.active
# 合并單元格
load_ws.range('A2:A3').api.merge
#獲取單元格
cell = xw.Range('B2')
# 打印單元格所在的行和列
print("row is:", cell.row, "col is:", cell.column)
# 打印當(dāng)前格子的高度和寬度
print("cell.width:", cell.width, "cell.height:", cell.height)
# 設(shè)置當(dāng)前格子的高度和寬度
cell.row_height = 32
cell.column_width = 64
# 指定單元格的高度和寬度自適應(yīng)
cell.columns.autofit()
cell.rows.autofit()
# 再次打印當(dāng)前格子的高度和寬度
print("cell.width:", cell.width, "cell.height:", cell.height)
# 保存修改后的Excel
load_wb.save(file_name)
load_wb.close()
幾個(gè)庫(kù)支持情況對(duì)比
雖然前面寫了這么多方法,但是遇到一個(gè)實(shí)際的問題時(shí)還是會(huì)猶豫,到底用哪種方式呢?下面做一個(gè)簡(jiǎn)單的對(duì)比,只是根據(jù)我做的實(shí)驗(yàn)來簡(jiǎn)單對(duì)比,如果有不準(zhǔn)確甚至是錯(cuò)誤的地方,歡迎大家指出來,我會(huì)盡快改正的。
| 情景/庫(kù) | xlrd、xlwt、xlutils | openpyxl | xlwings |
|---|---|---|---|
| 讀取.xls | 可以帶有樣式讀取 | 不支持 | 可以讀取 |
| 保存.xls | 可以帶有樣式保存 | 可以保存,但是提示文件擴(kuò)展名不匹配,可以看到原始數(shù)據(jù) | 可以保存,但是提示文件擴(kuò)展名不匹配,可以看到原始數(shù)據(jù) |
| 讀取.xlsx | 可以讀取,但沒有樣式 | 可以帶有樣式讀取 | 可以帶有樣式讀取 |
| 保存.xlsx | 保存后打不開 | 可以帶有樣式保存 | 可以帶有樣式保存 |
| 讀取.xlsm | 可以讀取,但沒有樣式和宏 | 可以讀取,但沒有宏 | 可以讀取包含宏的表格 |
| 保存.xlsm | 保存后打不開,存成 .xls 格式宏丟失 | 保存后打不開,存成 .xls想 格式宏丟失 | 存儲(chǔ)后宏還在 |
| 增刪行和列 | 沒有直接方法 | 支持 | 支持 |
| 另存后大小 | .xls 文件沒有變化 | .xlsx 文件會(huì)變小 | .xls、.xlsx 文件沒有變化 |
| 使用建議 | 只操作.xls文件可以考慮 | 只操作.xlsx文件可以考慮,不能帶有宏 | 一個(gè)比較好的選擇,使用時(shí)感覺速度稍微有點(diǎn)慢 |
總結(jié)
- Excel 表格程序經(jīng)過版本的更替發(fā)生了很大的變化,出現(xiàn)了相同內(nèi)容時(shí) .xls 比 .xlsx 格式的文件大很多的情況
- 基于上一點(diǎn)考慮,如果能使用的新版的表格,那么就放棄舊的格式的吧
- 還有一個(gè)神奇的情況,一個(gè)帶有少量數(shù)據(jù)的 .xlsx 格式的表格要比一個(gè)空表格還要小,這是什么情況,暫時(shí)沒弄明白怎么回事,求知道的大神告知一二
到此這篇關(guān)于Python操作Excel工作簿的示例代碼(\*.xlsx)的文章就介紹到這了,更多相關(guān)Python操作Excel工作簿內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 利用python在excel中畫圖的實(shí)現(xiàn)方法
- Python xlrd excel文件操作代碼實(shí)例
- python實(shí)現(xiàn)跨excel sheet復(fù)制代碼實(shí)例
- Python3使用xlrd、xlwt處理Excel方法數(shù)據(jù)
- python實(shí)現(xiàn)word文檔批量轉(zhuǎn)成自定義格式的excel文檔的思路及實(shí)例代碼
- python實(shí)現(xiàn)自動(dòng)化報(bào)表功能(Oracle/plsql/Excel/多線程)
- Python調(diào)用接口合并Excel表代碼實(shí)例
相關(guān)文章
Python利用re模塊實(shí)現(xiàn)簡(jiǎn)易分詞(tokenization)
分詞(tokenization)任務(wù)是Python字符串處理中最為常見任務(wù)了。本文將利用re模塊實(shí)現(xiàn)簡(jiǎn)易tokenizer,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-04-04
Python 3.x基于Xml數(shù)據(jù)的Http請(qǐng)求方法
今天小編就為大家分享一篇Python 3.x基于Xml數(shù)據(jù)的Http請(qǐng)求方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-12-12
Python網(wǎng)絡(luò)請(qǐng)求模塊urllib與requests使用介紹
網(wǎng)絡(luò)爬蟲的第一步就是根據(jù)URL,獲取網(wǎng)頁(yè)的HTML信息。在Python3中,可以使用urllib和requests進(jìn)行網(wǎng)頁(yè)數(shù)據(jù)獲取,這篇文章主要介紹了Python網(wǎng)絡(luò)請(qǐng)求模塊urllib與requests使用2022-10-10
python實(shí)現(xiàn)網(wǎng)頁(yè)自動(dòng)簽到功能
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)網(wǎng)頁(yè)自動(dòng)簽到功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
Python中實(shí)現(xiàn)定時(shí)任務(wù)常見的幾種方式
在Python中,實(shí)現(xiàn)定時(shí)任務(wù)是一個(gè)常見的需求,無論是在自動(dòng)化腳本、數(shù)據(jù)處理、系統(tǒng)監(jiān)控還是其他許多應(yīng)用場(chǎng)景中,Python提供了多種方法來實(shí)現(xiàn)定時(shí)任務(wù),包括使用標(biāo)準(zhǔn)庫(kù)、第三方庫(kù)以及系統(tǒng)級(jí)別的工具,本文將詳細(xì)介紹幾種常見的Python定時(shí)任務(wù)實(shí)現(xiàn)方式2024-08-08
pandas.dataframe按行索引表達(dá)式選取方法
今天小編就為大家分享一篇pandas.dataframe按行索引表達(dá)式選取方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-10-10
Python畫柱狀統(tǒng)計(jì)圖操作示例【基于matplotlib庫(kù)】
這篇文章主要介紹了Python畫柱狀統(tǒng)計(jì)圖操作,結(jié)合實(shí)例形式分析了Python基于matplotlib庫(kù)實(shí)現(xiàn)圖形繪制的相關(guān)操作技巧,需要的朋友可以參考下2018-07-07

