彻底解决Oledb连接Excel数据类型不统一的问题
2010-09-15 15:19
399 查看
在使用Microsoft.Jet.OLEDB.4.0连接Excel,进行读取数据,相对使用传统的COM来读取数据,效率是很高的。但相对传统COM操作Excel来说,及存在数据类型转换的问题。
因为使用OLEDB连接Excel读取数据时,需要确定数据的类型。默认情况使用连接字符串:
1.
string
connStr=
"Provider=Microsoft.Jet.OLEDB.4.0;DataSource="
+excelFile+
";ExtendedProperties='Excel8.0;'"
;
使用上面的连接字符串连接Excel时,可能会遇到数据类型不一致的问题。所谓数据类型不一致,是指同一列里面数据类型可能出现多种,如浮点数、字符串、日期等;当出现此类情况时,读取出来的数据就为空,甚至会报错,如“非法的日期格式”等异常。出现这种问题,我们大家都会想到把数据全部都按字符数据来读取,但是按什么数据类型来读取不是我们能控制的,是OLEDB控制的,至少暂时我还没有找到能控制输出数据类型的方法。因为我当初也尝试使用convert,cast函数对输出的列进行类型转换,但oledb连接Excel时,使用的SQL不支持这些函数。因此只能从其他角度来解决该问题。我也在网上搜索了很多解决方法,最全面的解决方法是:
解决方案 | 说明 | 缺点 |
---|---|---|
COM | 使用ExcelCOM接口访问Excel | 非托管、不容易释放资源、效率低下 |
连接字符串添加IMEX=1 | 构造的连接字符串,如:1. string strConn= "Provider=Microsoft.Jet.OLEDB.4.0;DataSource=" +excelFile+ ";ExtendedProperties='Excel8.0;HDR=YES;IMEX=1'" ; 其中HDR表示是否将Sheet页的第一行作为字段名,“YES”代表是,“NO”代表不是,当为YES时,将把SHEET页的第一行作为字段名,数据从第二行开始,而如果是NO时,字段名就是要SHEET的列名,如A,B,C等,数据就从第一行开始取;IMEX是用来告诉驱动程序,使用Excel文件的模式,其值有0、1、2三种,分别代表导出、导入、混合模式。当我们设置IMEX=1时将强制混合数据转换为文本,但仅仅这种设置并不可靠,IMEX=1只确保在某列前8行数据至少有一个是文本项的时候才起作用,它只是把查找前8行数据中数据类型占优选择的行为作了略微的改变。例如某列前8行数据全为纯数字,那么它仍然以数字类型作为该列的数据类型,随后行里的含有文本的数据仍然变空。(摘至:http://www.douban.com/note/18510346/)。 | 只根据前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文件又称为逗号分隔的文件,是一种纯文本文件,它以“,”分隔数据列。 需要指出的是,CSV文件也可以用OleDB或ODBC的方式读取,但是如果采用这些方式读取其数据又会回到丢失数据的老路上,ISAM机制同样会发挥作用。 (2)采用普通的读取文本文件的方法打开文件,读取第一行,用“,”作为分隔符获得各字段名,在DataTable中创建对应的各字段,字段的类型可以统一创建成“String”。 (3)逐行读取数据行,用“,”作为分隔符获得某行各列的数据并填入DataTable相应的字段中。 简要代码: 01. Stringline; 02. String[]split= null ; 03. DataTabletable= new DataTable( "auto" ); 04. DataRowrow= null ; 05. StreamReadersr= new StreamReader( "c:/auto.csv" ,System.Text.Encoding.Default); 06. //创建与数据源对应的数据列 07. line=sr.ReadLine(); 08. split=line.Split( ',' ); 09. foreach (Stringcolname 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 (Stringcolname 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(); (摘至:http://www.douban.com/note/18510346/)。 | 需要事先将excel转换成csv文件 |
1.
string
strConn=
"Provider=Microsoft.Jet.OLEDB.4.0;DataSource="
+excelFile+
";ExtendedProperties='Excel8.0;HDR=NO;IMEX=1'"
;
这里将HDR设为NO,因为我就是将第一行做为数据读取,而IMEX=1就表示根据前8行判断列的数据类型,如果有字符型数据,那么就强制混合数据转换为文本。这里就明白为什么要保证第一行为字符型的原因了。能将列的数据类型强制设为字符型,那么列中出现什么类型的数据都不怕了。需要做的工作就是,在获取完数据后,将字段名重新设置,并删除第一条记录即可。代码如下:
01.
DataTabledt=
new
DataTable();
02.
03.
using
(OleDbCommandcmd=
new
OleDbCommand()){
04.
cmd.Connection=conn;
05.
cmd.CommandType=CommandType.Text;
06.
cmd.CommandTimeout=6;
07.
cmd.CommandText=
string
.Format(
"select*from[{0}$]"
,sheetName);
08.
09.
OleDbDataAdapteradapter=
new
OleDbDataAdapter(cmd);
10.
adapter.Fill(dt);
11.
}
12.
13.
if
(dt.Rows.Count>0){
14.
DataRowdr=dt.Rows[0];
15.
16.
for
(
int
col=0;col<dt.Columns.Count;col++){
17.
dt.Columns[col].ColumnName=dr[col].ToString();
18.
}
19.
20.
dt.Rows[0].Delete();
21.
dt.AcceptChanges();
22.
}
相关文章推荐
- 彻底解决OLEDB连接Excel数据类型不统一的问题
- 彻底解决Oledb连接Excel数据类型不统一的问题
- 彻底解决Oledb连接Excel数据类型不统一的问题
- 解决Oledb连接Excel数据类型不统一的问题
- OLEDB方式操作规则EXCEL的字符串的完整写法(解决标题行和列数据类型不一致的问题)
- Ado方式导入excel混用数据类型引起数据缺失问题解决方法
- 彻底解决联想手机数据连接不能上网问题(无需恢复出厂设置) 本文来自移动叔叔论坛 ,详细出处请参考:http://bbs.ydss.cn/thread-201115-1-1.html
- 利用OleDb导入Excel数据丢失问题及解决方法
- 解决excel解析浮点类型数据精度问题
- C#导出EXCEL超大数据源码,解决内存溢出问题,使用OLEDB方式(NPOI做不到)
- 解决ADO读取Excel,数据丢失、数据错误、数据乱码问题
- poi 导出excel(BigDecimal数据类型)左上角有绿色小三角解决
- PL/SQL Developer导出大量数据到excel的快速方法,解决数据量大导出慢的问题
- kafka java中发送数据、连接失败问题解决
- Java IO流将数据输出到.csv文件中,excel打开时乱码问题的解决
- Visual Source Safe连接数据文件图解 解决密码缓存问题
- 关于使用DirectShow架构,传输YUV420数据的Filter与Video Renderer Filter连接问题的解决办法。
- 将GridView中的数据导出到Excel中下载并且解决乱码的问题
- 类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法 续集
- 解决cin因为输入错误的数据类型进入死循环的问题