您的当前位置:首页正文

Excel 读取数据不完整

2023-05-14 来源:爱go旅游网


C#采用ADO.NET读取Excel 03/07 数据不完整的问题

最开始还想是不是Excel里数据格式的问题,或者是数据表的字段类型跟长度的 问题,但一一排除后,还是不得其解。于是搜之,才发现原来是因为在使用ADO.NET读取Excel表格时,OLEDB(Excel 2000-2003一般是是Jet 4.0,Excel 2007是ACE 12.0,即Access Connectivity Engine,ACE也可以用来访问Excel 2000-2003)。会默认扫面Sheet中的前几行来决定数据类型,这个行数是由注册表中

Excel 2000-2003 : HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Jet\\4.0\\Engines\\Excel Excel 2007 :

HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Office\\12.0\\Access Connectivity Engine\\Engines\\Excel

Excel 2010 :

HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Office\\14.0\\Access Connectivity Engine\\Engines\\Excel

中的TypeGuessRows值来控制,默认是8。如果前8行都是数字,那么ADO.NET扫描不会有问题; 如果前8行内的数据类型不一样,ADO.NET会采用一个通配的数据类型来匹配,通常为varchar或unicode varchar。但是如果前8行的数据都比较短小,使得ADO.NET选择匹配了varchar,那么就只能容下255个字符,而实际上却有可能是其它更 大的类型。

为了避免这种情况产生的尴尬,需要在执行Excel读取之前将

TypeGuessRows值设为0,那样Jet就会扫描最多16384行。当然,如果文件太大的话,这里就有效率问题了,不过对于当前所要处理的情况就没有问题。写了个简单的设置函数。

private void modifyTypeGuessRows(bool setDefault) {

int toSetValue = 0; if (setDefault) toSetValue = 8; try {

string Root = \"SOFTWARE\\\\Microsoft\\\\Jet\\\\4.0\\\\Engines\\\\Excel\";

RegistryKey JetRegKey = Registry.LocalMachine.OpenSubKey(Root, true);

JetRegKey.SetValue(\"TypeGuessRows\", Convert.ToString(toSetValue, 16), RegistryValueKind.DWord); JetRegKey.Close();

Root = \"SOFTWARE\\\\Microsoft\\\\Office\\\\12.0\\\\Access Connectivity Engine\\\\Engines\\\\Excel\"; JetRegKey = Registry.LocalMachine.OpenSubKey(Root, true);

JetRegKey.SetValue(\"TypeGuessRows\", Convert.ToString(toSetValue, 16), RegistryValueKind.DWord); JetRegKey.Close();

Root = \"SOFTWARE\\\\Microsoft\\\\Office\\\\14.0\\\\Access Connectivity Engine\\\\Engines\\\\Excel\"; JetRegKey = Registry.LocalMachine.OpenSubKey(Root, true);

JetRegKey.SetValue(\"TypeGuessRows\", Convert.ToString(toSetValue, 16), RegistryValueKind.DWord); JetRegKey.Close(); } catch{} }

批处理bat注册表

@echo off

reg add HKLM\\SOFTWARE\\Microsoft\\Jet\\4.0\\Engines\\Excel /v TypeGuessRows /t REG_DWORD /d 0 /f @echo off

reg add \"HKLM\\SOFTWARE\\Microsoft\\Office\\12.0\\Access Connectivity Engine\\Engines\\Excel\" /v TypeGuessRows /t REG_DWORD /d 0 /f @echo off

reg add \"HKLM\\SOFTWARE\\Microsoft\\Office\\14.0\\Access Connectivity Engine\\Engines\\Excel\" /v TypeGuessRows /t REG_DWORD /d 0 /f

这样只要在读取Excel前设置TypeGuessRows为0,读取完成后将其改回默认值8,就可以解决这一问题了。 注意,网上说采用这个方案一般还要在Excel文件连接字符串中的Extended Properties加入IMEX=1,如 strACEConn = “Provider=Microsoft.ACE.OLEDB.12.0;Data Source=” + xlsFile + “;Extended Properties=\\”Excel 12.0;HDR=NO;IMEX=1\\”;”;

strJetConn = “Provider=Microsoft.Jet.OLEDB.4.0;Data Source=” + xlsFile + “;Extended Properties=\\”Excel 8.0;HDR=NO;IMEX=1\\”;”;

但是我采用这种方法后发现,依然有些文件会发生截断现象。于是将IMEX的值改为2,如

strACEConn = “Provider=Microsoft.ACE.OLEDB.12.0;Data Source=” + xlsFile + “;Extended Properties=\\”Excel 12.0;HDR=NO;IMEX=2\\”;”;

strJetConn = “Provider=Microsoft.Jet.OLEDB.4.0;Data Source=” + xlsFile + “;Extended Properties=\\”Excel 8.0;HDR=NO;IMEX=2\\”;”;

因篇幅问题不能全部显示,请点此查看更多更全内容