java的POI操作Excel文件
微軟在桌面系統(tǒng)上的成功,令我們不得不大量使用它的辦公產(chǎn)品,如:Word,Excel。時(shí)至今日,它的源代碼仍然不公開(kāi)已封鎖了我們的進(jìn)一步應(yīng)用和開(kāi)發(fā)。然而在要求更高的服務(wù)器領(lǐng)域,微軟本身的產(chǎn)品移植性不好,
性能不佳。在我們實(shí)際的開(kāi)發(fā)中,表現(xiàn)層的解決方案雖然有多樣,但是Ie瀏覽器已成為最多人使用的瀏覽器,因?yàn)榇蠹叶加?/font>Windows。在企業(yè)辦公系統(tǒng)中,常常有客戶(hù)這樣子要求:你要把我們的報(bào)表直接用Excel打開(kāi)。或者是:我們已經(jīng)習(xí)慣用Excel打印。這樣子如果用.net開(kāi)發(fā)是沒(méi)有問(wèn)題的,但是有j2ee這個(gè)比.net更有前途的開(kāi)放式的開(kāi)發(fā)環(huán)境,難道我為了解決打印的要求去另寫(xiě)客戶(hù)端的控件?或者在服務(wù)器端使用本地代碼?第一種方案的問(wèn)題是關(guān)鍵數(shù)據(jù)的處理有時(shí)候不能在客戶(hù)端做,第2種方案的問(wèn)題是犧牲了代碼的可移植性和穩(wěn)定性。如果讓客戶(hù)端只負(fù)責(zé)處理生成好的報(bào)表,那將是一種誘人的選擇。
Apache的Jakata項(xiàng)目的POI子項(xiàng)目,目標(biāo)是處理ole2對(duì)象。目前比較成熟的是HSSF接口,處理MS Excel(97-2002)對(duì)象。它不象我們僅僅是用csv生成的沒(méi)有格式的可以由Excel轉(zhuǎn)換的東西,而是真正的Excel對(duì)象,你可以控制一些屬性如sheet,cell等等。這是一個(gè)年輕的項(xiàng)目,所以象HDF這樣直接支持Word對(duì)象的好東西仍然在設(shè)計(jì)中。其它支持word格式的純java方案還有itext,不過(guò)也是仍在奮斗中。但是HSSF已經(jīng)成熟到能夠和足夠我們使用了。另外,無(wú)錫永中Office的實(shí)現(xiàn)方案也是純java的解決方案,不過(guò)那也是完全商業(yè)的產(chǎn)品,并不是公開(kāi)代碼項(xiàng)目。其實(shí),從開(kāi)發(fā)歷史的角度講,在80年代中期starOffice的原作者在德國(guó)成立了StarOffice suite公司,然后到1999年夏天starOffice被sun收購(gòu),再到2000年6月starOffice5.2的發(fā)布;并且從starOffice6.0開(kāi)始,starOffice建立在OpenOffice的api的基礎(chǔ)上,這個(gè)公開(kāi)代碼的office項(xiàng)目已經(jīng)進(jìn)行了很長(zhǎng)的時(shí)間。雖然那是由C++寫(xiě)的,但是POI的代碼部分也是由openOffice改過(guò)來(lái)的。所以,應(yīng)該對(duì)POI充滿(mǎn)足夠的信心。國(guó)內(nèi)已經(jīng)有部分公司在他們的辦公自動(dòng)化等Web項(xiàng)目中使用poi了,如日恒的ioffice,海泰的HTOffice等。
java當(dāng)初把核心處理設(shè)成Unicode,帶來(lái)的好處是另代碼適應(yīng)了多語(yǔ)言環(huán)境。然而由于老外的英語(yǔ)只有26個(gè)字母,有些情況下,一些程序員用8位的byte處理,一不小心就去掉了CJK的高位。或者是由于習(xí)慣在程序中采用硬編碼,還有多種原因,使得許多java應(yīng)用在CJK的處理上很煩惱。還好在POI HSSF中考慮到這個(gè)問(wèn)題,可以設(shè)置encoding為雙字節(jié)。
POI可以到www.apache.org下載到。編譯好的jar主要有這樣4個(gè):poi包,poi Browser包,poi hdf包,poi hssf例程包。實(shí)際運(yùn)行時(shí),需要有poi包就可以了。如果用Jakarta ant編譯和運(yùn)行,下載apache Jakarta POI的release中的src包,它里面已經(jīng)為你生成好了build文件了。只要運(yùn)行ant就可以了(ant 的安裝和使用在此不說(shuō)了)。如果是用Jbuilder 運(yùn)行,請(qǐng)?jiān)谛陆ǖ捻?xiàng)目中加入poi包。以Jbuilder6為例,選擇Tools菜單項(xiàng)的config libraries...選項(xiàng),新建一個(gè)lib。在彈出的菜單中選擇poi包,如這個(gè)jakarta-poi-1.5.1-final-20020820.jar,把poi添加到jbuilder中。然后,右鍵點(diǎn)擊你的項(xiàng)目,在project的properties菜單中path的required Libraries中,點(diǎn)add,添加剛才加入到jbuilder中的poi到你現(xiàn)在的項(xiàng)目中。如果你僅僅是為了熟悉POI hssf的使用,可以直接看POI的samples包中的源代碼,并且運(yùn)行它。hssf的各種對(duì)象都有例程的介紹。hssf提供的例程在org.apache.poi.hssf.usermodel.examples包中,共有14個(gè),生成的目標(biāo)xls都是workbook.xls。如果你想看更多的例程,可以參考hssf的Junit test cases,在poi的包的源代碼中有。hssf都有測(cè)試代碼。
這里只對(duì)部分例程的實(shí)現(xiàn)做介紹。
HSSF提供給用戶(hù)使用的對(duì)象在org.apache.poi.hssf.usermodel包中,主要部分包括Excell對(duì)象,樣式和格式,還有輔助操作。有以下幾種對(duì)象:
HSSFWorkbook excell的文檔對(duì)象
HSSFSheet excell的表單
HSSFRow excell的行
HSSFCell excell的格子單元
HSSFFont excell字體
HSSFName 名稱(chēng)
HSSFDataFormat 日期格式
在poi1.7中才有以下2項(xiàng):
HSSFHeader sheet頭
HSSFFooter sheet尾
和這個(gè)樣式
HSSFCellStyle cell樣式
輔助操作包括
HSSFDateUtil 日期
HSSFPrintSetup 打印
HSSFErrorConstants 錯(cuò)誤信息表
仔細(xì)看org.apache.poi.hssf包的結(jié)構(gòu),不難發(fā)現(xiàn)HSSF的內(nèi)部實(shí)現(xiàn)遵循的是MVC模型。
這里我用Rose把org.apache.poi.hssf.usermodel包中的對(duì)象反向?qū)氩⒏鶕?jù)相互關(guān)系作了整理。從中不難可以發(fā)現(xiàn)每一個(gè)基本對(duì)象都關(guān)聯(lián)了一個(gè)Record對(duì)象。Record對(duì)象是一個(gè)參考Office格式的相關(guān)記錄。
HSSFWorkbook即是一個(gè)Excell對(duì)象。這幅類(lèi)圖體現(xiàn)的是HSSFWorkbook和基本對(duì)象的相互關(guān)系。可見(jiàn),許多對(duì)象中也建立了Workbook的引用。還需要注意的是在HSSFWorkbook和HSSFSheet中建立了log機(jī)制POILogger,而且POILogger也是使用apache Log4J實(shí)現(xiàn)的。
先看poi的examples包中提供的最簡(jiǎn)單的例子,建立一個(gè)空xls文件。

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

通過(guò)這個(gè)例子,我們建立的是一個(gè)空白的xls文件(不是空文件)。在此基礎(chǔ)上,我們可以進(jìn)一步看其它的例子。

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

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

我稍微修改了原來(lái)的examples包中的CreateCells類(lèi)寫(xiě)了上面的功能測(cè)試類(lèi)。通過(guò)這個(gè)例子,我們可以清楚的看到xls文件從大到小包括了HSSFWorkbook HSSFSheet HSSFRow HSSFCell這樣幾個(gè)對(duì)象。我們可以在cell中設(shè)置各種類(lèi)型的值。尤其要注意的是如果你想正確的顯示非歐美的字符時(shí),尤其象中日韓這樣的語(yǔ)言,必須設(shè)置編碼為16位的即是HSSFCell.ENCODING_UTF_16,才能保證字符的高8位不被截?cái)喽鹁幋a失真形成亂碼。
其他測(cè)試可以通過(guò)參考examples包中的測(cè)試?yán)诱莆?/font>poi的詳細(xì)用法,包括字體的設(shè)置,cell大小和低紋的設(shè)置等。需要注意的是POI是一個(gè)仍然在完善中的公開(kāi)代碼的項(xiàng)目,所以有些功能正在不斷的擴(kuò)充。如HSSFSheet的getFooter() getHeader()和setFooter(HSSFFooter hsf) setHeader(HSSFHeader hsh)是在POI1.7中才有的,而POI1.5中就沒(méi)有。運(yùn)行測(cè)試熟悉代碼或者使用它做項(xiàng)目時(shí)請(qǐng)注意POI的版本。
另外需要注意的是HSSF也有它的對(duì)xls基于事件的解析。可以參考例程中的EventExample.java。它通過(guò)實(shí)現(xiàn)HSSFListener完成從普通流認(rèn)知Xls中包含的內(nèi)容,在apache Cocoon中的org.apache.cocoon.serialization.HSSFSerializer中用到了這個(gè)解析。因?yàn)?/font>Cocoon2是基于事件的,所以POI為了提供快速的解析也提供了相應(yīng)的事件。當(dāng)然我們自己也可以實(shí)現(xiàn)這個(gè)事件接口。
因?yàn)?font face="Times New Roman">POI還不是一個(gè)足夠成熟的項(xiàng)目,所以有必要做進(jìn)一步的開(kāi)發(fā)和測(cè)試。但是它已經(jīng)為我們用純java操作ole2對(duì)象提供了可能,而且克服了ole對(duì)象調(diào)用的缺陷,提供了服務(wù)器端的Excel解決方案。
為了保證示例程序的運(yùn)行,必須安裝Java 2 sdk1.4.0 和Jakarta POI,Jakarta POI的Web站點(diǎn)是: http://jakarta.apache.org/poi/
示例1將演示
如何利用Jakarta POI API 創(chuàng)建Excel 文檔。

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

30

31

32


33

34

35

36

37

38

39

讀取Excel文檔中的數(shù)據(jù)
示例2將演示如何讀取Excel文檔中的數(shù)據(jù)。假定在D盤(pán)JTest目錄下有一個(gè)文件名為gongye.xls的Excel文件。
示例2程序如下:

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

設(shè)置單元格格式
在這里,我們將只介紹一些和格式設(shè)置有關(guān)的語(yǔ)句,我們假定workbook就是對(duì)一個(gè)工作簿的引用。在Java中,第一步要做的就是創(chuàng)建和設(shè)置字體和單元格的格式,然后再應(yīng)用這些格式:
1、創(chuàng)建字體,設(shè)置其為紅色、粗體:

2

3

2、創(chuàng)建格式

2

3、應(yīng)用格式

2

3

4

總之,如本篇文章所演示的一樣,Java程序員不必?fù)?dān)心Excel工作表中的數(shù)據(jù)了,利用Jakarta POI API,我們就可以輕易的在程序中存取Excel文檔。
總結(jié)說(shuō)說(shuō)現(xiàn)在我所知道的Java編輯Excel文件的兩大開(kāi)源工具:
jakarta POI和JavaExcelAPI(簡(jiǎn)稱(chēng)JXL),這兩套工具我都試用了一這段時(shí)間,感覺(jué)各有優(yōu)劣吧。POI在某些細(xì)節(jié)有些小Bug并且不支持寫(xiě)入圖片,其他方面都挺不錯(cuò)的;
JXL就慘了,除了支持寫(xiě)入圖片外,我暫時(shí)看不到它比POI好的地方,我碰到的主要的問(wèn)題就是對(duì)公式支持不是很好,很多帶有公式的Excel文件用JXL打開(kāi)后,公式就丟失了(比如now(),today()),在網(wǎng)上看到其他大蝦評(píng)論說(shuō)JXL寫(xiě)入公式也有問(wèn)題,另外,JXL操作Excel文件的效率比POI低一點(diǎn)。經(jīng)過(guò)比較后,我選擇了POI開(kāi)發(fā)我的項(xiàng)目。
posted on 2011-07-04 16:10 何智 閱讀(8308) 評(píng)論(1) 編輯 收藏 所屬分類(lèi): Java Util