(轉載)NPOI使用手冊,實踐發現使用2.2版本的庫需要稍作調整
NPOI使用手冊
目錄
1.認識NPOI
2. 使用NPOI生成xls檔案
2.1 建立基本內容
Workbook和Sheet
DocumentSummaryInformation和SummaryInformation
2.2 單元格操作
2.3 使用Excel公式
NPOI獲得公式的返回值
2.4 建立圖形
2.6 高階功能
3. 專案實踐
3.1基於
3.4從xls檔案中抽取文字
3.6匯入Excel檔案
本章將介紹NPOI的一些基本資訊,包括以下幾個部分
· 什麼是NPOI
· 版權說明
· 相關資源
· 團隊介紹
· 未來展望
· 各Assembly的作用
1.1 什麼是NPOI
NPOI,顧名思義,就是POI的.NET版本。那POI又是什麼呢?POI是一套用Java寫成的庫,能夠幫助開發者在沒有安裝微軟Office的情況下讀寫Office 97-2003
NPOI 1.x是基於POI 3.x版本開發的,與poi 3.2對應的版本是NPOI 1.2,目前最新發布的版本是1.2.1,在該版本中僅支援讀寫Excel檔案和Drawing格式,其他檔案格式將在以後的版本中得到支援。
1.2 版權說明
NPOI採用的是Apache 2.0許可證(poi也是採用這個許可證),這意味著它可以被用於任何商業或非商業專案,你不用擔心因為使用它而必須開放你自己的原始碼,所以它對於很多從事業務系統開發的公司來說絕對是很不錯的選擇。
當然作為一個開源許可證,肯定也是有一些義務的,例如如果你在系統中使用NPOI,你必須保留NPOI中的所有宣告資訊。對於原始碼的任何修改,必須做出明確的標識。
1.3 相關資源
POIFS Browser 1.2
QQ交流群: 78142590
1.4 團隊介紹
Tony Qu來自於中國上海,是這個專案的發起人和開發人員,時區是GMT+8,2008年9月開始了NPOI的開發,負責NPOI所有底層庫的開發、測試和bug修復。
HüseyinTüfekçilerli來自於土耳其的伊斯坦布林,也是這個專案的開發人員,時區是GMT+2,2008年11月參與了NPOI的開發,主要負責POIFS Browser 1.0的開發工作。
aTao.Xiang,來自中國,2009年8月開始參與該專案,主要參與了NPOI 1.2中文版的撰寫工作和推廣工作
1.5 回顧與展望
目前POI版本中的HWPF(用於Word的讀寫庫)還不是很穩定,並非正式釋出版本,且負責HWPF的關鍵開發人員已經離開,所以NPOI可能考慮自己重新開發HWPF。另外,目前微軟正在開發Open XML Format SDK,NPOI可能會放棄對ooxml的支援,當然這取決於使用者的需求和Open XML Format SDK的穩定性和速度。從目前而言,NPOI有幾大優勢
第一,完全基於.NET 2.0,而非.NET 3.0/3.5。
第二,讀寫速度快(有個國外的兄弟回覆說,他原來用ExcelPackage生成用了4-5個小時,現在只需要4-5分鐘)
第三,穩定性好(相對於用Office OIA而言,畢竟那東西是基於Automation做的,在Server上跑個Automation的東西,想想都覺得可怕),跑過了將近1000個測試用例(來自於POI的testcase目錄)
第四,API簡單易用,當然這得感謝POI的設計師們
第五,完美支援Excel 2003格式(據說myxls無法正確讀取xls模板,但NPOI可以),以後也許是所有Office 2003格式
希望NPOI把這些優勢繼續發揚下去,這樣NPOI才會更有競爭力。
1.6 NPOI 1.2中各Assembly的作用
NPOI目前有好幾個assembly,每個的作用各有不同,開發人員可以按需載入相應的assembly。在這裡大概羅列一下:
NPOI.Util 基礎輔助庫
NPOI.POIFS OLE2格式讀寫庫
NPOI.DDF Microsoft Drawing格式讀寫庫
NPOI.SS Excel公式計算庫
NPOI.HPSF OLE2的Summary Information和Document Summary Information屬性讀寫庫
NPOI.HSSF Excel BIFF格式讀寫庫
- 2.1.1 建立Workbook和Sheet
作者:Tony Qu
建立Workbook說白了就是建立一個Excel檔案,當然在NPOI中更準確的表示是在記憶體中建立一個Workbook物件流。
本節作為第2章的開篇章節,將做較為詳細的講解,以幫助NPOI的學習者更好的理解NPOI的組成和使用。
NPOI.HSSF是專門負責Excel BIFF格式的名稱空間,供開發者使用的物件主要位於NPOI.HSSF.UserModel和NPOI.HSSF.Util名稱空間下,下面我們要講到的Workbook的建立用的就是NPOI.HSSF.UserModel.HSSFWorkbook類,這個類負責建立.xls文件。
在開始建立Workbook之前,我們先要在專案中引用一些必要的NPOI assembly,如下所示:
NPOI.dll
NPOI.POIFS.dll
NPOI.HSSF.dll
NPOI.Util.dll
要建立一個新的xls檔案其實很簡單,只要我們初始化一個新的HSSFWorkbook例項就行了,如下所示:
using NPOI.HSSF.UserModel;
...
HSSFWorkbookhssfworkbook =newHSSFWorkbook();
是不是很方便啊,沒有任何引數或設定,但這麼建立有一些限制,這樣創建出來的Workbook在Excel中開啟是會報錯的,因為Excel規定一個Workbook必須至少帶1個Sheet,這也是為什麼在Excel介面中,新建一個Workbook預設都會新建3個Sheet。所以必須加入下面的建立Sheet的程式碼才能保證生成的檔案正常:
HSSFSheetsheet = hssfworkbook.CreateSheet("newsheet");
如果要建立標準的Excel檔案,即擁有3個Sheet,可以用下面的程式碼:
hssfworkbook.CreateSheet("Sheet1");
hssfworkbook.CreateSheet("Sheet2");
hssfworkbook.CreateSheet("Sheet3");
最後就是把這個HSSFWorkbook例項寫入檔案了,程式碼也很簡單,如下所示:
FileStreamfile =new FileStream(@"test.xls", FileMode.Create);
hssfworkbook.Write(file);
file.Close();
這裡假設檔名是test.xls,,在建立完FileStream之後,直接呼叫HSSFWorkbook類的Write方法就可以了。
最後你可以開啟test.xls檔案確認一下,是不是有3個空的Sheet。
相關範例請見中的CreateEmptyExcelFile專案。
- 2.1.2 建立DocumentSummaryInformation和SummaryInformation
作者:Tony Qu
昨天收到了不少回覆,有msn上的,也有blog上的,我代表NPOI Team向所有支援和關注NPOI的兄弟表示感謝,讓我們共同完善NPOI。
前一節中我們講解了如何建立一個新的Workbook,但在此過程中大家也許會發現一個細節,這些檔案沒有包括DocummentSummaryInformation和SummaryInformation頭。如果你還不是很清楚我在說什麼,可以看POIFS Browser開啟test.xls檔案後的截圖:
你會發現只有Workbook目錄,其他什麼都沒有,但事實上一個正常的xls檔案,比如說Excel生成的xls檔案是類似下面的結構:
是不是多出來DocumentSummaryInformation和SummaryInformation兩個頭?很多人可能對DocumentSummaryInformation和SummaryInformation很陌生,可能第一次聽說這玩意,沒事,這很正常,因為普通使用者很少會去使用這些東西,但它們其實比想象中有用。
請看上圖中的資訊,如作者、標題、標記、備註、主題等資訊,其實這些資訊都是儲存在DocummentSummaryInformation和SummaryInformation裡面的,這麼一說我想大家應該明白了吧,這些資訊是為了快速提取檔案資訊準備。在Windows XP中,也有對應的檢視和修改介面,只是沒有Vista這麼方便,如下所示:
這恐怕也是很多人對於這些資訊漠不關心的原因吧,因為沒有人願意通過右擊檔案->屬性這樣複雜的操作去檢視一些摘要資訊。
提示
DocummentSummaryInformation和SummaryInformation並不是Office檔案的專利,只要是OLE2格式,都可以擁有這兩個頭資訊,主要目的就是為了在沒有完整讀取檔案資料的情況下獲得檔案的摘要資訊,同時也可用作桌面搜素的依據。要了解DocummentSummaryInformation的全部屬性請見;要了解SummaryInformation的全部屬性請見。
好了,說到這裡,我想大家對於接下來我們要建立的內容有了初步的認識,下面我們就馬上動手建立。
首先引用以下這些名稱空間:
using NPOI.HSSF.UserModel;
using NPOI.HPSF;
using NPOI.POIFS.FileSystem;
其中與DocummentSummaryInformation和SummaryInformation密切相關的是HPSF名稱空間。
首先建立Workbook
HSSFWorkbookhssfworkbook =newHSSFWorkbook();
然後建立DocumentSummaryInformation
DocumentSummaryInformationdsi = PropertySetFactory.CreateDocumentSummaryInformation();
dsi.Company ="NPOI Team";
再建立SummaryInformation
SummaryInformationsi = PropertySetFactory.CreateSummaryInformation();
si.Subject ="NPOI SDK Example";
因為是範例,這裡僅各設定了一個屬性,其他都沒有設定。
現在我們把建立好的物件賦給Workbook,這樣才能保證這些資訊被寫入檔案。
hssfworkbook.DocumentSummaryInformation= dsi;
hssfworkbook.SummaryInformation= si;
最後和2.1.1節一樣,我們把Workbook通過FileStream寫入檔案。
相關範例請見中的CreatePOIFSFileWithProperties
作者:Tony Qu
用過Excel的人都知道,單元格是Excel最有意義的東西,我們做任何操作恐怕都要和單元格打交道。在Excel中我們要新增一個單元格只需要點選任何一個單元格,然後輸入內容就是了,但是Excel底層其實沒有這麼簡單,不同的單元格是有不同的型別的,比如說數值單元格是用NumberRecord表示,文字單元格是用LabelSSTRecord表示,空單元格是用BlankRecord表示。這也就意味著,在設定單元格時,你必須告訴NPOI你需要建立哪種型別的單元格。
要建立單元格首先要建立單元格所在的行,比如,下面的程式碼建立了第0行:
HSSFSheetsheet1 = hssfworkbook.CreateSheet("Sheet1");
HSSFRowrow1=sheet1.CreateRow(0);
行建好了,就可以建單元格了,比如建立A1位置的單元格:
row1.CreateCell(0).SetCellValue(1);
這裡要說明一下,SetCellValue有好幾種過載,你可以設定單元格為bool、double、DateTime、string和HSSFRichTextString型別。其中對於string型別的過載呼叫的就是HSSFRichTextString型別的過載,所以是一樣的,HSSFRichTextString可用於有字型或者Unicode的文字。
如果你覺得每一行要宣告一個HSSFRow很麻煩,可以用下面的方式:
sheet1.CreateRow(0).CreateCell(0).SetCellValue("This is a Sample");
這麼用有個前提,那就是第0行還沒建立過,否則得這麼用:
sheet1.GetRow(0).CreateCell(0).SetCellValue("This is a Sample");
注意:這裡的行在Excel裡是從1開始的,但是NPOI內部是從0開始的;列在Excel裡面是用字母表示的,而NPOI中也是用從0開始的數字表示的,所以要注意轉換。
如果你要獲得某一個已經建立的單元格物件,可以用下面的程式碼:
sheet1.GetRow(row_index).GetCell(column_index);
本節僅講解最基本的單元格建立,有關單元格格式設定、樣式等高階話題請見:2.2節單元格相關操作。
相關範例請見中的SetCellValuesInXls專案。
作者:Tony Qu
很多人不怎麼用Excel中的批註,所以我特地截了張圖,讓大家知道本節我們要建立的到底是什麼東西。
在過去,我們恐怕沒有辦法實現這一功能,因為無論是cvs法、html法、oledb法都沒有提供這樣的介面,當然Office PIA法可以做到,但是效能實在太差,而且穩定性不好,經常莫名其妙crash(這是某某兄弟給我的反饋,我引用了下,呵呵)。在以後的教程中,你將看到更多在過去無法通過傳統方法實現的東西,好戲才剛剛開始。
批註主要有三個屬性需要設定,一個是批註的位置和大小、一個是批註的文字、還有一個是批註的作者。
批註的位置和大小,在Excel中是與單元格密切相關的,NPOI中通過HSSFClientAnchor的例項來表示,它的建構函式比較複雜,有8個引數,它們分別是
引數 |
說明 |
dx1 |
第1個單元格中x軸的偏移量 |
dy1 |
第1個單元格中y軸的偏移量 |
dx2 |
第2個單元格中x軸的偏移量 |
dy2 |
第2個單元格中y軸的偏移量 |
col1 |
第1個單元格的列號 |
row1 |
第1個單元格的行號 |
col2 |
第2個單元格的列號 |
row2 |
第2個單元格的行號 |
例如,如果我們打算讓註釋顯示在B3和E5之間,就應該這麼寫:
HSSFPatriarchpatr = sheet.CreateDrawingPatriarch();
HSSFCommentcomment1 = patr.CreateComment(new HSSFClientAnchor(0, 0, 0, 0, 1, 2 , 4, 4));
下面我們設定這個批註的內容和作者,這個比較簡單:
comment1.String=newHSSFRichTextString("Hello World");
comment1.Author="NPOI Team";
最後一步就是把批註賦給某個單元格:
HSSFCell cell= sheet.CreateRow(1).CreateCell(1);
cell.CellComment= comment1;
對於批註,你有兩種選擇,一種是隱藏(預設),一種是顯示(即表單一開啟就顯示該批註),可以通過comment1.Visible屬性來控制。
看了上面這張圖大家就應該明白了,這裡有2個批註,下面那個是顯示的,上面那個是隱藏的。
相關範例請見中的SetCellCommentInXls。
作者:Tony Qu
很多人並不知道Excel的頁首和頁尾功能,因為在介面上是顯示不了頁首和頁尾的,必須在列印頁面中才能看到,這也直接導致了其設定介面也顯得更隱祕,你必須進入頁面設定 –>頁首和頁尾才能設定。以下是Office 2007中的設定介面。
當你按“自定義頁首”或“自定義頁尾”時,你會看到以下介面,Excel把頁首、頁尾分成了左中右三部分,這一點絕非單純體現在介面上,在底層的儲存中也是如此。如果你設定的是“左”的內容,底層的儲存字串就會在開頭加上&L,如果是“右”的內容則會加上&R,所以HeaderRecord中的字串看上去是這樣的:"&C&LFooter A&R”,這個字串的意思是僅設定了“左”的內容,內容是Footer A。
看了這些我想你應該對頁首和頁尾有所瞭解了,回過頭來說NPOI,NPOI中主要是靠HSSFSheet.Header和HSSFSheet.Footer來設定的,這兩個屬性分別是HSSFHeader和HSSFFooter型別的。
參考程式碼如下:
HSSFSheet s1= hssfworkbook.CreateSheet("Sheet1");
s1.CreateRow(0).CreateCell(1).SetCellValue(123);
//set headertext
s1.Header.Center="This is a test sheet";
//set footertext
s1.Footer.Left="Copyright NPOI Team";
s1.Footer.Right="created by Tony Qu(瞿傑)";
以上程式碼中我添加了頁首的Center內容,Footer的Left和Right內容,在列印預覽中看到的效果大概是這樣的: