1.引言

在应用程序的设计中,经常需要读取Excel数据或将Excel数据导入转换到其他数据载体中,C#读取Excel的方式有两种,一种是通过OLEDB方式读取,另一种为通过COM组件方式读取。近段时间有客户反映,读取到程序中的Excel表,出现部分数据丢失的情况,笔者在此采用的是第一种方式读取(第二种读取比较慢,且不易控制),于是检查代码还有各种找资料,终于解决了该问题,在此记录导致丢失的原因及解决方法。

2.丢失原因

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

3.解决方式

(1)OLEDB连接字串

若Excel为Excel997-2003版本(后缀为“.xls”),读取的驱动为Jet,连接语句如下:

"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR={1};IMEX={2}'"

若Excel为Excel 2007及之后版本(后缀为“.xlsx”),读取的驱动为ACE,连接语句如下:

“Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR={1};IMEX={2}'”

其中:

当 IMEX=0 时为“汇出模式”,这个模式开启的 Excel 档案只能用来做“写入”用途;

当 IMEX=1 时为“汇入模式”,这个模式开启的 Excel 档案只能用来做“读取”用途;

当 IMEX=2 时为“链接模式”,这个模式开启的 Excel 档案可同时支援“读取”与“写入”用途;

当 HDR=Yes,这代表第一行是标题;

当 HDR=No,第一行作为数据内容。

(2)解决一:修改源数据

当我们设置IMEX=1时将强制混合数据转换为文本,但仅仅这种设置并不可靠,IMEX=1只确保在某列前8行数据至少有一个是文本项的时候才起作用,它只是把查找前8行数据中数据类型占优选择的行为作了略微的改变。例如某列前8行数据全为纯数字,那么它仍然以数字类型作为该列的数据类型,随后行里的含有文本的数据仍然变空。

(3)解决二:改动注册表

设置IMEX=1,修改注册表值TypeGuessRows(TypeGuessRows 值决定了ISAM 驱动程序从前几条数据采样确定数据类型,默认为“8”)为0,程序就会默认行数为最大。

对于修改注册表不熟悉的读者,具体步骤如下:

开始菜单,输入“Regedit”,打开注册表,找到“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\”项,按下“Ctrl+F”键,输入“TypeGuessRows”选择“值”项,如下图所示。

点击【查找下一个】按钮,查到找结果如下图所示,笔者Office版本为Office 2016 64bit。

右键该项,修改“TypeGuessRows”的值为“0”即可,如下图所示。

4.C#读取Excel代码

在此贴出C#读取Excel表到DataTable的方法代码:

public static DataTable GetExcelTableByOleDb(string excelPath, string tableName)
{
try
{
DataTable excelTable = new DataTable(); //数据表
DataSet ds = new DataSet(); //获取文件扩展名 //Excel的连接
OleDbConnection objConn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelPath + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1;'");
                if (objConn == null)
{
return null;
}
objConn.Open();
string strSql = "select * from [" + tableName + "]";//获取Excel指定Sheet表中的信息
OleDbDataAdapter myData = new OleDbDataAdapter(strSql, objConn);
myData.Fill(ds, tableName);//填充数据
objConn.Close(); //dtExcel即为excel文件中指定表中存储的信息
excelTable = ds.Tables[tableName];
return excelTable;
}
catch
{
return null;
}
}

5.总结

至此,不完美的解决了该问题,因为两种方法各有优缺点,受制于框架,这是无法避免的,后边有时间会写一篇通过开源库NPOI读取及创建Excel(不需要安装Office),以此彻底解决限制问题。如果该篇博文对你有帮助,希望点个关注支持下。

数据处理之以OLEDB方式读取Excel数据丢失的原因及解决方法的更多相关文章

  1. oledb方式读取excel文件

    进入博客园后台发现12年11月份写的草稿没发,时隔1年,把它拉出来晒晒太阳. 前言 第一次做Excel文件导入,采用了oledb,不足之处,还请各位大牛指出,谨以此文对导入Excel做个总结. 一般步 ...

  2. 使用OLEDB方式 读取excel和csv文件

    /// <summary> /// 使用OLEDB读取excel和csv文件 /// </summary> /// <param name="path" ...

  3. R读取excel文件乱码 read.xlsx() 解决方法

    1. 参考[R语言]R读取含中文excel文件,read.xlsx乱码问题  该文章总结得很好,可以直接跳到最后看博主的总结. 2. 如果依旧是乱码那么用read.xlsx2()去读取excel文件, ...

  4. C#使用OLEDB方式读取EXCEL,表的结构

    var tables = con.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { }); Ta ...

  5. truncate at 255 characters with xlsx files(OLEDB方式读取Excel丢失数据、字符串截断的原因和解决方法)

    The TypeGuessRows setting is supported by ACE. Note the version numbers in the key may change depend ...

  6. 通过oledb驱动读取excel、csv数据丢失解决方案

    1.问题出现 在开发应用程序的过程中,比较常用一功能就是通过oledb驱动读取excel.csv.text等文件:而最近有客户反映,在使用短信平台(下载地址:http://www.sms1086.co ...

  7. C#使用oledb方式将excel数据导入到datagridview后数据被截断为 255 个字符

    问题描述:在使用oledb方式将excel数据导入到datagridview中,在datagridview单元格中的数据没有显示全,似乎只截取了数据源中的一段 解决方案:1.关于该问题,微软官方答案: ...

  8. 【c#操作office】--OleDbDataAdapter 与OleDbDataReader方式读取excel,并转换为datatable

    OleDbDataAdapter方式: /// <summary> /// 读取excel的表格放到DataTable中 ---OleDbDataAdapter /// </summ ...

  9. C# 读取EXCEL文件的三种经典方法

    1.方法一:采用OleDB读取EXCEL文件: 把EXCEL文件当做一个数据源来进行数据的读取操作,实例如下: public DataSet ExcelToDS(string Path) { stri ...

随机推荐

  1. ASP.NET CORE 使用Consul实现服务治理与健康检查(1)——概念篇

    背景 笔者所在的公司正在进行微服务改造,这其中服务治理组件是必不可少的组件之一,在一番讨论之后,最终决定放弃 Zookeeper 而采用 Consul 作为服务治理框架基础组件.主要原因是 Consu ...

  2. C# dictionary to bytes and bytes convert to dictionary

    static byte[] GetBytesFromDic(Dictionary<string,string> dic) { if(dic==null || !dic.Any()) { r ...

  3. c++-zoo动物园

    面向对象抽象类写动物园 animal animal.h #pragma once #define _CRT_SECURE_NO_WARNINGS #include <iostream> u ...

  4. 松软科技Web课堂:JavaScript 正则表达式

    正则表达式是构成搜索模式的字符序列. 该搜索模式可用于文本搜索和文本替换操作. 什么是正则表达式? 正则表达式是构成搜索模式(search pattern)的字符序列. 当您搜索文本中的数据时,您可使 ...

  5. 渗透测试初学者的靶场实战 3--墨者学院SQL注入—宽字节盲注

    墨者SQL注入-MYSQL数据库实战环境 实践步骤 1. 决断注入点 输入单引号,提示错误信息: 输入and 1=1 返回页面正常: 输入 and 1=2 返回正常 输入-1,返回异常: 2. 带入s ...

  6. 关于EXIT和BADI增强的查找

    EXIT出口的查找: 方法一: 第一步:通过SE30,输入TCODE(例如ME21N),执行EXCUTE,前台创建一张采购订单.点击TIMES页签,查找EXIT开头的SAP程序.  第二步:这些fun ...

  7. sqlserver update join 多关联更新

    由于程序bug,导致之前很多数据入库后信息不全,好在有基础信息表,可以通过基础信息表更新缺失字段信息 1.通过 inner join语法实现多关联更新 update a set a.name = b. ...

  8. 持续集成(CI):Jmeter+Ant+Jenkins定时构建

    这里Jenkins的安装部署以及工程项目的整体配置不做赘述,其它博文已经说明,这里主要是赘述Ant的相关配置,build.xml文件配置以及项目中的部分配置 一.build.xml 在Ant的安装目录 ...

  9. JavaScript 日期格式

    有四种 JavaScript 日期输入格式: 类型 实例 ISO 日期 "2018-02-19" (国际标准) 短日期 "02/19/2018" 或者 &quo ...

  10. form表单input回车提交问题

    问题:文本框输入完成后点击回车页面刷新问题出在form上,当表单中只有一个文本框的时候获取焦点并点击回车之后会提交表单内容,就会发生刷新事件. 解决方法: 1.增加一个隐藏的输入框 <input ...