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官網下載地址:點選開啟連結,(如不能下載,可以試試csdn下載上的這個連結: NPOI v2.2.1 ) 開啟之後,點選紅色框裡的“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檔案的引用外,還需要新增名稱空間:
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
HSSF使用於2007之前的xls版本,XSSF適用於2007及其之後的xlsx版本。
以下程式新建一個Excel 2003 xls和一個2007 xlsx檔案,跟用Office建立的標準Excel格式一樣,每一個Excel檔案初始包含了3個工作表。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.IO;
namespace Excel_NPOI
{
class Program
{
static void Main(string[] args)
{
HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建xls工作簿
workbook2003.CreateSheet("Sheet1"); //新建3個Sheet工作表
workbook2003.CreateSheet("Sheet2");
workbook2003.CreateSheet("Sheet3");
FileStream file2003 = new FileStream(@"E:\Excel2003.xls", FileMode.Create);
workbook2003.Write(file2003);
file2003.Close(); //關閉檔案流
workbook2003.Close();
XSSFWorkbook workbook2007 = new XSSFWorkbook(); //新建xlsx工作簿
workbook2007.CreateSheet("Sheet1");
workbook2007.CreateSheet("Sheet2");
workbook2007.CreateSheet("Sheet3");
FileStream file2007 = new FileStream(@"E:\Excel2007.xlsx", FileMode.Create);
workbook2007.Write(file2007);
file2007.Close();
workbook2007.Close();
}
}
}
執行之後會在E盤根目錄下生成Excel2003.xls和Excel2007.xlsx兩個檔案。
寫入Excel檔案資料
以xls檔案為例,介紹把資料寫入Excel檔案的方法。
寫資料要遵循一定的順序,可以概括為:讀取(或新建一個工作簿)->獲取工作表->對工作表新增行->對每一行新增單元格->對單元格賦值;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.IO;
namespace Excel_NPOI
{
class Program
{
static void Main(string[] args)
{
HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建工作簿
workbook2003.CreateSheet("Sheet1"); //新建1個Sheet工作表
HSSFSheet SheetOne = (HSSFSheet)workbook2003.GetSheet("Sheet1"); //獲取名稱為Sheet1的工作表
//對工作表先新增行,下標從0開始
for (int i = 0; i < 10; i++)
{
SheetOne.CreateRow(i); //建立10行
}
//對每一行建立10個單元格
HSSFRow SheetRow = (HSSFRow)SheetOne.GetRow(0); //獲取Sheet1工作表的首行
HSSFCell[] SheetCell = new HSSFCell[10];
for (int i = 0; i < 10; i++)
{
SheetCell[i] = (HSSFCell)SheetRow.CreateCell(i); //為第一行建立10個單元格
}
//建立之後就可以賦值了
SheetCell[0].SetCellValue(true); //賦值為bool型
SheetCell[1].SetCellValue(0.000001); //賦值為浮點型
SheetCell[2].SetCellValue("Excel2003"); //賦值為字串
SheetCell[3].SetCellValue("123456789987654321");//賦值為長字串
for (int i = 4; i < 10; i++)
{
SheetCell[i].SetCellValue(i); //迴圈賦值為整形
}
FileStream file2003 = new FileStream(@"E:\Excel2003.xls", FileMode.Create);
workbook2003.Write(file2003);
file2003.Close();
workbook2003.Close();
}
}
}
執行之後在生成的Exce2003.xls中的內容為:
讀取Excel檔案資料
HSSFWorkbook類和XSSFWorkbook類都繼承自IWorkbook類,所以在不知道所要讀取的Excel檔案時xls還是xlsx時,可以使用IWorkbook來宣告一個通用的工作簿變數,隨後根據傳入的檔名判斷是xls還是xlsx。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.IO;
namespace Excel_NPOI
{
class Program
{
static void Main(string[] args)
{
IWorkbook workbook = null; //新建IWorkbook物件
string fileName = "E:\\Excel2003.xls";
FileStream fileStream = new FileStream(@"E:\Excel2003.xls", FileMode.Open, FileAccess.Read);
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
{
workbook = new XSSFWorkbook(fileStream); //xlsx資料讀入workbook
}
else if (fileName.IndexOf(".xls") > 0) // 2003版本
{
workbook = new HSSFWorkbook(fileStream); //xls資料讀入workbook
}
ISheet sheet = workbook.GetSheetAt(0); //獲取第一個工作表
IRow row;// = sheet.GetRow(0); //新建當前工作表行資料
for (int i = 0; i < sheet.LastRowNum; i++) //對工作表每一行
{
row = sheet.GetRow(i); //row讀入第i行資料
if (row != null)
{
for (int j = 0; j < row.LastCellNum; j++) //對工作表每一列
{
string cellValue = row.GetCell(j).ToString(); //獲取i行j列資料
Console.WriteLine(cellValue);
}
}
}
Console.ReadLine();
fileStream.Close();
workbook.Close();
}
}
}
這段程式碼實現讀取一個Excel檔案內第一個工作表中的所有單元格內容,並列印輸出。
取在上段程式碼中生成的xml檔案作為輸入,執行結果為: