溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Python操作Excel工作簿的示例代碼(\*.xlsx)

發(fā)布時(shí)間:2020-08-27 17:53:12 來(lái)源:腳本之家 閱讀:147 作者:AlbertS 欄目:開(kāi)發(fā)技術(shù)

前言

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)題:

  • 操作系統(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ù)使用之前自行安裝就行,安裝方法就不贅述了,不過(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é)

  1. Excel 表格程序經(jīng)過(guò)版本的更替發(fā)生了很大的變化,出現(xiàn)了相同內(nèi)容時(shí) .xls 比 .xlsx 格式的文件大很多的情況
  2. 基于上一點(diǎn)考慮,如果能使用的新版的表格,那么就放棄舊的格式的吧
  3. 還有一個(gè)神奇的情況,一個(gè)帶有少量數(shù)據(jù)的 .xlsx 格式的表格要比一個(gè)空表格還要小,這是什么情況,暫時(shí)沒(méi)弄明白怎么回事,求知道的大神告知一二

到此這篇關(guān)于Python操作Excel工作簿的示例代碼(\*.xlsx)的文章就介紹到這了,更多相關(guān)Python操作Excel工作簿內(nèi)容請(qǐng)搜索億速云以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持億速云!

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI