[轉載]C#讀取Excel幾種方法的體會

C#讀取Excel幾種方法的體會

轉載地址:http://developer.51cto.com/art/201302/380622.htm

(1) OleDb: 用這種方法讀取Excel速度還是非常的快的,但這種方式讀取數據的時候不太靈活,不過可以在 DataTable 中對數據進行一些刪減修改

這種方式將Excel作爲一個數據源,直接用Sql語句獲取數據了。所以讀取之前要知道此次要讀取的Sheet(當然也可以用序號,類似dt.Row[0][0]。這樣倒是不需要知道Sheet)
?

  1. if (fileType == ".xls")  
  2.    connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + fileName + ";" + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";  
  3. else 
  4.    connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + fileName + ";" + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";  
  5.    
  6. OleDbConnection conn new OleDbConnection(connStr);  
  7. DataTable dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { nullnullnull"TABLE" }); 

以上是讀取Excel的Sheet名,xls和xlsx的連接字符串也不一樣的,可以根據文件的後綴來區別。這裏需要注意的一點,Excel裏面只有一個Sheet,但通過這種方式讀取Sheet可能會大於一個。原因已經有人在別的網站說過了,偷一下懶O(∩_∩)O,下面文段來自【cdwolfling

【在使用過程中發現取出的Sheet和實際excel不一致, 會多出不少。目前總結後有兩種情況:

1. 取出的名稱中,包括了XL命名管理器中的名稱(參見XL2007的公式--命名管理器, 快捷鍵Crtl+F3);

2. 取出的名稱中,包括了FilterDatabase後綴的, 這是XL用來記錄Filter範圍的,  參見http://www.mrexcel.com/forum/showthread.php?t=27225

對於第一點比較簡單, 刪除已有命名管理器中的內容即可;第二點處理起來比較麻煩, Filter刪除後這些名稱依然保留着,簡單的做法是新增sheet然後將原sheet Copy進去】

---------------------------------

但實際情況並不能爲每個Excel做以上檢查【cdwolfling】也給出了過濾的方案,當時還是有點問題,本來補充了一點。總之先看代碼吧

  1. for (int i = 0; i < dtSheetName.Rows.Count; i++)  
  2.  
  3. {  
  4. ?  
  5. SheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];  
  6.    
  7. if (SheetName .Contains("$") && !SheetName .Replace("'""").EndsWith("$"))continue;//過濾無效SheetName完畢....  
  8.  
  9. da.SelectCommand = new OleDbCommand(String.Format(sql_F, tblName), conn);  
  10. DataSet dsItem = new DataSet();  
  11. da.Fill(dsItem, tblName);  
  12. ?  

因爲讀取出來無效SheetName一般情況最後一個字符都不會是$。如果SheetName有一些特殊符號,讀取出來的SheetName會自動加上單引號,比如在Excel中將SheetName編輯成:MySheet(1),此時讀取出來的SheetName就爲:'MySheet(1)$',所以判斷最後一個字符是不是$之前最好過濾一下單引號。

優點:讀取方式簡單、讀取速度快

缺點:除了讀取過程不太靈活之外,這種讀取方式還有個弊端就是,當Excel數據量很大時。會非常佔用內存,當內存不夠時會拋出內存溢出的異常。

不過一般情況下還是非常不錯的

讀取Excel完整代碼:

    1. /// <summary>  
    2.         /// 讀取Excel文件到DataSet中  
    3.         /// </summary>  
    4.         /// <param name="filePath">文件路徑</param>  
    5.         /// <returns></returns>  
    6.         public static DataSet ToDataTable(string filePath)  
    7.         {  
    8.             string connStr = "";             
    9.             string fileType = System.IO.Path.GetExtension(fileName);  
    10.             if (string.IsNullOrEmpty(fileType)) return null;  
    11.    
    12.             if (fileType == ".xls")  
    13.                 connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filePath+ ";" + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";  
    14.             else 
    15.                 connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + filePath+ ";" + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";  
    16.             string sql_F = "Select * FROM [{0}]";  
    17.    
    18.             OleDbConnection conn = null;  
    19.             OleDbDataAdapter da = null;  
    20.             DataTable dtSheetName= null;  
    21.    
    22.             DataSet ds = new DataSet();  
    23.             try 
    24.             {  
    25.                 // 初始化連接,並打開  
    26.                 conn = new OleDbConnection(connStr);  
    27.                 conn.Open();  
    28.    
    29.                 // 獲取數據源的表定義元數據                         
    30.                 string SheetName = "";  
    31.                 dtSheetName= conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { nullnullnull"TABLE" });  
    32.    
    33.                 // 初始化適配器  
    34.                 da = new OleDbDataAdapter();  
    35.                 for (int i = 0; i < dtSheetName.Rows.Count; i++)  
    36.                 {  
    37.                     SheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];  
    38.    
    39.                     if (SheetName .Contains("$") && !SheetName .Replace("'""").EndsWith("$"))  
    40.                     {  
    41.                         continue;  
    42.                     }  
    43.    
    44.                     da.SelectCommand = new OleDbCommand(String.Format(sql_F, SheetName ), conn);  
    45.                     DataSet dsItem = new DataSet();  
    46.                     da.Fill(dsItem, tblName);  
    47.    
    48.                     ds.Tables.Add(dsItem.Tables[0].Copy());  
    49.                 }  
    50.             }  
    51.             catch (Exception ex)  
    52.             {  
    53.             }  
    54.             finally 
    55.             {  
    56.                 // 關閉連接  
    57.                 if (conn.State == ConnectionState.Open)  
    58.                 {  
    59.                     conn.Close();  
    60.                     da.Dispose();  
    61.                     conn.Dispose();  
    62.                 }  
    63.             }  
    64.             return ds;  
    65.         } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章