最近在处理C#读取excel文件时碰到了个BT问题,有部分数据读取失败了,翻看了不少资料,终于找到了问题的所在,所以在这里跟大伙分享下:

简要问题分析:

用C#读取excel文件数据时,出现数据丢失现象。

经查资料,发现产生这种问题的根源与Excel ISAM[3](Indexed Sequential Access Method,即索引顺序存取方法)驱动程序的限制有关,Excel ISAM 驱动程序通过检查前几行中实际值确定一个 Excel 列的类型,然后选择能够代表其样本中大部分值的数据类型[4]。也即Excel ISAM查找某列前几行(默认情况下是8行),把占多的类型作为其处理类型。例如如果数字占多,那么其它含有字母等文本的数据项就会置空;相反如果文本居多,纯数字的数据项就会被置空。

相关知识:

现具体分析HDR和IMEX所代表的含义。

HDR用来设置是否将Excel表中第一行作为字段名,“YES”代表是,“NO”代表不是即也为数据内容;

IMEX是用来告诉驱动程序使用Excel文件的模式,其值有0、1、2三种,分别代表导出、导入、混合模式。当我们设置IMEX=1时将强制混合数据转换为文本,但仅仅这种设置并不可靠,IMEX=1只确保在某列前8行数据至少有一个是文本项的时候才起作用,它只是把查找前8行数据中数据类型占优选择的行为作了略微的改变。例如某列前8行数据全为纯数字,那么它仍然以数字类型作为该列的数据类型,随后行里的含有文本的数据仍然变空。

网络上大部分的解决方法:

1、修改连接字符串:

如原来的连接字符串为: string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path + "; Extended Properties=Excel 8.0;";  

将其修改为:string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path + ";Extended Properties=Excel 8.0;IMEX=1;";

2、我还看到的一些改进的措施是IMEX=1与注册表值TypeGuessRows配合使用

TypeGuessRows 值决定了ISAM 驱动程序从前几条数据采样确定数据类型,默认为“8”。可以通过修改“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel”下的该注册表值来更改采样行数。但是这种改进还是没有根本上解决问题,即使我们把IMEX设为“1”, TypeGuessRows设得再大,例如1000,假设数据表有1001行,某列前1000行全为纯数字,该列的第1001行又是一个文本,ISAM驱动的这种机制还是让这列的数据变成空。

故此,以上两种解决方式都存在着一定的弊端。经过仔细的查阅资料,总结出如下方法:

解决办法:

从以上的分析中可以得知,当某列数据中含有混合类型时,在.NET中使用Microsoft.Jet.OLEDB.4.0来读取Excel文件造成数据丢失是不可避免的,要解决这个问题只能考虑采用其它数据读取方法。 在.NET中读取Excel文件的另外一种方法是回到使用传统COM组件,这种方法在很多技术文章或论文中都有涉及,本文不作赘述。需要指出的是,使用COM组件来读取Excel文件数据的效率较低,在作释放的时候有可能碰到不可预知的错误,特别开发Web应用的程序应该慎重使用。  (不推荐使用)不过在网上查到了另外一种利用读取CSV纯文本格式解决此问题的方法。   (1)在读取Excel的.xls类型的文本数据之前,先将其转换为.csv格式,在Excel中直接另存为这种格式就可以达到转换的目的。CSV文件又称为逗号分隔的文件,是一种纯文本文件,它以“,”分隔数据列,本文表1的数据表用CSV格式存储后用纯文本编辑器打开的表现形式如表3所示。   表3 采用CSV格式保存的表1数据   需要指出的是,CSV文件也可以用Ole DB或ODBC的方式读取,但是如果采用这些方式读取其数据又会回到丢失数据的老路上,ISAM机制同样会发挥作用。   (2)采用普通的读取文本文件的方法打开文件,读取第一行,用“,”作为分隔符获得各字段名,在DataTable中创建对应的各字段,字段的类型可以统一创建成“String”。   本文原文  (3)逐行读取数据行, 用“,”作为分隔符获得某行各列的数据并填入DataTable相应的字段中。   实现的简化代码如下:   String line;   String [] split = null;   DataTable table=new DataTable("Thylx");   DataRow row=null;   StreamReader sr=new StreamReader("c:/Thylx.csv",System.Text.Encoding.Default);   //创建与数据源对应的数据列   line = sr.ReadLine();   split=line.Split(',');   foreach(String colname in split){   table.Columns.Add(colname,System.Type.GetType("System.String")); }   //将数据填入数据表   int j=0;   while((line=sr.ReadLine())!=null){    j=0;    row = table.NewRow();    split=line.Split(',');    foreach(String colname in split){    row[j]=colname;    j++;}    table.Rows.Add(row);}    sr.Close();   //显示数据   dataGrid1.DataSource=table.DefaultView;   dataGrid1.DataBind(); 总结: 在应用程序的设计中,需要访问Excel数据的情况非常普遍,本文以在.NET中对访问含有混合类型数据的Excel表格拟采取的方法进行探讨。当然,如果不存在混合类型的数据使用Microsoft.Jet.OLEDB为较佳方案,也就是我上面提到的在网络中查到的大部分做法。本文只是针对NET方面的一些研究,对于其他开发语言,可参照类似的做法来解决excel读取时数据丢失的问题

C#读取excel文件数据丢失问题相关推荐

  1. php把excel变成数组,PHP excel读取excel文件转换为数组

    /* 备注:先去下载PHP EXCEL--http://download-codeplex.sec.s-msft.com/Download/Release?ProjectName=phpexcel&a ...

  2. python 读取excel文件 效率 时间 格式_python读取Excel文件中的时间数据

    在使用python读取Excel文件中的时间格式,碰到的时间格式转换问题: 读取这样的表格: 输出这样的数据结果: 然而这样的结果却不是我们想要的,我们需要的是这样的结果: 1.安装python官方库 ...

  3. C#读取Excel文件,准换为list

    经常会用到,废话不多说直接贴代码 //读取Excel文件 public static DataTable ReadExcelToTable(string path)//excel存放的路径 { try ...

  4. R语言读取excel文件实战(read.xlsx函数、read_excel函数、read.xlsx函数、Write函数)

    R语言读取excel文件实战(read.xlsx函数.read_excel函数.read.xlsx函数.Write函数) 目录 R语言读取excel文件实战(read.xlsx函数.read_exce ...

  5. matlab显示服务器出现意外,Matlab 读取excel文件提示服务器出现意外情况或无法读取问题解决...

    1.问题描述: 该错误通常发生在应用函数读取excel文件(后缀xls或xlsx)时. 应用xlsread函数读取提示服务器出现意外情况: 应用importdata读取时提示can't open fi ...

  6. form表单提交,Servlet接收并读取Excel文件

    首先是jsp页面: <body scroll=no style="overflow-y:hidden;" onselectstart="return false&q ...

  7. 两个关于.NET读取EXCEL文件的问题,记下来,很有用!

    今天有个同事问我个问题,他在用C#"Microsoft.Jet.OLEDB.4.0"读取EXCEL文件的时候,发现了一个问题,是这样的,他读出来的EXCEL数据在DATAGRID中 ...

  8. 读取EXCEL文件内容

    2019独角兽企业重金招聘Python工程师标准>>> package org.bigdata.framework.admin.web.util;import java.io.Fil ...

  9. 转:C#读取Excel文件 (2009年9月28日)

    原文:刘武|c#如何读取excel文件 使用OLEDB可以对excel文件进行读取,我们只要把该excel文件作为数据源即可. 一 在D盘创建excel文件test.xls: 二 将工作表Sheet1 ...

最新文章

  1. error LNK2019: 无法解析的外部符号,该符号在函数 _main 中被引用的解决方法
  2. JAVA学习笔记--数组初始化
  3. A Survey on Techniques in NLP--阅读笔记
  4. c++ 字符串转数字
  5. 算法:由0-5随机数设计0-8随机数
  6. python---(4) win10 环境下访问MYSQL 数据库
  7. [linux内存]伙伴系统学习笔记(一)——概念
  8. UITableView自定义Section
  9. 【TJOI2016】【bzoj4552】排序(二分答案+线段树01排序)
  10. 打印机质量测试软件,打印质量测试
  11. 【转载】Pandas速查手册中文版
  12. 怎么批量修改文件后缀名?
  13. 港科夜闻|香港科技大学(HKUST)及香港科大智能建造实验室(HKUST BIM Lab)荣获CIC建造数码化大奖组织类最高奖项...
  14. 正则表达式(第1部分) - 基本语法
  15. 机器视觉 · 工业光源
  16. 机器学习之Apriori算法
  17. NMS(Non-Maximum Suppression,非极大值抑制)解析
  18. 本地的registry图形化界面harbor安装与使用--02
  19. 英飞凌TC275芯片开发笔记
  20. MKS PI V1.0使用说明书

热门文章

  1. PHP脚本管理kvm,kvm管理脚本
  2. Mysql增强半同步模式_MySQL增强半同步参数rpl_semi_sync_master_wait_point值AFTER_SYNC和AFTER_COMMIT...
  3. 信号量的实现和应用实验报告_Java高级编程基础:原子信号量操作实现组线程执行管理...
  4. step在c语言中什么作用,C语言step-by-step(二)(数据类型)
  5. oracle 函数 disk,Oracle能够识别asm diskgroup,但却不能够访问disk
  6. Golang二维切片初始化
  7. Java 对象初始化的过程介绍
  8. const 修饰指针
  9. HH的项链 (求区间内有多少个不同的数字)
  10. java根据属性获取对象_java反射工具类--通过指定属性名,获取/设置对象属性值