1、通过设置注册表将读取猜测列数据类型的行数改成不限制
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
中的TypeGuessRows值来控制,默认是8。如果前8行都是数字,那么ADO.NET扫描不会有问题;如果前8行内的数据类型不一样,ADO.NET会采用一个通配的数据类型来匹配,通常为varchar或unicode varchar。但是如果前8行的数据都比较短小,使得ADO.NET选择匹配了varchar,那么就只能容下255个字符,而实际上却有可能是其它更大的类型。
为了避免这种情况产生的尴尬,需要在执行Excel读取之前将
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
中的TypeGuessRows值设为0,那样Jet就会扫描最多16384行。当然,如果文件太大的话,这里就有效率问题了,不过对于当前所要处理的情况就没有问题。写了个简单的设置函数。
可以调用程序实现
./// <summary>
02./// 修改注册表TypeGuessRows的值
03./// </summary>
04./// <param name="setDefault">为true表示设为默认值8,为flase表示设为0</param>
05./// <returns></returns>
06.
privateboolmodifyTypeGuessRows(boolsetDefault)
07.{
08.
inttoSetValue = 0;
09.
stringJetKeyRoot = "SOFTWARE\\Microsoft\\Jet\\4.0\\Engines\\Excel";
10.
stringACEKeyRoot = "SOFTWARE\\Microsoft\\Office\\12.0\\Access Connectivity Engine\\Engines\\Excel";
11.
12.
if(setDefault)
13. {
14. toSetValue = 8;
15. }
16.
17. try
18. {
19. RegistryKey JetRegKey = Registry.LocalMachine.OpenSubKey(JetKeyRoot, true);
20. JetRegKey.SetValue("TypeGuessRows", Convert.ToString(toSetValue, 16), RegistryValueKind.DWord);
21. JetRegKey.Close();
22.
23. RegistryKey ACERegKey = Registry.LocalMachine.OpenSubKey(ACEKeyRoot, true);
24. ACERegKey.SetValue("TypeGuessRows", Convert.ToString(toSetValue, 16), RegistryValueKind.DWord);
25. ACERegKey.Close();
26. }
27.
catch(Exception ex)
28. {
29.
MessageBox.Show("修改注册表失败:"+ ex.Message);
30.
returnfalse;
31. }
32.
returntrue;
33.}
2、设置行数据混合读取
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + fileName + ";" + "Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;'";
不读行头:HDR=Yes;
混合读取:IMEX=1