由于使用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行判断列的数据类型,若是有字符型数据,那么就强制混合数据转换为文本。这里就明白为何要保证第一行为字符型的缘由了。能将列的数据类型强制设为字符型,那么列中出现什么类型的数据都不怕了。须要作的工做就是,在获取完数据后,将字段名从新设置,并删除第一条记录便可。代码以下: