python處理excel總結


工作中,大家經常會使用excel去處理數據以及展示,但是對於部分工作我們可以借助程序幫忙實現,達到高效解決問題的效果,比如將接口返回的json解析並保存結果到excel中,按一定規律處理excel中的數據然后寫入到新的excel文件中,匯總來自多個文件的內容到一個excel中,等等。
平時在工作中遇到比較繁瑣的數據需要寫入到excel中,除非excel的內置公式可以處理,我會第一時間想到使用python處理。在這個過程中,研究並嘗試了一些工具,閑着沒事,我整理並記錄下來。

 




各個工具對比

  XlsxWriter xlrd&xlwt&xlutils OpenPyXL Microsoft Excel API
介紹 可以創建和寫Excel 2007+ XLSX文件 xlrd、xlwt、xlutils三大模塊分別提供讀、寫和其他功能 可以讀、寫Excel 2007+ /xlsm/xltx/xltm文件 直接通過COM組件與Microsoft Excel進程通信調用各種功能實現對excel文件操作
修改 ⚠️
.xls
.xlsx
      xlrd: 0.8.0+ √

    * xlwt:✘
大文件
功能 一般 超強
速度 超慢

|系統|無限制|無限制|無限制|Windows + excel|

|使用場景|* 需要創建xlsx文件
* 不需要讀取已有文件
* 需要實現比較復雜的功能
* 數據量可能會比較大
* 需要跨平台|* 需要讀取xls或者xlsx文件
* 要生成xls文件
* 需要對文件處理的功能不太復雜
* 需要跨平台|* 需要處理xlsx文件
* 需要修改已有文件或者在寫入過程中不斷修改
* 需要對文件處理的功能比較復雜
* 數據量可能會很大
* 需要跨平台|* 需要處理各種文件格式
* 需要用到特別復雜功能
* 在修改文件時不希望對原有信息造成任何意外破壞
* 數據量很小,或者願意等待
* 僅在Windows中使用|

一、XlsxWriter

XlsxWriter是我最終選擇的用於寫操作的工具。顧名思義,它只能用來寫文件。
這應該是個比較新的項目,在GitHub上看它最早的提交是在2013年1月份。

 

其官方文檔中宣稱它支持(See the full documentation at: https://xlsxwriter.readthedocs.io):

  • 100% compatible Excel XLSX files.
  • Full formatting.
  • Merged cells.
  • Defined names.
  • Charts.
  • Autofilters.
  • Data validation and drop down lists.
  • Conditional formatting.
  • Worksheet PNG/JPEG images.
  • Rich multi-format strings.
  • Cell comments.
  • Memory optimisation mode for writing large files.

優點

  • 功能比較強
    相對而言,這是除Excel自身之外功能最強的工具了。比如我就用到了它提供的:字體設置、前景色背景色、border設置、視圖縮放(zoom)、單元格合並、autofilter、freeze panes、公式、data validation、單元格注釋、行高和列寬設置等等。
    最讓我驚奇的是,用它生成的帶有單元格注釋的Excel文件,不論是Excel 2007還是Excel 2013都可正常打開。
  • 支持大文件寫入
    如果數據量非常大,可以啟用constant_memory,這是一種順序寫入模式,得到一行數據就立刻寫入一行,而不會把所有的數據都保持在內存中。

缺點

  • 不支持讀取和修改
    作者並沒有打算做一個XlsxReader來提供讀取操作。不能讀取,也就無從修改了。它只能用來創建新的文件。我是利用xlrd把需要的信息讀入后,用XlsxWriter創建全新的文件。
    另外,即使是創建到一半Excel文件,也是無法讀取已經創建出來的內容的(信息應該在,但是並沒有相應的接口)。因為它的主要方法是write而不是set。當你在某個單元格寫入數據后,除非你自己保存了相關的內容,否則還是沒有辦法讀出已經寫入的信息。從這個角度看,你無法做到讀出->修改->寫回,只能是寫入->寫入->寫入。
  • 不支持XLS文件
    XLS是Office 2013或更早版本所使用的格式,是一種二進制格式的文件。XLSX則是用一系列XML文件組成的(最后的X代表了XML)一個壓縮包。如果非要創建低版本的XLS文件,就請移步xlwt吧。
  • 暫時不支持透視表(Pivot Table)
    透視表是非常麻煩的東西,除了自身復雜的結構外,還需要一套數據緩存。

舉例

 1     import xlsxwriter
 2     # Create an new Excel file and add a worksheet.
 3     workbook = xlsxwriter.Workbook('demo.xlsx')
 4     worksheet = workbook.add_worksheet()
 5     # Widen the first column to make the text clearer.
 6     worksheet.set_column('A:A', 20)
 7     # Add a bold format to use to highlight cells.
 8     bold = workbook.add_format({'bold': True})
 9     # Write some simple text.
10     worksheet.write('A1', 'Hello')
11     # Text with formatting.
12     worksheet.write('A2', 'World', bold)
13     # Write some numbers, with row/column notation.
14     worksheet.write(2, 0, 123) # 第二3行第1列
15     worksheet.write(3, 0, 123.456) # 第四行第1列
16     # Insert an image.
17     worksheet.insert_image('B5', 'logo.png')
18     workbook.close()

二、xlrd&xlwt&xlutils

xlrd&xlwt主要是針對Office 2013或更早版本的XLS文件格式。xlutils使用需要依賴xlrd和xlwt,擴充這兩個庫的功能。(更多信息請見:http://www.python-excel.org/)

優點

支持XLS格式
XlsxWriter和OpenPyXL都不支持XLS格式,從這個角度看,xlrd&xlwt仍然有一定的不可替代性。

缺點

  • 對XLSX支持比較差
    目前xlrd0.8.0+版本已經可以讀取XLSX文件了,有限地支持。至於xlwt還僅僅只支持xls文件。
  • 對修改的支持比較差
    xlrd和xlwt是兩個相對獨立的模塊,雖然xlutils提供方法幫助你把xlrd.Book對象復制到xlwt.Workbook對象,但跟XlsxWriter類似,只是提供write方法,使得你無法很容易地獲取當前已經寫入的數據並進行有針對性的修改。如果非要這樣做,你要不斷地保存,然后再用新的xlrd.Book對象讀取你要的信息,還是比較麻煩的。
  • 功能很弱
    除了最基本的寫入數據和公式,xlwt所提供的功能非常少(Excel 2013本身支持的功能也就很少)。對於讀取也是一樣的,很多信息在讀入時就丟失掉了。

舉例

寫數據到xls文件

 1     import xlwt
 2     from datetime import datetime
 3     style0 = xlwt.easyxf('font: name Times New Roman, color-index red, bold on',
 4       num_format_str='#,##0.00')
 5     style1 = xlwt.easyxf(num_format_str='D-MMM-YY')
 6     wb = xlwt.Workbook()
 7     ws = wb.add_sheet('A Test Sheet')
 8     ws.write(0, 0, 1234.56, style0)
 9     ws.write(1, 0, datetime.now(), style1)
10     ws.write(2, 0, "hello world")
11     ws.write(3, 0, 1)
12     ws.write(3, 1, 3)
13     ws.write(3, 2, xlwt.Formula("A4+B4"))
14     wb.save('example.xls')

 

讀取文件內容

 1     import xlrd
 2     # 打開文件
 3     workbook = xlrd.open_workbook('example.xls')
 4     sheet2_name = workbook.sheet_names() # 獲取所有sheet名稱
 5     print(sheet2_name)
 6     # 根據sheet索引或者名稱獲取sheet內容
 7     sheet1 = workbook.sheet_by_index(0) # sheet索引從0開始
 8     # sheet1 = workbook.sheet_by_name('sheet2')
 9     # sheet1的名稱,行數,列數
10     print(sheet1.name, sheet1.nrows, sheet1.ncols)
11     # 獲取整行和整列的值(數組)
12     rows = sheet1.row_values(2) # 獲取第三行內容
13     cols = sheet1.col_values(0) # 獲取第1列內容
14     print(rows)
15     print(cols)
16     # 獲取單元格內容
17     print(sheet1.cell(2, 0).value.encode('utf-8'))
18     print(sheet1.cell_value(2, 0).encode('utf-8'))
19     print(sheet1.row(2)[0].value.encode('utf-8'))
20     # 獲取單元格內容的數據類型
21     print(sheet1.cell(2, 0).ctype)
輸出:
['A Test Sheet']
A Test Sheet 4 3
['hello world', '', '']
[1234.56, 43262.66097222222, 'hello world', 1.0]
b'hello world'
b'hello world'
b'hello world'
1

 

三、OpenPyXL

OpenPyXL是比較綜合的一個工具,能讀能寫能修改,功能還算可以但網上有人說有很大的缺陷。(更多信息請見:http://www.python-excel.org/, https://openpyxl.readthedocs.io/en/stable/index.html)

 

優點

  • 能讀能寫能修改
    OpenPyXL的工作模式跟XlsxWriter和xlwt有很大的區別,它用的是getter/setter模式。你可以隨時讀取某個單元格的內容,並根據其內容進行相應的修改,OpenPyXL會幫你記住每個單元格的狀態。
    特別需要注意的一點:雖然它支持修改已有文件,但由於其所支持的功能有限,讀入文件時會忽略掉它所不支持的內容,再寫入時,這些內容就丟失了。因此使用時一定要慎重。比如下面的缺點中提到它無法讀入公式,那如果你修改一個帶有公式的文件,保存之后,所有的公式就都沒有了。
  • 功能還算可以
    整體來講,它所支持的功能介於XlsxWriter和xlwt之間。

缺點

  • 不支持XLS
    這件事情只能讓xlrd和xlwt去做。
  • 不支持讀取公式
    這其實是個不太簡單的事情,雖然我沒嘗試過,但相信xlrd也做不好這件事。
    Excel的單元格如果是一個公式,它內部會同時保存公式本身和運算結果的緩存。用OpenPyXL讀取單元格內容,它不會告訴你這個單元格的公式是什么,甚至不會告訴你這個單元格存的是公式,它只會拿到這個緩存的運算結果。我本來想利用它判別單元格是不是用了公式,然后做出不同的處理。結果遇到了這個問題,最后只好采取了其他變通的方式去做。

舉例

簡單例子

    from openpyxl import Workbook
    wb = Workbook()
    # grab the active worksheet
    ws = wb.active
    # Data can be assigned directly to cells
    ws['A1'] = 42
    # Rows can also be appended
    ws.append([1, 2, 3])
    # Python types will automatically be converted
    import datetime
    ws['A2'] = datetime.datetime.now()
    # Save the file
    wb.save("sample.xlsx")

 

寫入數據到文件

  1. from openpyxl import Workbook
  2. from openpyxl.compat import range
  3. from openpyxl.utils import get_column_letter
  4. wb = Workbook()
  5. dest_filename = 'book.xlsx'
  6. ws1 = wb.active
  7. ws1.title = "range names"
  8. for row in range(1, 5):
  9. ws1.append(range(0, 10))
  10. ws2 = wb.create_sheet(title="Pi")
  11. ws2['F5'] = 3.14
  12. ws3 = wb.create_sheet(title="Data")
  13. for row in range(2, 10):
  14. for col in range(27, 40):
  15. _ = ws3.cell(column=col, row=row, value="{0}".format(get_column_letter(col)))
  16. wb.save(filename=dest_filename)

讀取數據

1     from openpyxl import load_workbook
2     wb = load_workbook(filename='book.xlsx')
3     sheet_ranges = wb['range names']
4     print(sheet_ranges['D2'].value)

 

輸出:
3

四、Microsoft Excel API

大部分Windows環境的開發人員都會選擇Microsoft Excel API。實際上不僅僅是Python,幾乎各種語言都有相應的方法使用它,因為核心的邏輯完全是由Microsft Excel自身提供的。語言相關的部分只是負責跟Windows的COM組件進行通信。
在Python中首先需要安裝Python for Windows extensions(pywin32),具體的文檔可以查閱Win32 ModulesPython COM
當然你還必須要安裝某一個版本的Microsoft Office Excel,它內部的DLL負責實際的操作。

優點

  • 最大的優點:強大無極限
    因為直接與Excel進程通信,你可以做任何在Excel里可以做的事情。
  • 文檔豐富
    MSDN上的文檔絕對是世界上最優秀的文檔。沒有之一。
  • 調試方便
    你完全可以直接在Excel里面用宏先調試你想要的效果。甚至如果你不清楚怎么用程序實現某個操作,你可以通過宏錄制的方法得到該操作的處理代碼。

缺點

  • 致命的缺點:慢到死
    因為需要與Excel進程通信,其效率是非常低的。
    如果讓Excel窗口可見,隨着程序的運行,你可以看到每一句程序所帶來的變化,單元格的內容一個一個地改變。如果要寫入的數據很多,那速度是無法忍受的。
  • 平台限制
    目前還沒有發現可以在非Windows系統使用它的方法。
    另外,基於它的程序能做什么事情,很大程度上依賴於當前系統所安裝的Excel版本。不同的版本在功能上有很大的差異,API也會有差異。用起來會比較麻煩。
  • Excel自身bug導致的問題
    和Python沒有任何關系,可以完全在Excel中手動復現。在Excel 2007中隨便創建一個文件,給某個單元格添加注釋,保存。換台電腦,用Excel 2013打開,就會報錯,然后注釋就消失了。同樣如果你的程序在一台裝有Excel 2007的機器上創建一個帶有注釋的Excel文件,把這個文件拿到Excel 2013中打開也會報錯,也看不到注釋。反過來也一樣。

五、pyexcel工具

一個包裝器,他提供了一個接口去讀、寫、操作數據。通過該包裝器可以根據場景下載安裝不同的插件(比如前面提到的:xlrd、xlwt、OpenPyXL、XlsxWriter),然后使用該包裝器可以使用相同的一套api去操作excel。

不過該工具如果是公司使用需要支付一定費用,大概$10,個人使用的話是免費的。(詳情可參見:https://pypi.org/project/pyexcel/)。

可用插件如下:

舉例(以xls文件為例,xlsx文件下載相應插件即可,api一致)

保存數據

 1     import pyexcel as p # make sure you had pyexcel-xls installed
 2     a_list_of_dictionaries = [
 3     {
 4     "Name": 'Adam',
 5     "Age": 28
 6     },
 7     {
 8     "Name": 'Beatrice',
 9     "Age": 29
10     },
11     {
12     "Name": 'Ceri',
13     "Age": 30
14     },
15     {
16     "Name": 'Dean',
17     "Age": 26
18     }
19     ]
20     pyexcel.save_as(records=a_list_of_dictionaries, dest_file_name="your_file.xls")

 

讀取數據

1     import pyexcel as p # make sure you had pyexcel-xls installed
2     records = p.iget_records(file_name="your_file.xls")
3     for record in records:
4     print("%s is aged at %d" % (record['Name'], record['Age']))
5     p.free_resources()

 

輸出:
Adam is aged at 28
Beatrice is aged at 29
Ceri is aged at 30
Dean is aged at 26


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM