使用 oledb 读取 excel 不显示正确的值

use*_*864 0 c# oledb excel winforms

这是我发布的老问题:

使用 C# 读取一个 Excel 并更新其他一些 Excel

按照建议,我创建了 schema.ini 文件。我的 Excel 文件有很多包含混合数据的列(其中许多不是固定的)。甚至单元格也包含数字和文本。我观察到,当我使用 OLEDB 读取 excel 并将其填充到数据表中时,并非所有值都会显示。

我不能假设所有列都放入 .ini 文件中。我的 Excel 中的列将上升为“DX”。我观察到,仅显示具有数字+文本值的第一行,但未显示出现在下方某处的类似文本。它显示为空白。

这是连接字符串:

string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;数据源='" + FilePath+ "';扩展属性=\"Excel 12.0;HDR=YES;IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text\"" ;

有什么解决方案可以读取所有类型的数据吗?

Cia*_*rán 5

这种情况经常出现,而且很好理解,因为文档有些缺乏

Microsoft.ACE.OLEDB.12.0 不能很好地处理混合数据类型的列。因此,驱动程序将始终读取每列中的前 n 个值,并根据在该列的前 n 个单元中找到的内容分配数据类型。n 由注册表项的设置确定。它会根据您是否有 64 位实现或 32 位实现而移动,但 64 位密钥位于...

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Excel\TypeGuessRows
Run Code Online (Sandbox Code Playgroud)

遗憾的是,修改注册表项并不总是很方便,最好将此设置保留在连接字符串上,但事实就是如此。默认值为 8 行。

如果驱动程序发现混合数据类型,那么 IMEX 的设置才会发挥作用。如果包含 IMEX=1,则混合数据类型的列将以文本形式返回。如果未指定,则任何与分配的数据类型不对应的值都将返回为 null。

这就是 HDR=No 有用的地方。如果您有标题,请指定 HDR=No 并读取它。当然,只要标题全部是文本,这将有助于确保该列以文本形式返回。然后,您可以在处理数据之前丢弃标头。如果列的前 n 个单元格中有大部分数字/日期时间数据类型,这将无济于事。

顺便说一句,驱动程序将读取所有类型的 Excel 文件,包括 .xls、.xlsm 和 .xlsx - 无需更改 Excel 12.0 的扩展属性即可执行此操作。这是一个相当大的优势。

较旧的 Microsoft.Jet.OLEDB.4.0 很好,因为您可以在连接字符串中指定 TypeGuessRows 和 ImportMixedTypes,但 Microsoft.ACE.OLEDB.12.0 完全忽略它们,因此您可以从连接字符串中删除它们,因为它们的存在会产生误导。旧版驱动程序只能读取 .xls 文件。

两个驱动程序将仅读取 255 列而不修改 SELECT 语句。要读取超过 255 列,请指定一个范围。例如

Select * From [Sheet1$IV:SP]
Run Code Online (Sandbox Code Playgroud)

将阅读第 256-510 列。如果您的工作表以 DX 结尾,则完全在 255 列限制之内。

始终返回隐藏列。

这位司机有一些令人讨厌的地方。首先,前导空行或空列将被完全忽略。如果您期望特定行/列中的数据,这真的会把事情搞砸。其次,Excel 错误地将 29/Feb/1900 视为有效日期,但 OLEDB 则不然。您可以将 29/Feb/1900 粘贴到 Excel 电子表格中,但 OLEDB 会将其返回为 28/Feb/1900。我看不出它还能做什么。

该驱动程序是一种非常方便且便宜的读取格式良好的 Excel 电子表格的方法,只要您了解这些限制并可以围绕它们编写代码即可。

祝你好运。