iT邦幫忙

8

好用的Excel檔案讀取元件for .Net

通常,要存取Excel檔案,無非是把Excel檔案當作資料庫,透過Ole或ODBC存取,不然就是透過Excel的ActiveX元件,開啟檔案,逐一讀取。
這兩種方式,在執行效率上似乎都不是很好,尤其是遇到工作表、資料列很多的狀況,讓人感覺到幾乎跟當機沒兩樣....
L 在 CodePlex 上找到了一個for .net的開源 Excel 讀取元件,支援Excel 97-2003的xls格式,以及Excel 2007 xlsx檔案格式。
透過這個元件,存取Excel資料,顯得更加快速、簡單。
如果客戶要求,應用程式必須要可以讀取Excel檔、把Excel匯入資料庫...等等疑難雜症,程式設計人員存取Excel檔案的方式,不外乎把Excel檔案當作資料庫,透過Ole或ODBC存取,不然就是透過Excel的ActiveX元件,開啟檔案,逐一讀取,執行效率上似乎都不是很好。
CodePlex 上的 ExcelDataReader 元件,支援Excel 97-2003的xls格式,以及Excel 2007 xlsx檔案格式。透過這個元件,存取Excel資料,顯得更加快速、簡單。

以下是一段C# 寫的 Console application:

using System;
using System.Data;
using Excel;
using ICSharpCode;
using Excel.Core;
using ICSharpCode.SharpZipLib;
using System.IO;

namespace ExcelReader
{
  class Program
  {
    public static void Main(string[] args)
    {
      Console.WriteLine("Welcome to Excel Reader testing program!");
      Console.Write("Please enter a full path of an Excel file:");
      string strPath = Console.ReadLine();
	
      if(String.IsNullOrEmpty(strPath))
        Console.WriteLine("Invalid file path!");
      else{
	if(File.Exists(strPath){
          try{
            // Excel 97-2003檔案格式-->CreateBinaryReader;Excel 2007檔案格式-->CreateOpenXmlReader
            IExcelDataReader _reader = ExcelReaderFactory.CreateBinaryReader(File.Open(strPath, FileMode.Open,FileAccess.Read));
            /* 若設定IsFirstRowAsColumnNames為true,倒入資料時會由第二列開始倒入,第一列的資料將被忽略
              * 第一列的內容,會被當做每個欄位的名稱,透過SharDevelop執行,會有很奇怪的問題....請愛用Visual Studio...Orz。
              * 這個Component處理中文好像有不少問題......
            * 如果要將Excel資料,倒入DataSet,IsFirstRowAsColumnNames屬性必須在執行 AsDataSet 前設定完成*/
            _reader.IsFirstRowAsColumnNames = true;
						
           // 將Excel工作表,依序倒入Dataset,每個工作表生成一個datatable;空白的工作表,將被忽略
            DataSet _dataset = _reader.AsDataSet();
            foreach(DataTable _table in _dataset.Tables){
              for(int i=0;i<_table.Columns.Count;i++)
                Console.Write(_table.Columns[i].ColumnName.PadRight(_table.Columns[i].ColumnName.Length+2,Convert.ToChar(" ")));
              Console.WriteLine();
              foreach(DataRow _row in _table.Rows){
                for(int i=0;i<_table.Columns.Count;i++)
                  Console.Write(_row[i].ToString().Trim().PadRight(_table.Columns[i].ColumnName.Length+2,Convert.ToChar(" ")));
      
                Console.WriteLine();
	      }
              Console.WriteLine("\n-------------------------------------------");
              // 這兩行純粹用來測試IsFirstRowAsColumnNames屬性的差異
	       Console.WriteLine("Total Columns: "+_table.Columns.Count.ToString());
              Console.WriteLine("Total Rows: " + _table.Rows.Count.ToString());
              }
              _reader.Close();
            }
            catch(Exception exp){
              Console.WriteLine("An error occurs: " + exp.Message);}
          }else
            Console.WriteLine("Excel file: "+strPath+" not exists!");
        }
        Console.Write("Press any key to continue . . . ");
        Console.ReadKey(true);
    }
  }
}

0
jamesjan
iT邦高手 1 級 ‧ 2010-08-19 09:21:54

個人平常習慣透過 Excel 的 Range 物件來存取 Excel Data
透過.CopyFromRecordset 可以很快的把資料庫的資料 Dump 到 Excel worksheet 中
同樣的透過 Range 也是可以很快的將資料 Export 到 Recordset or text file
不過前提是 Excel 物件已經載入記憶體中...XD

透過 Excel.Application 在開啟 Excel 時因為需要 Initialize Excel 物件,所以這一段會耗掉蠻多時間的,這個元件透過 filestream 將 Excel 讀入,就省掉呼叫 Excel 物件的麻煩,並利用 dataset 的觀念來處理 Excel data 就不用去記那麼多 Excel 物件模型了

^^b

這個組件,是透過解析二進位檔案的模式處理excel檔案,比起取用OLE或者資料庫的方式,要來的節省資源與快速,如果經常需要把由Excel做資料的匯出、匯入,這倒是個不錯的選擇。

0
Ken(Bigcandy)
iT邦大師 1 級 ‧ 2010-08-19 13:49:59

我的環境,用戶也都習慣用EXCEL

怪怪....好像有了ERP,大家還是愛用Excel....
Orz

0
plums
iT邦高手 1 級 ‧ 2010-08-20 00:44:09

說到excel,我曾在日商待過,日本人把excel運用的非常透徹,不管他們的erp多高檔,還是習慣導出成excel來分析...Orz

我們家的財會也很強....什麼鬼報表、計算式都難不倒她...

我要留言

立即登入留言