C#項目中操作Excel文件——使用NPOI庫


實際C#項目中經常會涉及到需要對本地Excel文件進行操作,特別是一些包含數據記錄、分析、匯總功能模塊的項目。常用的操作Excel文件的方法主要有三個:

 

1. OleDb:

這種方式是把整個Excel文件當做一個數據源來進行數據的讀取操作。

優點:實現方式簡單,讀取速度快;

缺點:讀取Excel數據的過程不太靈活,對內存的占用比較高,當數據量變的很大時,容易由於內存空間不足導致內存溢出異常。(不過貌似對於今天電腦的硬件配置來說,內存問題不大)

 

2. Com組件

這種方式是通過Com組件 Microsoft.Office.Interop.Excel.dll實現Excel文件的操作。

優點:讀取Excel數據非常靈活,可以實現Excel具有的各種數據處理功能;

缺點:對數據的訪問時基於單元格方式實現的,所以讀寫數據較慢,特別是當數據量較大時,訪問效率問題更為突出。另一點是要求本機安裝了Microsoft Office組件。

 

3. NPOI

這種方式是通過NPOI庫實現Excel文件操作,可以在沒有安裝微軟Office的情況下使用。

優點:讀取Excel數據速度較快,操作方式靈活;

缺點:試了再說!

 

NPOI支持的文件格式處理xls、xlsx外,還包括doc、ppt、vsd等,功能強大,人稱Excel一哥。本文就准備單獨談一談NPOI對Excel的基本操作。

 

NPOI是什么?

 

NPOI的log圖標如下:

NPOI中N指代的是.Net,POI是一個完全開源的Java寫成的庫,能夠在沒有安裝微軟Office或者相應環境的情況下讀寫Excel、Word等微軟OLE2組件文檔,幾乎支持所有的Office97~Office2007的文件格式。所以NPOI就是POI項目的.Net版本。目前NPOI的最新版本是今年5月份發布的V2.2.1,包含了.Net Framework2和.Net Framework4兩個版本。

 

各個版本.Net Framework對應信息如下:

 

 

可以在C盤——C:\Windows\Microsoft.NET\Framework 下查看本機已經安裝的.Net Framework版本,在我的機器上安裝了以下版本:

 

 

 

NPOI庫下載、解壓

 

 

NPOI官網下載地址:點擊打開鏈接,打開之后,點擊紅色框里的“NPOI 2.2.1 package”即可下載:

 

 

下載完成的壓縮包大小只有3.5MB,解壓后可以看到主要文件其實就是5個Dll文件(.Net 2.0和.Net 4.0):

 

 

使用的時候只要在自己的C#項目中添加這幾個動態庫文件的引用就可以了。

 

在C#工程中添加NPOI動態庫引用

 

新建Visual Studio C# 控制台應用程序(或Windows窗體應用程序、WPF應用程序等均可),在解決方案管理器里項目下的“引用”上右擊“添加引用”:

 

 

在彈出的“引用管理器”對話框中單擊“瀏覽(B)”,選擇NPOI所在的文件夾,根據機器上.Net Framework版本,選擇Net20或Net40下的動態庫。

 

 

添加完成之后展開項目下的“引用”項,可以看到剛才所添加的動態庫。

經過簡單的“添加引用”之后就可以在自己的代碼中使用NPOI提供的接口實現各種Excel操作了。

 

 

Excel工作簿、工作表、xls、xlsx概念

 

在用NPOI編碼之前,簡單明確一下Excel中工作簿、工作表、xls、xlsx的概念,行、列、單元格等很明了的概念就不啰嗦了。

 

1. 每一個Excel文件都可以看做是一個工作簿,當打開一個Excel文件時,就等於打開了一個Excel工作簿。

 

2. 當打開了excel工作簿后在窗口底部看到的“Sheet”標簽標示的是工作表,有幾個標簽就表示有幾個工作表。

    簡單做一個類比,一個Excel文件即一個工作簿可以看做一本書,一個工作表即一個Sheet頁面是書內的一頁,可以     有很多頁。Excel2003最多可以添加255(有強迫症的程序猿最愛的數字之一)個,Excel2007隨意加。

 

3. xls是Office 2003以及之前版本Excel的擴展名,xlsx是Office 2007及之后版本Excel所用的擴展名。xlsx用新的基於     XML的壓縮文件格式取代了之前的默認文件格式,在傳統的文件名后面添加了字面x(即.docx取代.doc、.xlsx取         代.xls,等等),使其占用的空間更小。xlsx向下兼容xls。

 

 

新建一個Excel工作表

 

 

除添加Dll文件的引用外,還需要添加名稱空間:

 

 

[cpp]  view plain  copy
 
  1. using NPOI.SS.UserModel;  
  2. using NPOI.HSSF.UserModel;  
  3. using NPOI.XSSF.UserModel;  

 

 

HSSF使用於2007之前的xls版本,XSSF適用於2007及其之后的xlsx版本。

以下程序新建一個Excel 2003 xls和一個2007 xlsx文件,跟用Office建立的標准Excel格式一樣,每一個Excel文件初始包含了3個工作表。

 

 

[csharp]  view plain  copy
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using NPOI.SS.UserModel;  
  7. using NPOI.HSSF.UserModel;  
  8. using NPOI.XSSF.UserModel;  
  9. using System.IO;  
  10.   
  11. namespace Excel_NPOI  
  12. {  
  13.     class Program  
  14.     {  
  15.         static void Main(string[] args)  
  16.         {  
  17.             HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建xls工作簿  
  18.             workbook2003.CreateSheet("Sheet1");  //新建3個Sheet工作表  
  19.             workbook2003.CreateSheet("Sheet2");  
  20.             workbook2003.CreateSheet("Sheet3");  
  21.             FileStream file2003 = new FileStream(@"E:\Excel2003.xls", FileMode.Create);  
  22.             workbook2003.Write(file2003);  
  23.             file2003.Close();  //關閉文件流  
  24.             workbook2003.Close();  
  25.   
  26.             XSSFWorkbook workbook2007 = new XSSFWorkbook();  //新建xlsx工作簿  
  27.             workbook2007.CreateSheet("Sheet1");  
  28.             workbook2007.CreateSheet("Sheet2");  
  29.             workbook2007.CreateSheet("Sheet3");  
  30.             FileStream file2007 = new FileStream(@"E:\Excel2007.xlsx", FileMode.Create);  
  31.             workbook2007.Write(file2007);  
  32.             file2007.Close();  
  33.             workbook2007.Close();  
  34.         }  
  35.     }  
  36. }  

 

 

運行之后會在E盤根目錄下生成Excel2003.xls和Excel2007.xlsx兩個文件。



寫入Excel文件數據

 

 

以xls文件為例,介紹把數據寫入Excel文件的方法。

寫數據要遵循一定的順序,可以概括為:讀取(或新建一個工作簿)->獲取工作表->對工作表添加行->對每一行添加單元格->對單元格賦值;

 

 

[csharp]  view plain  copy
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using NPOI.SS.UserModel;  
  7. using NPOI.HSSF.UserModel;  
  8. using NPOI.XSSF.UserModel;  
  9. using System.IO;  
  10.   
  11. namespace Excel_NPOI  
  12. {  
  13.     class Program  
  14.     {  
  15.         static void Main(string[] args)  
  16.         {  
  17.             HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建工作簿  
  18.             workbook2003.CreateSheet("Sheet1");  //新建1個Sheet工作表              
  19.             HSSFSheet SheetOne = (HSSFSheet)workbook2003.GetSheet("Sheet1"); //獲取名稱為Sheet1的工作表  
  20.             //對工作表先添加行,下標從0開始  
  21.             for (int i = 0; i < 10; i++)  
  22.             {  
  23.                 SheetOne.CreateRow(i);   //創建10行  
  24.             }  
  25.             //對每一行創建10個單元格  
  26.             HSSFRow SheetRow = (HSSFRow)SheetOne.GetRow(0);  //獲取Sheet1工作表的首行  
  27.             HSSFCell[] SheetCell = new HSSFCell[10];  
  28.             for (int i = 0; i < 10; i++)  
  29.             {  
  30.                 SheetCell[i] = (HSSFCell)SheetRow.CreateCell(i);  //為第一行創建10個單元格  
  31.             }  
  32.             //創建之后就可以賦值了  
  33.             SheetCell[0].SetCellValue(true); //賦值為bool型           
  34.             SheetCell[1].SetCellValue(0.000001); //賦值為浮點型  
  35.             SheetCell[2].SetCellValue("Excel2003"); //賦值為字符串  
  36.             SheetCell[3].SetCellValue("123456789987654321");//賦值為長字符串  
  37.             for (int i = 4; i < 10; i++)  
  38.             {  
  39.                 SheetCell[i].SetCellValue(i);    //循環賦值為整形  
  40.             }  
  41.             FileStream file2003 = new FileStream(@"E:\Excel2003.xls", FileMode.Create);  
  42.             workbook2003.Write(file2003);  
  43.             file2003.Close();  
  44.             workbook2003.Close();              
  45.         }  
  46.     }  
  47. }  

 

 

運行之后在生成的Exce2003.xls中的內容為:

 

 


 

 

讀取Excel文件數據

 

 

HSSFWorkbook類和XSSFWorkbook類都繼承自IWorkbook類,所以在不知道所要讀取的Excel文件時xls還是xlsx時,可以使用IWorkbook來聲明一個通用的工作簿變量,隨后根據傳入的文件名判斷是xls還是xlsx。

 

 

[csharp]  view plain  copy
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using NPOI.SS.UserModel;  
  7. using NPOI.HSSF.UserModel;  
  8. using NPOI.XSSF.UserModel;  
  9. using System.IO;  
  10.   
  11. namespace Excel_NPOI  
  12. {  
  13.     class Program  
  14.     {  
  15.         static void Main(string[] args)  
  16.         {  
  17.             IWorkbook workbook = null;  //新建IWorkbook對象  
  18.             string fileName = "E:\\Excel2003.xls";  
  19.             FileStream fileStream = new FileStream(@"E:\Excel2003.xls", FileMode.Open, FileAccess.Read);  
  20.             if (fileName.IndexOf(".xlsx") > 0) // 2007版本  
  21.             {  
  22.                 workbook = new XSSFWorkbook(fileStream);  //xlsx數據讀入workbook  
  23.             }  
  24.             else if (fileName.IndexOf(".xls") > 0) // 2003版本  
  25.             {  
  26.                 workbook = new HSSFWorkbook(fileStream);  //xls數據讀入workbook  
  27.             }  
  28.             ISheet sheet = workbook.GetSheetAt(0);  //獲取第一個工作表  
  29.             IRow row;// = sheet.GetRow(0);            //新建當前工作表行數據  
  30.             for (int i = 0; i < sheet.LastRowNum; i++)  //對工作表每一行  
  31.             {  
  32.                 row = sheet.GetRow(i);   //row讀入第i行數據  
  33.                 if (row != null)  
  34.                 {  
  35.                     for (int j = 0; j < row.LastCellNum; j++)  //對工作表每一列  
  36.                     {  
  37.                         string cellValue = row.GetCell(j).ToString(); //獲取i行j列數據  
  38.                         Console.WriteLine(cellValue);  
  39.                     }  
  40.                 }  
  41.             }  
  42.             Console.ReadLine();  
  43.             fileStream.Close();  
  44.             workbook.Close();  
  45.         }  
  46.     }  
  47. }  


 

這段代碼實現讀取一個Excel文件內第一個工作表中的所有單元格內容,並打印輸出。

取在上段代碼中生成的xml文件作為輸入,運行結果為:

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM