程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> NPOI實踐 - .NET導入Excel文件的另一種選擇

NPOI實踐 - .NET導入Excel文件的另一種選擇

編輯:關於.NET

NPOI之所以強大,並不是因為它支持導出Excel,而是因為它支持導入Excel ,並能“理解”OLE2文檔結構,這也是其他一些Excel讀寫庫比較弱的方面。通 常,讀入並理解結構遠比導出來得復雜,因為導入你必須假設一切情況都是可能 的,而生成你只要保證滿足你自己需求就可以了,如果把導入需求和生成需求比 做兩個集合,那麼生成需求通常都是導入需求的子集,這一規律不僅體現在 Excel讀寫庫中,也體現在pdf讀寫庫中,目前市面上大部分的 pdf庫僅支持生成 ,不支持導入。

如果你不相信NPOI能夠很好的理解OLE2文檔格式,那就去下載POIFS Brower 。具體可以參考這篇文章的介紹:Office文件格式解惑。當然單單理解OLE2是不 夠的,因為Excel文件格式是BIFF,但BIFF是以OLE2為基礎的,做個很形象的比 喻就是:OLE2相當於磁盤的FAT格式,BIFF相當於文件和文件夾。NPOI負責理解 BIFF格式的代碼基本都在HSSF命名空間裡面。

好了,剛才廢話了一會兒,主要是給大家打打基礎,現在進入正題。

本文將以DataTable為容器讀入某xls的第一個工作表的數據(最近群裡面很 多人問這個問題)。

在開始之前,我們先來補些基礎知識。每一個xls都對應一個唯一的 HSSFWorkbook,每一個HSSFWorkbook會有若干個 HSSFSheet,而每一個 HSSFSheet包含若干HSSFRow(Excel 2003中不得超過65535行),每一個HSSFRow 又包含若干個HSSFCell(Excel 2003中不得超過256列)。

為了遍歷所有的單元格,我們就得獲得某一個HSSFSheet的所有HSSFRow,通 常可以用 HSSFSheet.GetRowEnumerator()。如果要獲得某一特定行,可以直接 用HSSFSheet.GetRow(rowIndex)。另外要遍歷我們就必須知道邊界,有一些屬性 我們是可以用的,比如HSSFSheet.FirstRowNum(工作表中第一個有數據行的行 號)、 HSSFSheet.LastRowNum(工作表中最後一個有數據行的行號)、 HSSFRow.FirstCellNum(一行中第一個有數據列的列號)、 HSSFRow.LastCellNum(一行中最後一個有數據列的列號)。

基礎知識基本上補得差不多了,現在開工!

首先我們要准備一個用於打開文件流的函數InitializeWorkbook,由於文件 讀完後就沒用了,所以這裡直接用using(養成好習慣,呵呵)。

HSSFWorkbook hssfworkbook;
void InitializeWorkbook(string path)
{
   //read the template via FileStream, it is suggested to  use FileAccess.Read to prevent file lock.
   //book1.xls is an Excel-2007-generated file, so some new  unknown BIFF records are added.
   using (FileStream file = new FileStream(path,  FileMode.Open, FileAccess.Read))
   {
     hssfworkbook = new HSSFWorkbook(file);
   }
}

接下來我們要開始寫最重要的函數ConvertToDataTable,即把HSSF的數據放 到一個DataTable中。

HSSFSheet sheet = hssfworkbook.GetSheetAt(0);
System.Collections.IEnumerator rows = sheet.GetRowEnumerator ();
while (rows.MoveNext())
{
   HSSFRow row = (HSSFRow)rows.Current;
   //TODO::Create DataTable row

   for (int i = 0; i < row.LastCellNum; i++)
   {
     HSSFCell cell = row.GetCell(i);
     //TODO::set cell value to the cell of DataTables
   }

上面的結構大家都應該能看懂吧,無非就是先遍歷行,再遍歷行中的每一列 。這裡引出了一個難點,由於Excel的單元格有好幾種類型,類型不同顯示的東 西就不同,具體的類型有 布爾型、數值型、文本型、公式型、空白、錯誤。

public enum HSSFCellType
{
   Unknown = -1,
   NUMERIC = 0,
   STRING = 1,
   FORMULA = 2,
   BLANK = 3,
   BOOLEAN = 4,
   ERROR = 5,
}

這裡的HSSFCellType描述了所有的類型,但細心的朋友可能已經發現了,這 裡沒有日期型,這是為什麼呢?這是因為Excel底層並沒有一定日期型,而是通 過數值型來替代,至於如何區分日期和數字,都是由文本顯示的樣式決定的,在 NPOI中則是由HSSFDataFormat來處理。為了能夠方便的獲得所需要的類型所對應 的文本,我們可以使用HSSFCell.ToString()來處理。

於是剛才的代碼則變成了這樣:

HSSFSheet sheet = hssfworkbook.GetSheetAt(0);
System.Collections.IEnumerator rows = sheet.GetRowEnumerator ();
DataTable dt = new DataTable();
for (int j = 0; j < 5; j++)
{
   dt.Columns.Add(Convert.ToChar(((int)'A')+j).ToString());
}
while (rows.MoveNext())
{
   HSSFRow row = (HSSFRow)rows.Current;
   DataRow dr = dt.NewRow();
   for (int i = 0; i < row.LastCellNum; i++)
   {
     HSSFCell cell = row.GetCell(i);
     if (cell == null)
     {
       dr[i] = null;
     }
     else
     {
       dr[i] = cell.ToString();
     }
   }
   dt.Rows.Add(dr);
}

是不是很簡單,呵呵!

當然,如果你要對某個特定的單元格類型做特殊處理,可以通過判 HSSFCell.CellType來解決,比如下面的代碼:

switch(cell.CellType)
     {
       case HSSFCellType.BLANK:
         dr[i] = "[null]";
         break;
       case HSSFCellType.BOOLEAN:
         dr[i] = cell.BooleanCellValue;
         break;
       case HSSFCellType.NUMERIC:
         dr[i] = cell.ToString();  //This is a trick  to get the correct value of the cell. NumericCellValue will  return a numeric value no matter the cell value is a date  or a number.
         break;
       case HSSFCellType.STRING:
         dr[i] = cell.StringCellValue;
         break;
       case HSSFCellType.ERROR:
         dr[i] = cell.ErrorCellValue;
         break;
       case HSSFCellType.FORMULA:
       default:
         dr[i] = "="+cell.CellFormula;
         break;
     }

這裡只是舉個簡單的例子。

原文地址: http://www.cnblogs.com//archive/2009/12/25/1631075.html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved