数据处理之以OLEDB方式读取Excel数据丢失的原因及解决方法

摘要:
最近,一些客户报告,他们在程序中读取Excel表时丢失了一些数据。作者使用了第一种方法来读取这里的数据,因此他们检查代码并搜索信息。最后,问题得到了解决,并在此处记录了损失的原因和解决方案。也就是说,ExcelISAM查找列的前几行,并将占大多数的类型作为其处理类型。

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_MACHINESOFTWAREMicrosoft”项,按下“Ctrl+F”键,输入“TypeGuessRows”选择“值”项,如下图所示。

数据处理之以OLEDB方式读取Excel数据丢失的原因及解决方法第1张

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

数据处理之以OLEDB方式读取Excel数据丢失的原因及解决方法第2张

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

数据处理之以OLEDB方式读取Excel数据丢失的原因及解决方法第3张

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数据丢失的原因及解决方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇小梵同学前进!Spring boot activeMQ 设置并行消费下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用 elementUI 树形控件Tree 编辑数据

操作新增/编辑功能时初始化数据: 应用属性 default-checked-keys 给Tree节点赋默认值(赋值数据为节点数组Arr)前,应先清空数组Arr,并且配合使用this.$refs.tree.setCheckedKeys([])。...

php 访问java接口数据

$header = []; $header[] = 'Accept:application/json'; $header[] = 'Content-Type:application/json;charset=utf-8'; $data = $_GPC['mobile']; $ch = curl_init();...

Mysql数据表字段设置了默认值,插入数据后默认字段的值却为null,不是默认值

我将mysql的数据表的某个字段设置了默认值为1,当向该表插入数据的时候该字段的值不是默认值,而是null。 我的错误原因: 对数据库的操作我使用了持久化工具mybatis,插入数据的时候插入的是整个实体,直接使用的是持久层的insert(实体对象)方法插入的数据 这样就会出现一个问题,当实体对象中某个属性值为空时,对应的数据库的字段就会插入null值,而...

SAS | 数据读入思路及代码

目录 1 读入思路 2 读入代码 1 读入思路 不管对数据是否熟悉,是否有数据字典,下图的读数思路都可以通用。 2 读入代码 *1.设置读入的记录数:全局变量,可设置为指定数字,全量读入设为max; option obs=1000; /* max */ *2.import语句读入; proc import datafile = 'C:U...

让pandas的输出结果中显示全部数据

1 import pandas as pd 2 pd.set_option('display.max_columns', 1000) 3 pd.set_option('display.width', 1000) 4 pd.set_option('display.max_colwidth', 1000)...

同事的Excel中的图片突然不能选择

今天上午,同事突然说自己用的Excel不能编辑了,发来一看原来是其中做的图片不能编辑,鼠标放上去后显示个圆圈选不中。 在“视图”中调出“控件工具箱”工具栏,上面有一个三角板与直尺样子的按钮叫“设计模式”按钮,用鼠标点击它,然后就能用鼠标选中那个以前无法选中的图片了。 如果是2007版的EXCEL,需要在“开发工具”功能区中找“插入”按钮,点一下就可以。...