常用的操作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等,功能強大。
NPOI中N指代的是.Net,POI是一個完全開源的Java寫成的庫,能夠在沒有安裝微軟Office或者相應環境的情況下讀寫Excel、
Word等微軟OLE2元件文檔,幾乎支援所有的Office97~Office2007的檔案格式。是以NPOI就是POI項目的.Net版本。
目前NPOI的最新版本是今年5月份釋出的V2.2.1,包含了.Net Framework2和.Net Framework4兩個版本
4.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。
5.建立一個Excel工作表
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兩個檔案。
6.寫入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();
}
}
}
7.讀取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檔案内第一個工作表中的所有單元格内容,并列印輸出。