鍍金池/ 教程/ Python/ 電子表格
標準庫 (4)
如何成為 Python 高手
標準庫 (6)
標準庫 (3)
類(2)
Pandas 使用 (2)
xml
用 tornado 做網(wǎng)站 (5)
文件(1)
練習
列表(3)
從小工到專家
除法
錯誤和異常 (2)
函數(shù)(1)
用 tornado 做網(wǎng)站 (7)
為做網(wǎng)站而準備
函數(shù)練習
標準庫 (8)
Pandas 使用 (1)
回顧 list 和 str
字典(1)
用 tornado 做網(wǎng)站 (3)
字符串(1)
函數(shù)(2)
寫一個簡單的程序
將數(shù)據(jù)存入文件
語句(5)
SQLite 數(shù)據(jù)庫
集成開發(fā)環(huán)境(IDE)
集合(1)
類(1)
用 tornado 做網(wǎng)站 (6)
用 tornado 做網(wǎng)站 (2)
自省
語句(4)
錯誤和異常 (1)
用 tornado 做網(wǎng)站 (4)
集合(2)
列表(1)
標準庫 (1)
生成器
mysql 數(shù)據(jù)庫 (1)
第三方庫
實戰(zhàn)
運算符
類(3)
字典(2)
語句(1)
數(shù)和四則運算
語句(2)
文件(2)
MySQL 數(shù)據(jù)庫 (2)
電子表格
迭代器
mongodb 數(shù)據(jù)庫 (1)
特殊方法 (2)
特殊方法 (1)
字符編碼
編寫模塊
用 tornado 做網(wǎng)站 (1)
標準庫 (5)
函數(shù)(4)
類(5)
字符串(2)
關(guān)于 Python 的故事
函數(shù)(3)
字符串(4)
處理股票數(shù)據(jù)
常用數(shù)學(xué)函數(shù)和運算優(yōu)先級
字符串(3)
為計算做準備
多態(tài)和封裝
類(4)
迭代
語句(3)
錯誤和異常 (3)
分析 Hello
Python 安裝
標準庫 (2)
列表(2)
元組

電子表格

一提到電子表格,可能立刻想到的是 excel。殊不知,電子表格,還是“歷史悠久”的呢,比 word 要長久多了。根據(jù)維基百科的記載整理一個簡史:

VisiCalc 是第一個電子表格程序,用于蘋果II型電腦。由丹·布李克林(Dan Bricklin)和鮑伯·法蘭克斯頓(Bob Frankston)發(fā)展而成,1979 年 10 月跟著蘋果二號電腦推出,成為蘋果二號電腦上的「殺手應(yīng)用軟件」。

接下來是 Lotus 1-2-3,由 Lotus Software(美國蓮花軟件公司)于 1983 年起所推出的電子試算表軟件,在 DOS 時期廣為個人電腦使用者所使用,是一套殺手級應(yīng)用軟件。也是世界上第一個銷售超過 100 萬套的軟件。

然后微軟也開始做電子表格,早在 1982 年,它推出了它的第一款電子制表軟件──Multiplan,並在 CP/M 系統(tǒng)上大獲成功,但在 MS-DOS 系統(tǒng)上,Multiplan 敗給了 Lotus 1-2-3。

1985 年,微軟推出第一款 Excel,但它只用于 Mac 系統(tǒng);直到 1987 年 11 月,微軟的第一款適用于 Windows 系統(tǒng)的 Excel 才誕生,不過,它一出來,就與 Windows 系統(tǒng)直接捆綁,由于此后 windows 大行其道,并且 Lotus1-2-3 遲遲不能適用于 Windows 系統(tǒng),到了 1988 年,Excel 的銷量超過了 1-2-3。

此后就是微軟的天下了,Excel 后來又并入了 Office 里面,成為了 Microsoft Office Excel。

盡管 Excel 已經(jīng)發(fā)展了很多代,提供了大量的用戶界面特性,但它仍然保留了第一款電子制表軟件 VisiCalc 的特性:行、列組成單元格,數(shù)據(jù)、與數(shù)據(jù)相關(guān)的公式或者對其他單元格的絕對引用保存在單元格中。

由于微軟獨霸天下,Lotus 1-2-3 已經(jīng)淡出了人們的視線,甚至于誤認為歷史就是從微軟開始的。

其實,除了微軟的電子表格,在 Linux 系統(tǒng)中也有很好的電子表格,google 也提供了不錯的在線電子表格(可惜某國內(nèi)不能正常訪問)。

從歷史到現(xiàn)在,電子表格都很廣泛的用途。所以,Python 也要操作一番電子表格,因為有的數(shù)據(jù),或許就是存在電子表格中。

openpyl

openpyl 模塊是解決 Microsoft Excel 2007/2010 之類版本中擴展名是 Excel 2010 xlsx/xlsm/xltx/xltm 的文件的讀寫的第三方庫。(差點上不來氣,這句話太長了。)

安裝

安裝第三方庫,當然用法力無邊的 pip install

$ sudo pip install openpyxl

如果最終看到下面的提示,恭喜你,安裝成功。

Successfully installed openpyxl jdcal
Cleaning up...

workbook 和 sheet

第一步,當然是要引入模塊,用下面的方式:

>>> from openpyxl import Workbook

接下來就用 Workbook() 類里面的方法展開工作:

>>> wb = Workbook()

請回憶 Excel 文件,如果想不起來,就打開 Excel,我們第一眼看到的是一個稱之為工作簿(workbook)的東西,里面有幾個 sheet,默認是三個,當然可以隨意增刪。默認又使用第一個 sheet。

>>> ws = wb.active

每個工作簿中,至少要有一個 sheet,通過這條指令,就在當前工作簿中建立了一個 sheet,并且它是當前正在使用的。

還可以在這個 sheet 后面追加:

>>> ws1 = wb.create_sheet()

甚至,還可以加塞:

>>> ws2 = wb.create_sheet(1)

排在了第二個位置。

在 Excel 文件中一樣,創(chuàng)建了 sheet 之后,默認都是以"Sheet1"、"Sheet2"樣子來命名的,然后我們可以給其重新命名。在這里,依然可以這么做。

>>> ws.title = "Python"

ws所引用的sheet對象名字就是"Python"了。

此時,可以使用下面的方式從工作簿對象中得到 sheet

>>> ws01 = wb['Python']    #sheet 和工作簿的關(guān)系,類似鍵值對的關(guān)系
>>> ws is ws01
True

或者用這種方式

>>> ws02 = wb.get_sheet_by_name("Python")    #這個方法名字也太直接了,方法的參數(shù)就是 sheet 名字
>>> ws is ws02
True

整理一下到目前為止我們已經(jīng)完成的工作:建立了工作簿(wb),還有三個 sheet。還是顯示一下比較好:

>>> print wb.get_sheet_names()
['Python', 'Sheet2', 'Sheet1']

Sheet2 這個 sheet 之所以排在了第二位,是因為在建立的時候,用了一個加塞的方法。這跟 Excel 中差不多少,如果 sheet 命名了,就按照那個名字顯示,否則就默認為名字是"Sheet1"形狀的(注意,第一個字母大寫)。

也可以用循環(huán)語句,把所有的 sheet 名字打印出來。

>>> for sh in wb:
...     print sh.title
... 
Python
Sheet2
Sheet1

如果讀者去 dir(wb) 工作簿對象的屬性和方法,會發(fā)現(xiàn)它具有迭代的特征__iter__方法。說明,工作簿是可迭代的。

cell

為了能夠清楚理解填數(shù)據(jù)的過程,將電子表中約定的名稱以下圖方式說明:

http://wiki.jikexueyuan.com/project/start-learning-python/images/23401.jpg" alt="" />

對于 sheet,其中的 cell 是它的下級單位。所以,要得到某個 cell,可以這樣:

b4 = ws['B4']

如果 B4 這個 cell 已經(jīng)有了,用這種方法就是將它的值賦給了變量 b4;如果 sheet 中沒有這個 cell,那么就創(chuàng)建這個 cell 對象。

請讀者注意,當我們打開 Excel,默認已經(jīng)畫好了好多 cell。但是,在 Python 操作的電子表格中,不會默認畫好那樣一個表格,一切都要創(chuàng)建之后才有。所以,如果按照前面的操作流程,上面就是創(chuàng)建了 B4 這個 cell,并且把它作為一個對象被 b4 變量引用。

如果要給 B4 添加數(shù)據(jù),可以這么做:

>>> ws['B4'] = 4444

因為 b4 引用了一個 cell 對象,所以可以利用這個對象的屬性來查看其值:

>>> b4.value
4444

要獲得(或者建立并獲得)某個 cell 對象,還可以使用下面方法:

>>> a1 = ws.cell("A1")

或者:

>>> a2 = ws.cell(row = 2, column = 1)

剛才已經(jīng)提到,在建立了 sheet 之后,內(nèi)存中的它并沒有 cell,需要程序去建立。上面都是一個一個地建立,能不能一下建立多個呢?比如要類似下面的:

|A1|B1|C1| |A2|B2|C2| |A3|B3|C3|

就可以如同切片那樣來操作:

>>> cells = ws["A1":"C3"]

可以用下面方法看看創(chuàng)建結(jié)果:

>>> tuple(ws.iter_rows("A1:C3"))
((<Cell python.A1>, <Cell Python.B1>, <Cell Python.C1>), 
 (<Cell python.A2>, <Cell Python.B2>, <Cell Python.C2>), 
 (<Cell python.A3>, <Cell Python.B3>, <Cell Python.C3>))

這是按照橫向順序數(shù)過來來的,即 A1-B1-C1,然后下一橫行。還可以用下面的循環(huán)方法,一個一個地讀到每個 cell 對象:

>>> for row in ws.iter_rows("A1:C3"):
...     for cell in row:
...         print cell
... 
<Cell Python.A1>
<Cell Python.B1>
<Cell Python.C1>
<Cell Python.A2>
<Cell Python.B2>
<Cell Python.C2>
<Cell Python.A3>
<Cell Python.B3>
<Cell Python.C3>

也可以用 sheet 對象的 rows 屬性,得到按照橫向順序依次排列的 cell 對象(注意觀察結(jié)果,因為沒有進行范圍限制,所以是目前 sheet 中所有的 cell,前面已經(jīng)建立到第四行了 B4,所以,要比上面的操作多一個 row):

>>> ws.rows
((<Cell python.A1>, <Cell python.B1>, <Cell python.C1>), 
 (<Cell python.A2>, <Cell python.B2>, <Cell python.C2>), 
 (<Cell python.A3>, <Cell python.B3>, <Cell python.C3>), 
 (<Cell python.A4>, <Cell python.B4>, <Cell python.C4>))

用 sheet 對象的 columns 屬性,得到的是按照縱向順序排列的 cell 對象(注意觀察結(jié)果):

>>> ws.columns
((<Cell python.A1>, <Cell python.A2>, <Cell python.A3>, <Cell python.A4>), 
 (<Cell python.B1>, <Cell python.B2>, <Cell python.B3>, <Cell python.B4>), 
 (<Cell python.C1>, <Cell python.C2>, <Cell python.C3>, <Cell python.C4>))

不管用那種方法,只要得到了 cell 對象,接下來就可以依次賦值了。比如要將上面的表格中,依次填寫上 1,2,3,...

>>> i = 1
>>> for cell in ws.rows:
...     cell.value = i
...     i += 1

... Traceback (most recent call last): File "", line 2, in AttributeError: 'tuple' object has no attribute 'value'

報錯了。什么錯誤。關(guān)鍵就是沒有注意觀察上面的結(jié)果。tuple 里面是以 tuple 為元素,再里面才是 cell 對象。所以,必須要“時時警醒”,常常謹慎。

>>> for row in ws.rows:
...     for cell in row:
...         cell.value = i
...         i += 1
... 

如此,就給每個 cell 添加了數(shù)據(jù)。查看一下,不過要換一個屬性:

>>> for col in ws.columns:
...     for cell in col:
...         print cell.value
... 
1
4
7
10
2
5
8
11
3
6
9
12

雖然看著有點不舒服,但的確達到了前面的要求。

保存

把辛苦工作的結(jié)果保存一下吧。

>>> wb.save("23401.xlsx")

如果有同名文件存在,會覆蓋。

此時,可以用 Excel 打開這個文件,看看可視化的結(jié)果:

http://wiki.jikexueyuan.com/project/start-learning-python/images/23402.jpg" alt="" />

讀取已有文件

如果已經(jīng)有一個 .xlsx 文件,要讀取它,可以這樣來做:

>>> from openpyxl import load_workbook
>>> wb2 = load_workbook("23401.xlsx")
>>> print wb2.get_sheet_names()
['python', 'Sheet2', 'Sheet1']
>>> ws_wb2 = wb2["python"]
>>> for row in ws_wb2.rows:
...     for cell in row:
...         print cell.value
... 
1
2
3
4
5
6
7
8
9
10
11
12

很好,就是這個文件。

其它第三方庫

針對電子表格的第三方庫,除了上面這個 openpyxl 之外,還有別的,列出幾個,供參考,使用方法大同小異。

  • xlsxwriter:針對 Excel 2010 格式,如 .xlsx,官方網(wǎng)站:https://xlsxwriter.readthedocs.org/,這個官方文檔寫的圖文并茂。非常好讀。

下面兩個用來處理 .xls 格式的電子表表格。


總目錄   |   上節(jié):SQLite數(shù)據(jù)庫   |   下節(jié):實戰(zhàn)-引

如果你認為有必要打賞我,請通過支付寶:qiwsir@126.com,不勝感激。