Python操作Excel工作簿的示例代碼(*.xlsx)
前言
Excel 作為流行的個(gè)人計(jì)算機(jī)數(shù)據(jù)處理軟件,混跡于各個(gè)領(lǐng)域,在程序員這里也是常常被處理的對(duì)象,可以處理 Excel 格式文件的 Python 庫還是挺多的,比如 xlrd、xlwt、xlutils、openpyxl、xlwings 等等,但是每個(gè)庫處理 Excel 的方式不同,有些庫在處理時(shí)還會(huì)有一些局限性。
接下來對(duì)比一下幾個(gè)庫的不同,然后主要記錄一下 xlwings 這個(gè)庫的使用,目前這是個(gè)人感覺使用起來比較方便的一個(gè)庫了,其他的幾個(gè)庫在使用過程中總是有這樣或那樣的問題,不過在特定情況下使用也是挺不錯(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 庫也是不斷迭代的,這里盡可能的給出版本號(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è)程序庫使用之前自行安裝就行,安裝方法就不贅述了,不過可以提供一個(gè)可以快速安裝鏡像源,使用 pip install -i https://pypi.doubanio.com/simple 庫名 可以盡可能解決下載安裝緩慢的問題。
Excel具體操作
關(guān)于使用 Python 具體操作 Excel 的方法可以分為三組,配合使用 xlrd、xlwt、xlutils 操作作為第一組,使用庫 openpyxl 作為第二組,而 xlwings 作為第三組,這篇總結(jié)重點(diǎn)總結(jié) xlwings 的使用,其他兩組簡(jiǎn)單了解。
xlrd、xlwt、xlutils
這一組操作 Excel 的庫名字很形象,一個(gè)讀、一個(gè)寫、一個(gè)小工具,湊到一起就可以對(duì) Excel 肆意妄為了,下面做個(gè)小練習(xí),打開一個(gè) Excel 文件然后修改第一個(gè)單元格的值,再另存為一個(gè)新文件,代碼如下:
import xlrdimport xlwtimport xlutils.copydef 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頁簽 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è)庫操作 Excel。
還有一點(diǎn),這幾個(gè)庫操作單元格時(shí),行和列的索引是從0開始的。
openpyxl
首先說這個(gè)庫主要用來操作 .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 Workbookfrom openpyxl import load_workbookfrom openpyxl.styles import Font, Fill, Alignment, PatternFilldef 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è)庫遇到的情況,存儲(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è)庫操作單元格時(shí),行和列的索引是從1開始的。
xlwings
這個(gè)庫在操作的首先要?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è)庫支持情況對(duì)比
雖然前面寫了這么多方法,但是遇到一個(gè)實(shí)際的問題時(shí)還是會(huì)猶豫,到底用哪種方式呢?下面做一個(gè)簡(jiǎn)單的對(duì)比,只是根據(jù)我做的實(shí)驗(yàn)來簡(jiǎn)單對(duì)比,如果有不準(zhǔn)確甚至是錯(cuò)誤的地方,歡迎大家指出來,我會(huì)盡快改正的。
情景/庫 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)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. PHP循環(huán)與分支知識(shí)點(diǎn)梳理2. 讀大數(shù)據(jù)量的XML文件的讀取問題3. 利用CSS3新特性創(chuàng)建透明邊框三角4. 解析原生JS getComputedStyle5. JSP+Servlet實(shí)現(xiàn)文件上傳到服務(wù)器功能6. ASP基礎(chǔ)入門第三篇(ASP腳本基礎(chǔ))7. css代碼優(yōu)化的12個(gè)技巧8. ASP刪除img標(biāo)簽的style屬性只保留src的正則函數(shù)9. ASP實(shí)現(xiàn)加法驗(yàn)證碼10. jsp+servlet實(shí)現(xiàn)猜數(shù)字游戲
