由於使用OLEDB鏈接Excel讀取數據時,須要肯定數據的類型。默認狀況使用鏈接字符串: ide
使用上面的鏈接字符串鏈接Excel時,可能會遇到數據類型不一致的問題。所謂數據類型不一致,是指同一列裏面數據類型可能出現多種,如浮點數、字符串、日期等;當出現此類狀況時,讀取出來的數據就爲空,甚至會報錯,如「非法的日期格式」等異常。出現這種問題,咱們你們都會想到把數據所有都按字符數據來讀取,可是按什麼數據類型來讀取不是咱們能控制的,是OLEDB控制的,至少暫時我尚未找到能控制輸出數據類型的方法。由於我當初也嘗試使用convert,cast函數對輸出的列進行類型轉換,但oledb鏈接Excel時,使用的SQL不支持這些函數。所以只能從其餘角度來解決該問題。我也在網上搜索了不少解決方法,最全面的解決方法是:http://www.douban.com/note/18510346/。下面列出了網上出現解決該問題方法的比較: 函數
解決方案 | 說明 | 缺點 |
---|---|---|
COM | 使用Excel COM接口訪問Excel | 非託管、不容易釋放資源、效率低下 |
鏈接字符串添加IMEX=1 | 構造的鏈接字符串,如:
1.
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelFile + ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1'";
|
只根據前8行數據判斷是否使用字符類型 |
IMEX=1與註冊表值TypeGuessRows配合使用 | TypeGuessRows 值決定了ISAM 驅動程序從前幾條數據採樣肯定數據類型,默認爲「8」。能夠經過修改「HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Jet/4.0/Engines/Excel」下的該註冊表值來更改採樣行數。可是這種改進仍是沒有根本上解決問題,即便咱們把IMEX設爲「1」, TypeGuessRows設得再大,例如1000,假設數據表有1001行,某列前1000行全爲純數字,該列的第1001行又是一個文本,ISAM驅動的這種機制仍是讓這列的數據變成空。 (摘至:http://www.douban.com/note/18510346/)。 | 修改註冊表不方便,並且沒法事先判讀sheet有多少行,所以仍是受行數限制。 |
將Excel先轉換成csv純文本格式 | (1)在讀取Excel的.xls類型的文本數據以前,先將其轉換爲.csv格式,在Excel中直接另存爲這種格式就能夠達到轉換的目的。CSV文件又稱爲逗號分隔的文件,是一種純文本文件,它以「,」分隔數據列。 spa 須要指出的是,CSV文件也能夠用Ole DB或ODBC的方式讀取,可是若是採用這些方式讀取其數據又會回到丟失數據的老路上,ISAM機制一樣會發揮做用。 .net (2)採用普通的讀取文本文件的方法打開文件,讀取第一行,用「,」做爲分隔符得到各字段名,在DataTable中建立對應的各字段,字段的類型能夠統一建立成「String」。 excel (3)逐行讀取數據行, 用「,」做爲分隔符得到某行各列的數據並填入DataTable相應的字段中。 orm 簡要代碼: blog
01.
String line;
02.
String [] split = null;
03.
DataTable table=new DataTable("auto");
04.
DataRow row=null;
05.
StreamReader sr=newStreamReader("c:/auto.csv",System.Text.Encoding.Default);
06.
//建立與數據源對應的數據列
07.
line = sr.ReadLine();
08.
split=line.Split(',');
09.
foreach(String colname in split){
10.
table.Columns.Add(colname,System.Type.GetType("System.String"));
11.
}
12.
//將數據填入數據表
13.
int j=0;
14.
while((line=sr.ReadLine())!=null){
15.
j=0;
16.
row = table.NewRow();
17.
split=line.Split(',');
18.
foreach(String colname in split){
19.
row[j]=colname;
20.
j++;
21.
}
22.
table.Rows.Add(row);
23.
}
24.
sr.Close();
25.
//顯示數據
26.
dataGrid1.DataSource=table.DefaultView;
27.
dataGrid1.DataBind();
|
須要事先將excel轉換成csv文件 |
這裏提供一個更加方便的辦法,不過前提是第一行必須是做爲字段名或者第一行的數據類型就爲字符型。這樣一說,你們就明白了。首先修改鏈接字符串爲: 接口
//2003(Microsoft.Jet.Oledb.4.0)
string strConn = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;'", excelFilePath); 資源
//2010(Microsoft.ACE.OLEDB.12.0)
string strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;'", excelFilePath); 字符串
這裏將HDR設爲NO,由於我就是將第一行作爲數據讀取,而IMEX=1就表示根據前8行判斷列的數據類型,若是有字符型數據,那麼就強制混合數據轉換爲文本。這裏就明白爲何要保證第一行爲字符型的緣由了。能將列的數據類型強制設爲字符型,那麼列中出現什麼類型的數據都不怕了。須要作的工做就是,在獲取完數據後,將字段名從新設置,並刪除第一條記錄便可。代碼以下: