一提到電子表格,可能立刻想到的是excel。殊不知,電子表格,還是“歷史悠久”的呢,比word要長久多了。根據維基百科的記載整理一個簡史:
> VisiCalc是第一個電子表格程序,用于蘋果II型電腦。由丹·布李克林(Dan Bricklin)和鮑伯·法蘭克斯頓(Bob Frankston)發展而成,1979年10月跟著蘋果二號電腦推出,成為蘋果二號電腦上的「殺手應用軟體」。
>
> 接下來是Lotus 1-2-3,由Lotus Software(美國蓮花軟體公司)於1983年起所推出的電子試算表軟體,在DOS時期廣為個人電腦使用者所使用,是一套殺手級應用軟體。也是世界上第一個銷售超過100萬套的軟件。
>
> 然后微軟也開始做電子表格,早在1982年,它推出了它的第一款電子制表軟件──Multiplan,並在CP/M系統上大獲成功,但在MS-DOS系統上,Multiplan敗給了Lotus 1-2-3。
>
> 1985年,微軟推出第一款Excel,但它只用於Mac系統;直到1987年11月,微軟的第一款適用於Windows系統的Excel才誕生,不過,它一出來,就與Windows系統直接捆綁,由于此后windows大行其道,并且Lotus1-2-3遲遲不能適用於Windows系統,到了1988年,Excel的銷量超過了1-2-3。
>
> 此后就是微軟的天下了,Excel后來又并入了Office里面,成為了Microsoft Office Excel。
>
> 盡管Excel已經發展了很多代,提供了大量的用戶界面特性,但它仍然保留了第一款電子制表軟件VisiCalc的特性:行、列組成單元格,數據、與數據相關的公式或者對其他單元格的絕對引用保存在單元格中。
>
> 由于微軟獨霸天下,Lotus 1-2-3已經淡出了人們的視線,甚至于誤認為歷史就是從微軟開始的。
>
> 其實,除了微軟的電子表格,在Linux系統中也有很好的電子表格,google也提供了不錯的在線電子表格(可惜某國內不能正常訪問)。
從歷史到現在,電子表格都很廣泛的用途。所以,python也要操作一番電子表格,因為有的數據,或許就是存在電子表格中。
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/234.md#openpyl)openpyl
openpyl模塊是解決Microsoft Excel 2007/2010之類版本中擴展名是Excel 2010 xlsx/xlsm/xltx/xltm的文件的讀寫的第三方庫。(差點上不來氣,這句話太長了。)
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/234.md#安裝)安裝
安裝第三方庫,當然用法力無邊的pip install
~~~
$ sudo pip install openpyxl
~~~
如果最終看到下面的提示,恭喜你,安裝成功。
~~~
Successfully installed openpyxl jdcal
Cleaning up...
~~~
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/234.md#workbook和sheet)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文件中一樣,創建了sheet之后,默認都是以"Sheet1"、"Sheet2"樣子來命名的,然后我們可以給其重新命名。在這里,依然可以這么做。
~~~
>>> ws.title = "python"
~~~
ws所引用的sheet對象名字就是"python"了。
此時,可以使用下面的方式從工作簿對象中得到sheet
~~~
>>> ws01 = wb['python'] #sheet和工作簿的關系,類似鍵值對的關系
>>> ws is ws01
True
~~~
或者用這種方式
~~~
>>> ws02 = wb.get_sheet_by_name("python") #這個方法名字也太直接了,方法的參數就是sheet名字
>>> ws is ws02
True
~~~
整理一下到目前為止我們已經完成的工作:建立了工作簿(wb),還有三個sheet。還是顯示一下比較好:
~~~
>>> print wb.get_sheet_names()
['python', 'Sheet2', 'Sheet1']
~~~
Sheet2這個sheet之所以排在了第二位,是因為在建立的時候,用了一個加塞的方法。這跟Excel中差不多少,如果sheet命名了,就按照那個名字顯示,否則就默認為名字是"Sheet1"形狀的(注意,第一個字母大寫)。
也可以用循環語句,把所有的sheet名字打印出來。
~~~
>>> for sh in wb:
... print sh.title
...
python
Sheet2
Sheet1
~~~
如果讀者去`dir(wb)`工作簿對象的屬性和方法,會發現它具有迭代的特征`__iter__`方法。說明,工作簿是可迭代的。
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/234.md#cell)cell
為了能夠清楚理解填數據的過程,將電子表中約定的名稱以下圖方式說明:
[](https://github.com/qiwsir/StarterLearningPython/blob/master/2images/23401.jpg)
對于sheet,其中的cell是它的下級單位。所以,要得到某個cell,可以這樣:
~~~
b4 = ws['B4']
~~~
如果B4這個cell已經有了,用這種方法就是將它的值賦給了變量b4;如果sheet中沒有這個cell,那么就創建這個cell對象。
請讀者注意,當我們打開Excel,默認已經畫好了好多cell。但是,在python操作的電子表格中,不會默認畫好那樣一個表格,一切都要創建之后才有。所以,如果按照前面的操作流程,上面就是創建了B4這個cell,并且把它作為一個對象被b4變量引用。
如果要給B4添加數據,可以這么做:
~~~
>>> ws['B4'] = 4444
~~~
因為b4引用了一個cell對象,所以可以利用這個對象的屬性來查看其值:
~~~
>>> b4.value
4444
~~~
要獲得(或者建立并獲得)某個cell對象,還可以使用下面方法:
~~~
>>> a1 = ws.cell("A1")
~~~
或者:
~~~
>>> a2 = ws.cell(row = 2, column = 1)
~~~
剛才已經提到,在建立了sheet之后,內存中的它并沒有cell,需要程序去建立。上面都是一個一個地建立,能不能一下建立多個呢?比如要類似下面的:
|A1|B1|C1| |A2|B2|C2| |A3|B3|C3|
就可以如同切片那樣來操作:
~~~
>>> cells = ws["A1":"C3"]
~~~
可以用下面方法看看創建結果:
~~~
>>> 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>))
~~~
這是按照橫向順序數過來來的,即A1-B1-C1,然后下一橫行。還可以用下面的循環方法,一個一個地讀到每個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對象(注意觀察結果,因為沒有進行范圍限制,所以是目前sheet中所有的cell,前面已經建立到第四行了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對象(注意觀察結果):
~~~
>>> 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'
報錯了。什么錯誤。關鍵就是沒有注意觀察上面的結果。tuple里面是以tuple為元素,再里面才是cell對象。所以,必須要“時時警醒”,常常謹慎。
~~~
>>> for row in ws.rows:
... for cell in row:
... cell.value = i
... i += 1
...
~~~
如此,就給每個cell添加了數據。查看一下,不過要換一個屬性:
~~~
>>> for col in ws.columns:
... for cell in col:
... print cell.value
...
1
4
7
10
2
5
8
11
3
6
9
12
~~~
雖然看著有點不舒服,但的確達到了前面的要求。
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/234.md#保存)保存
把辛苦工作的結果保存一下吧。
~~~
>>> wb.save("23401.xlsx")
~~~
如果有同名文件存在,會覆蓋。
此時,可以用Excel打開這個文件,看看可視化的結果:
[](https://github.com/qiwsir/StarterLearningPython/blob/master/2images/23402.jpg)
### [](https://github.com/qiwsir/StarterLearningPython/blob/master/234.md#讀取已有文件)讀取已有文件
如果已經有一個.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
~~~
很好,就是這個文件。
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/234.md#其它第三方庫)其它第三方庫
針對電子表格的第三方庫,除了上面這個openpyxl之外,還有別的,列出幾個,供參考,使用方法大同小異。
* xlsxwriter:針對Excel 2010格式,如.xlsx,官方網站:[https://xlsxwriter.readthedocs.org/](https://xlsxwriter.readthedocs.org/),這個官方文檔寫的圖文并茂。非常好讀。
下面兩個用來處理.xls格式的電子表表格。
* xlrd:網絡文件:[https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html?p=4966](https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html?p=4966)
* xlwt:網絡文件:[http://xlwt.readthedocs.org/en/latest/](http://xlwt.readthedocs.org/en/latest/)
- 第零章 預備
- 關于Python的故事
- 從小工到專家
- Python安裝
- 集成開發環境
- 第壹章 基本數據類型
- 數和四則運算
- 除法
- 常用數學函數和運算優先級
- 寫一個簡單的程序
- 字符串(1)
- 字符串(2)
- 字符串(3)
- 字符串(4)
- 字符編碼
- 列表(1)
- 列表(2)
- 列表(3)
- 回顧list和str
- 元組
- 字典(1)
- 字典(2)
- 集合(1)
- 集合(2)
- 第貳章 語句和文件
- 運算符
- 語句(1)
- 語句(2)
- 語句(3)
- 語句(4)
- 語句(5)
- 文件(1)
- 文件(2)
- 迭代
- 練習
- 自省
- 第叁章 函數
- 函數(1)
- 函數(2)
- 函數(3)
- 函數(4)
- 函數練習
- 第肆章 類
- 類(1)
- 類(2)
- 類(3)
- 類(4)
- 類(5)
- 多態和封裝
- 特殊方法(1)
- 特殊方法(2)
- 迭代器
- 生成器
- 上下文管理器
- 第伍章 錯誤和異常
- 錯誤和異常(1)
- 錯誤和異常(2)
- 錯誤和異常(3)
- 第陸章 模塊
- 編寫模塊
- 標準庫(1)
- 標準庫(2)
- 標準庫(3)
- 標準庫(4)
- 標準庫(5)
- 標準庫(6)
- 標準庫(7)
- 標準庫(8)
- 第三方庫
- 第柒章 保存數據
- 將數據存入文件
- mysql數據庫(1)
- MySQL數據庫(2)
- mongodb數據庫(1)
- SQLite數據庫
- 電子表格
- 第捌章 用Tornado做網站
- 為做網站而準備
- 分析Hello
- 用tornado做網站(1)
- 用tornado做網站(2)
- 用tornado做網站(3)
- 用tornado做網站(4)
- 用tornado做網站(5)
- 用tornado做網站(6)
- 用tornado做網站(7)
- 第玖章 科學計算
- 為計算做準備
- Pandas使用(1)
- Pandas使用(2)
- 處理股票數據
- 附:網絡文摘
- 如何成為Python高手
- ASCII、Unicode、GBK和UTF-8字符編碼的區別聯系