Windows系統 使用Python處理Excel文件

引子

最近在做一些數據處理和計算的工作,因爲數據是以.csv格式保存的,因此剛開始直接用Excel來處理。但是做着做着發現重複的勞動其實並沒有多大的意義,於是就想着寫個小工具幫着處理。以前正好在一本書上看到過使用Python來處理Excel表格,可惜沒有仔細看。於是我到處查找資料,終於算是完成了任務,因此撰寫此文就算是總結吧。

在這裏我還會順帶介紹一下如何處理.csv文件,因爲某些情況下這是必須的(後面會提到)。

環境配置

下面的環境配置是針對Windows操作系統的,其他操作系統差別不是很大,可以參考一下。

我使用的Python版本號是2.7.12,如果你的Python是2.x,請確保在2.6以上。在Python 3.x上可能會有些不太一樣,所以要注意,可以參考其他的文檔和博客。

Python自帶的csv模塊可以處理.csv文件。

xlrdxlwt兩個模塊分別用來讀Excel和寫Excel,只支持.xls和.xlsx格式,Python不默認包含。這兩個模塊之間相互獨立,沒有依賴關係,也就是說可以根據需要只安裝其中一個。

xlutils模塊可以同時讀寫一個已存在的Excel文件,依賴於xlrdxlwt

安裝這三個模塊時,可以去PyPI去搜索需要的模塊並下載。在我寫這篇文章時,xlrd是有一個適合python 3.x的.whl文件和一個通用的.tar.gz的源碼文件。xlwt是提供了同時適用於python 2.x和3.x的.whl文件和一個通用的.tar.gz的源碼文件,還提供了pip的安裝方式。xlutilsxlwt情況相同。

安裝過程中我是默認你已經配好了環境變量,並且pip是可用的,如果在命令行裏執行pip命令顯示找不到命令,可以在網上搜索相關解決方案,這裏不做贅述。

下面簡單說一下幾種安裝模塊的方式。

安裝源碼文件需要先解壓,然後進入到源碼目錄執行下面命令:

python setup.py install
  • 1

安裝.whl文件執行下面命令:

pip install <你的.whl文件>
  • 1

使用pip安裝前要確認你的網絡是可用的,然後執行命令:

pip install <模塊名>
  • 1

當你看到類似Successfully的字樣時,表明已經安裝成功了。如果沒成功,那就一定是有什麼原因了,可以自己上網搜索具體解決方案。

使用xlrd讀Excel

xlrd提供的接口比較多,常用的如下:

open_workbook()打開指定的Excel文件,返回一個Book對象。

通過Book對象可以得到各個Sheet對象(一個Excel文件可以有多個Sheet,每個Sheet就是一張表格)。

Book.nsheets返回Sheet的數目。

Book.sheets()返回所有Sheet對象的list。

Book.sheet_by_index(index)返回指定索引處的Sheet。相當於Book.sheets()[index]

Book.sheet_names()返回所有Sheet對象名字的list。

Book.sheet_by_name(name)根據指定Sheet對象名字返回Sheet。

通過Sheet對象可以獲取各個單元格,每個單元格是一個Cell對象。

Sheet.name返回表格的名稱。

Sheet.nrows返回表格的行數。

Sheet.ncols返回表格的列數。

Sheet.row(r)獲取指定行,返回Cell對象的list。

Sheet.row_values(r)獲取指定行的值,返回list。

Sheet.col(c)獲取指定列,返回Cell對象的list。

Sheet.col_values(c)獲取指定列的值,返回list。

Sheet.cell(r, c)根據位置獲取Cell對象。

Sheet.cell_value(r, c)根據位置獲取Cell對象的值。

Cell.value返回單元格的值。

下面是一段示例代碼:

import xlrd

wb = xlrd.workbook('test.xls')

# 打印每張表的最後一列
# 方法1
for s in wb.sheets():
    print "== The last column of sheet '%s' ==" % (s.name)
    for i in range(s.nrows):
        print s.row(i)[-1].value

# 方法2
for i in range(wb.nsheets):
    s = wb.sheet_by_index(i)
    print "== The last column of sheet '%s' ==" % (s.name)
    for v in s.col_values(s.ncols - 1):
        print v

# 方法3
for name in wb.sheet_names():
    print "== The last column of sheet '%s' ==" % (name)
    s = wb.sheet_by_name(name)
    c = s.ncols - 1
    for r in range(s.nrows):
        print s.cell_value(r, c)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

使用xlwt寫Excel

相對來說,xlwt提供的接口就沒有xlrd那麼多了,主要如下:

Workbook()是構造函數,返回一個工作簿的對象。

Workbook.add_sheet(name)添加了一個名爲name的表,類型爲Worksheet。

Workbook.get_sheet(index)可以根據索引返回Worksheet(前提是已經添加到Workbook中了)。

Worksheet.write(r, c, vlaue)是將vlaue填充到指定位置。

Worksheet.row(n)返回指定的行。

Row.write(c, value)在某一行的指定列寫入value。

Worksheet.col(n)返回指定的列。

通過對Row.heightColumn.width賦值可以改變行或列默認的高度或寬度。(單位:0.05 pt,即1/20 pt)

Workbook.save(filename)保存文件。

有這麼幾點需要注意一下:

  • xlwt模塊最大能寫65535行,256列,如果超過這個範圍,程序運行就會出現錯誤,那麼可能需要找一些其他方法來解決。如果我們只注重數據的處理,那麼可以採用csv模塊來替代。

  • 文件默認的編碼方式是ascii,如果要改變編碼方式,指定Workbook()encoding參數,如 
    Workbook(encoding='utf-8')

  • 表的單元格默認是不可重複寫的,如果有需要,在調用add_sheet()的時候指定參數cell_overwrite_ok=True即可。

下面是一段示例代碼:

import xlwt

book = xlwt.Workbook(encoding='utf-8')
sheet = book.add_sheet('sheet_test', cell_overwrite_ok=True)

sheet.write(0, 0, 'Python')
sheet.row(0).write(1, 'is')
sheet.write(0, 2, 'very very useful.')
sheet.col(2).width = 4000

book.save('test.xls')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

除了基本的寫入數據之外,xlwt還可以改變單元格格式。上面的write方法允許接受一個XFStyle(意爲eXcel File Style)類型的參數,放在最後的位置。easyxf()可以快速生成一個XFStyle對象。

這裏簡單介紹一下其用法:

import datetime, xlwt

# ... some code

font = xlwt.Font()
font.name = 'Arial'
font.height = 240 # font size: 12pt

pattern = xlwt.Pattern()
pattern.pattern = xlwt.Pattern.SOLID_PATTERN
pattern.pattern_fore_colour = 0x0A

style = xlwt.XFStyle()
style.num_format_str = '0.00%'
style.font = font
style.pattern = pattern

a = 8
b = 10
# 以百分比的形式顯示,保留兩位小數
sheet.write(0,3, float(a) / b, style)

# 顯示日期
sheet.row(0).write(4, datetime.date(2016,8,14), xlwt.easyxf(
        'font: name Arial, height 240;'
        'pattern: pattern squares, fore_color red;',
        num_format_str = 'YYYY-MM-DD'
    )
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

使用xlutils修改Excel

通過xlrd.open_workbook()打開的Book對象是隻讀的,不能直接對其進行修改操作,而xlwt.Workbook()返回的Workbook對象雖然可寫,但是寫的時候只能從零寫起,那如果要修改一個已經存在的Excel該怎麼辦呢?

慶幸的是,在xlutils.copy中有個copy()方法,我們可以將一個xlrd.Book對象轉化爲一個xlwt.Workbook對象,這樣我們就可以直接對已存在的Excel文件進行修改了。

用法舉例如下:

import xlrd
import xlutils.copy

book = xlrd.open_workbook('test.xls', formatting_info=True)
wtbook = xlutils.copy.copy(book)
wtsheet = wtbook.get_sheet(0)
wtsheet.write(0, 0, 'Ok, changed!')
wtbook.save('test.xls')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

要注意的是:

  • 調用xlrd.open_workbook()時,如果不指定formatting_info=True,那麼修改後整個文檔的樣式會丟失。對一個單元格進行write操作時,如果不指定樣式,也會將原來的樣式丟失。

  • 注意調用copy()的方法。也可以通過聲明from xlutils.copy import copy來直接調用copy()

使用csv讀寫csv文件

與讀寫Excel文件相比,csv文件的讀寫是相當方便的。 
直接看下面的例子吧。

import csv

file1 = open('test1.csv', 'rb')
reader = csv.reader(file1)

for line in reader:
    for col in line:
        print col,
    print

file1.close()

file2 = file('test2.csv', 'wb')
writer = csv.writer(file2)

writer.writerow([1,2,3,4,5])
writer.writerows([
    [6,7,8],
    [9,10,11,12],
    [13,14,15,16,17]
])
file2.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

這個程序涉及到了下面的方法:

  • csv.reader()返回一個DictReader對象。
  • csv.writer()返回一個DictWriter對象。
  • DictWriter.writerow()寫一行。
  • DictWriter.writerows()寫多行。

需要注意的問題是:當我們需要寫csv的時候,打開文件一定要帶上’b’,否則可能會往文件裏輸出空行。Python 3.x情況會有些不同。

More…

[1] https://github.com/python-excel/xlrd/ 
[2] https://github.com/python-excel/xlwt/ 
[3] https://github.com/python-excel/tutorial/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章