您好,登錄后才能下訂單哦!
前言
Excel 作為流行的個(gè)人計(jì)算機(jī)數(shù)據(jù)處理軟件,混跡于各個(gè)領(lǐng)域,在程序員這里也是常常被處理的對(duì)象,可以處理 Excel 格式文件的 Python 庫(kù)還是挺多的,比如 xlrd、xlwt、xlutils、openpyxl、xlwings 等等,但是每個(gè)庫(kù)處理 Excel 的方式不同,有些庫(kù)在處理時(shí)還會(huì)有一些局限性。
接下來(lái)對(duì)比一下幾個(gè)庫(kù)的不同,然后主要記錄一下 xlwings 這個(gè)庫(kù)的使用,目前這是個(gè)人感覺(jué)使用起來(lái)比較方便的一個(gè)庫(kù)了,其他的幾個(gè)庫(kù)在使用過(guò)程中總是有這樣或那樣的問(wèn)題,不過(guò)在特定情況下使用也是挺不錯(cuò)的。
EXCEL文件
Excel 被稱(chēng)為電子表格,其實(shí)際可以保存的格式分為很多種,但是“Excel 工作簿(*.xlsx)”和“Excel 97-2003 工作簿(*.xls)”是其中比較常用的兩種,可以認(rèn)為 .xls 格式的表格是 03版Excel 之前常用的格式,而 .xlsx 是 03版之后,一般指 07版Excel 之后常用的格式。
一般的 Excel 程序?qū)τ谏鲜龅膬煞N格式都可以打開(kāi)編輯,也可以相互轉(zhuǎn)化存儲(chǔ),不過(guò)還是建議在沒(méi)有特殊要求的情況下使用新版本的格式,一方面新的穩(wěn)定版本可能會(huì)修復(fù)之前的一些BUG,同時(shí)也會(huì)帶來(lái)進(jìn)行一些優(yōu)化。
我也是在寫(xiě)這篇總結(jié)之前才發(fā)現(xiàn),一個(gè)空的 .xlsx 格式的文件大小有 7KB,而一個(gè)空的 .xls 格式的文件大小有 24KB,當(dāng)我分別寫(xiě)入一個(gè)相同的漢字后,兩個(gè)文件大小變成了 10KB 和 30KB,差距還是不小的,還有一個(gè)問(wèn)題就是在將 .xlsx 格式的文件另存為 .xls 格式時(shí)還會(huì)有兼容性提示,提醒用戶(hù)有些設(shè)置可能會(huì)丟失,所以能選新版本還是盡量用新版本吧。
測(cè)試環(huán)境
因?yàn)楹芏鄳?yīng)用程序是不斷迭代的,相對(duì)應(yīng)的 Python 庫(kù)也是不斷迭代的,這里盡可能的給出版本號(hào),不同的版本可能會(huì)有不同的問(wèn)題:
以上各個(gè)程序庫(kù)使用之前自行安裝就行,安裝方法就不贅述了,不過(guò)可以提供一個(gè)可以快速安裝鏡像源,使用 pip install -i https://pypi.doubanio.com/simple 庫(kù)名
可以盡可能解決下載安裝緩慢的問(wèn)題。
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è)寫(xiě)、一個(gè)小工具,湊到一起就可以對(duì) Excel 肆意妄為了,下面做個(gè)小練習(xí),打開(kāi)一個(gè) Excel 文件然后修改第一個(gè)單元格的值,再另存為一個(gè)新文件,代碼如下:
import xlrd import xlwt import xlutils.copy def save_as_new_file(file_name, new_file_name): # 打開(kāi)Excel文件 rb = xlrd.open_workbook(file_name) # 創(chuàng)建一個(gè)可寫(xiě)入的副本 wb = xlutils.copy.copy(rb) # 獲得第一個(gè)sheet頁(yè)簽 ws = wb.get_sheet(0) # 第一個(gè)單元格寫(xiě)入測(cè)試值 ws.write(0, 0, 'test value') # 另存為一個(gè)新文件 wb.save(new_file_name)
上述代碼無(wú)論是操作 .xlsx 文件還是操作 .xls 文件都不會(huì)報(bào)錯(cuò),但是另存為的 .xlsx 格式的文件會(huì)打不開(kāi),同時(shí)你會(huì)發(fā)現(xiàn)正常存儲(chǔ)的 .xls 文件打開(kāi)后格式全都沒(méi)了,怎么辦,改個(gè)參數(shù)試試,將打開(kāi)文件的代碼修改如下:
rb = xlrd.open_workbook(file_name, formatting_info=True)
其中參數(shù) formatting_info=True 就表示打開(kāi)Excel時(shí)保留原有的格式,但是這是相對(duì)于 .xls 格式的文件,對(duì)于 .xlsx 格式的文件直接跑出異常 raise NotImplementedError("formatting_info=True not yet implemented"),就因?yàn)樘幚聿涣?.xlsx 格式的文件,我暫時(shí)沒(méi)有使用這幾個(gè)庫(kù)操作 Excel。
還有一點(diǎn),這幾個(gè)庫(kù)操作單元格時(shí),行和列的索引是從0開(kāi)始的。
openpyxl
首先說(shuō)這個(gè)庫(kù)主要用來(lái)操作 .xlsx 格式的文件,對(duì)于 .xls 格式的文件無(wú)法打開(kāi),會(huì)報(bào) openpyxl does not support the old .xls file format 這樣的錯(cuò)誤,但是可以存儲(chǔ)成這樣的格式,再次打開(kāi)時(shí)會(huì)有格式不匹配的警告,但是基礎(chǔ)的數(shù)據(jù)還在,所以還是優(yōu)先用來(lái)操作 .xls 格式的文件吧。
寫(xiě)一個(gè)新文件的常見(jiàn)用法:
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)
讀取和改寫(xiě)一個(gè)原有文件的常見(jiàn)用法:
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ù)沒(méi)有發(fā)現(xiàn)問(wèn)題,但是當(dāng)加入一個(gè)計(jì)算公式后,另存為一個(gè)文件時(shí)明顯文件尺寸變小了,但是數(shù)據(jù)和公式?jīng)]有發(fā)現(xiàn)有問(wèn)題。
有資料說(shuō)處理速度真的很慢,因?yàn)槲姨幚淼奈募容^小,但是沒(méi)有發(fā)現(xiàn)這方面的問(wèn)題,還有一個(gè)問(wèn)題就是說(shuō)Excel中的宏全部丟失,這個(gè)測(cè)試的時(shí)候確實(shí)是丟了,只不過(guò)這個(gè)好像和文件格式有關(guān),要想保存宏需要存儲(chǔ)為 .xlsm 格式,但是 openpyxl 使用來(lái)操作 .xlsx 文件的,存儲(chǔ)時(shí)會(huì)導(dǎo)致宏丟失,強(qiáng)行存儲(chǔ)為 .xlsm 格式會(huì)導(dǎo)致最終的文件打不開(kāi)。
還有一點(diǎn),這個(gè)庫(kù)操作單元格時(shí),行和列的索引是從1開(kāi)始的。
xlwings
這個(gè)庫(kù)在操作的首先要?jiǎng)?chuàng)建一個(gè) App,通過(guò)這個(gè)創(chuàng)建出來(lái)的 App 對(duì)象來(lái)操作 Excel,非常像把 Excel 的各種操作 api 封裝到一起,然后通過(guò)這個(gè) App 對(duì)象來(lái)調(diào)用,如果在創(chuàng)建 App 的時(shí)候不設(shè)置隱藏參數(shù),是會(huì)正常打開(kāi) Excel 程序的。
使用 xlwings 的基本方式:
import xlwings as xw # 設(shè)置Excel程序不可見(jiàn) app = xw.App(visible=False, add_book=False) # 通過(guò) app 操作 Excel文件 # app.bala bala bala ..... # app.bala bala bala ..... # 優(yōu)雅的退出 app.quit()
創(chuàng)建一個(gè)新的 Excel 文件并寫(xiě)入數(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()
需要注意的是通過(guò)行索引和列索引修改單元格時(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單元格開(kāi)始擴(kuò)展到非空行空列,最后的行數(shù)和列數(shù) print((load_ws.range('A1').expand().last_cell.row, load_ws.range('A1').expand().last_cell.column)) # 從A1單元格開(kāi)始擴(kuò)展到非空行空列,最后的行數(shù)和列數(shù) print((load_ws.range('A1').expand().last_cell.row, load_ws.range('A1').expand().last_cell.column)) # 從A1單元格開(kāi)始擴(kuò)展到非空行空列,最后形狀 print(load_ws.range(1,1).expand().shape) # 從A1單元格開(kāi)始擴(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行開(kāi)始插入4行,也就是說(shuō)2-5行變成新插入的空行 load_ws.api.rows('2:5').insert # 刪除第6行和第7行 load_ws.api.rows('6:7').delete # 插入一個(gè)單元格,實(shí)際測(cè)試效果是B列從B2開(kāi)始向下移動(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()
單元格寬高查詢(xún)?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ì)比
雖然前面寫(xiě)了這么多方法,但是遇到一個(gè)實(shí)際的問(wèn)題時(shí)還是會(huì)猶豫,到底用哪種方式呢?下面做一個(gè)簡(jiǎn)單的對(duì)比,只是根據(jù)我做的實(shí)驗(yàn)來(lái)簡(jiǎn)單對(duì)比,如果有不準(zhǔn)確甚至是錯(cuò)誤的地方,歡迎大家指出來(lái),我會(huì)盡快改正的。
情景/庫(kù) | xlrd、xlwt、xlutils | openpyxl | xlwings |
---|---|---|---|
讀取.xls | 可以帶有樣式讀取 | 不支持 | 可以讀取 |
保存.xls | 可以帶有樣式保存 | 可以保存,但是提示文件擴(kuò)展名不匹配,可以看到原始數(shù)據(jù) | 可以保存,但是提示文件擴(kuò)展名不匹配,可以看到原始數(shù)據(jù) |
讀取.xlsx | 可以讀取,但沒(méi)有樣式 | 可以帶有樣式讀取 | 可以帶有樣式讀取 |
保存.xlsx | 保存后打不開(kāi) | 可以帶有樣式保存 | 可以帶有樣式保存 |
讀取.xlsm | 可以讀取,但沒(méi)有樣式和宏 | 可以讀取,但沒(méi)有宏 | 可以讀取包含宏的表格 |
保存.xlsm | 保存后打不開(kāi),存成 .xls 格式宏丟失 | 保存后打不開(kāi),存成 .xls想 格式宏丟失 | 存儲(chǔ)后宏還在 |
增刪行和列 | 沒(méi)有直接方法 | 支持 | 支持 |
另存后大小 | .xls 文件沒(méi)有變化 | .xlsx 文件會(huì)變小 | .xls、.xlsx 文件沒(méi)有變化 |
使用建議 | 只操作.xls文件可以考慮 | 只操作.xlsx文件可以考慮,不能帶有宏 | 一個(gè)比較好的選擇,使用時(shí)感覺(jué)速度稍微有點(diǎn)慢 |
總結(jié)
到此這篇關(guān)于Python操作Excel工作簿的示例代碼(\*.xlsx)的文章就介紹到這了,更多相關(guān)Python操作Excel工作簿內(nèi)容請(qǐng)搜索億速云以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持億速云!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。