關於c#讀取Excel,目前為止,我一共發現三種方式
oledb,com組件、第三方類庫
三種方式各有優缺點。本文介紹使用oledb讀取excel的最佳做法。
首先說一下為什么不使用其他兩種方式:
com組件,使用起來比較麻煩。
第三方類庫,我只用過ExcelLibrary這個類庫,很不錯,只是,它以gpl授權發布,我可不想受它的感染。
所以我采用oledb的方式,方便,無限制。
當然oledb也有它的問題,默認情況下,他檢查表中數據行的前8行,來決定列的類型,
此時,就會面臨一個問題,如果一個表的前8行是數字,而到了第9行,是字母或是漢字什么的,無法轉換成數字格式,就沒法讀取數據了。
解決此問題的方法是,在連接字符串中設置HDR=no,不把第一行認為是列名,而直接把第一行認為是普通數據,
這樣,在讀取到dataTable里,oledb會自動生成列名,f1、f2、f3之類,這樣的話,我只需要保證列名不是純數字,然后根據第一行的數據,
改一下列名,再把第一行數據刪除,就得到我們想要的DataTable了。
以下代碼出自我的開源項目,都是平時的積累,還有一些其他的東西,以后會慢慢介紹給大家:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Text.RegularExpressions; namespace Lm.Common.Excel { public class ExcelReader { public DataTable Read(string file) { string ConnectionString = @"Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + file + ";" + "Extended Properties='Excel 8.0;HDR=no;IMEX=1';"; var con = new System.Data.OleDb.OleDbConnection(ConnectionString); try { con.Open(); var tables = con.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { }); con.Close(); if (tables.Rows.Count == 0) { throw new Exception("Excel必須包含一個表"); } var firstTableName = tables.Rows[0]["TABLE_NAME"].ToString(); System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand("select * from [" + firstTableName + "] ", con); System.Data.OleDb.OleDbDataAdapter apt = new System.Data.OleDb.OleDbDataAdapter(cmd); var dt = new System.Data.DataTable(); apt.Fill(dt); if (dt.Rows.Count < 2) { throw new Exception("表必須包含數據"); } var headRow = dt.Rows[0]; foreach (DataColumn c in dt.Columns) { var headValue = (headRow[c.ColumnName] == DBNull.Value || headRow[c.ColumnName] == null) ? "" : headRow[c.ColumnName].ToString().Trim(); if (headValue.Length == 0) { throw new Exception("必須輸入列標題"); } if (Regex.IsMatch(headValue, "^[\u4e00-\u9fa5,a-z,A-Z]{0,}$") == false) { throw new Exception("列標題只能輸入漢字或英文字母:" + headValue); } if (dt.Columns.Contains(headValue)) { throw new Exception("不能用重復的列標題:" + headValue); } c.ColumnName = headValue; } dt.Rows.RemoveAt(0); return dt; } catch (Exception ee) { throw ee; } finally { con.Close(); } } } }