一提到電子表格,可能立刻想到的是 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 模塊是解決 Microsoft Excel 2007/2010 之類版本中擴展名是 Excel 2010 xlsx/xlsm/xltx/xltm 的文件的讀寫的第三方庫。(差點上不來氣,這句話太長了。)
安裝第三方庫,當然用法力無邊的 pip install
$ sudo pip install openpyxl
如果最終看到下面的提示,恭喜你,安裝成功。
Successfully installed openpyxl jdcal
Cleaning up...
第一步,當然是要引入模塊,用下面的方式:
>>> 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__
方法。說明,工作簿是可迭代的。
為了能夠清楚理解填數(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 "
報錯了。什么錯誤。關(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 之外,還有別的,列出幾個,供參考,使用方法大同小異。
下面兩個用來處理 .xls 格式的電子表表格。
總目錄 | 上節(jié):SQLite數(shù)據(jù)庫 | 下節(jié):實戰(zhàn)-引
如果你認為有必要打賞我,請通過支付寶:qiwsir@126.com,不勝感激。