一、 问题描述:
表格某一单元格内容过长,则上位机读取Excel表时,字符串将被截断,导致数据缺失,对后续数据处理造成错误。
二、 问题分析:
目前微软提供了两种Office Ole驱动来实现数据库连接,分别为ACE版本和Jet版本。由于Jet引擎只可以访问 Office 97-2003,故上位机代码中采用了调用Microsoft.ACE.OLEDB.12.0驱动的方式,利用Microsoft ACE引擎连接到工作簿,将Excel文件作为数据源来读写。
而OleDb读取文件的方式受Excel ISAM(Indexed Sequential Access Method,即索引顺序存取方法)驱动程序的限制。在读取过程中,Excel ISAM 驱动程序通过扫描sheet中前几行(默认为8行)的内容来确定一个 Excel列的最合适的数据类型,然后选择能够代表其样本中大部分值的数据类型,分配存储大小。该数据类型通常为varchar,其大小为255字符。而实际使用中,常常会出现该列前8行字符串在255个字符以内,8行以外的字符串却大于255个字符的情况,那么这个时候使用OleDb读取Excel就会将后面大于255的字符串截断。
三、改善措施与验证结果:
经翻查资料,得到的解决方案为,通过修改注册表值来更改采样行数。修改路径如下(Excel 2016):
计算机HKEY_LOCAL_MACHINESOFTWAREMicrosoftOffice16.0Access Connectivity EnginesExcel
TypeGuessRows取值范围为0-16。当TypeGuessRows = 0时会扫描整个页面再匹配合适的数据类型。但试验后发现,该方法只适用于Jet引擎,对于使用ACE引擎的上位机,该方法无效。
在不修改表格读取方式的情况下,一个可以实现字符串正常读取的措施是,把数据大于255的表格放到前8行。在前8行的判定中,数据已经超过255,则该列的数据类型会被设定得更大,就不会出现截断的情况。
由于该方法会增加额外的工作量,不宜作为永久措施。目前的最佳方案是修改文件读取方式,用NPOI方法读取Excel表格。该方法不受ISAM驱动程序限制,可以保证字符串的完整性,同时可以满足读取高版本Excel文件的需求。
经调试,可以确保该方法能够完整读取单元格长度远大于255的字符串。
四、总结:
在处理单一、长度较短的表格时,可以优先选择OleDb方式对表格进行读取;若每一单元格包含的数据类型较为复杂,则推荐在编写上位机时使用NPOI方法读取表格,保证数据处理的可靠性。