1. 程式人生 > >C#項目中操作Excel文件——使用NPOI庫

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

獲取 單擊 包含 pop code 紅色 oar 行數 發布

轉載自:http://blog.csdn.net/dcrmg/article/details/52356236#

感謝-牧野-

實際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 print?
  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 print?
  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. namespace Excel_NPOI
  11. {
  12. class Program
  13. {
  14. static void Main(string[] args)
  15. {
  16. HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建xls工作簿
  17. workbook2003.CreateSheet("Sheet1"); //新建3個Sheet工作表
  18. workbook2003.CreateSheet("Sheet2");
  19. workbook2003.CreateSheet("Sheet3");
  20. FileStream file2003 = new FileStream(@"E:\Excel2003.xls", FileMode.Create);
  21. workbook2003.Write(file2003);
  22. file2003.Close(); //關閉文件流
  23. workbook2003.Close();
  24. XSSFWorkbook workbook2007 = new XSSFWorkbook(); //新建xlsx工作簿
  25. workbook2007.CreateSheet("Sheet1");
  26. workbook2007.CreateSheet("Sheet2");
  27. workbook2007.CreateSheet("Sheet3");
  28. FileStream file2007 = new FileStream(@"E:\Excel2007.xlsx", FileMode.Create);
  29. workbook2007.Write(file2007);
  30. file2007.Close();
  31. workbook2007.Close();
  32. }
  33. }
  34. }


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



寫入Excel文件數據



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

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


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


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


技術分享



讀取Excel文件數據



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


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



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

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


技術分享

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