【问题标题】:reading excel with oledb not displaying correct values用oledb读取excel不显示正确的值
【发布时间】:2018-04-25 02:49:06
【问题描述】:

这是我发布的老问题:

Reading one & Update some other Excel with c#

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

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

这是连接字符串:

string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + FilePath+ "';Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text \"";

有没有什么办法可以读取所有类型的数据?

【问题讨论】:

  • 请重新格式化您的代码
  • 你能解释一下“重新格式化”吗?
  • 在你的代码前放四个空格就可以了
  • 你的桌子怎么样? “并非所有值都显示”是什么意思?
  • 我不明白“在你的代码前放四个空格”?我的excel中的列将上升到“DX”。我观察到仅显示具有数字+文本值的第一行,但未显示类似文本出现在下方某处。它显示为空白。

标签: c# excel winforms oledb


【解决方案1】:

这出现了很多,而且很容易理解,因为文档有些缺乏

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

遗憾的是,修改注册表项并不总是很方便,将此设置保留在连接字符串上会更好,但它就是这样。默认值为 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]

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

总是返回隐藏的列。

这个驱动程序有几个讨厌的地方。首先,前导的空行或列被完全忽略。如果您期望特定行/列中的数据,这真的会搞砸。其次,Excel 错误地将 29/Feb/1900 视为有效日期,但 OLEDB 没有。您可以将 29/Feb/1900 粘贴到 Excel 电子表格中,但 OLEDB 会将其返回为 28/Feb/1900。我真的看不出它还能做什么。

驱动程序是一种非常方便且廉价的读取格式良好的 Excel 电子表格的方法,只要您了解这些限制并且可以围绕这些限制进行编码。

祝你好运。

【讨论】:

  • 哇,您的评论“这是 HDR=No 有用的地方。如果您有标题,请指定 HDR=No 并阅读它。”一定程度上解决了问题。我的查询也有 where 条件。我删除了 where 子句并设置 HDR=No。它成功了,但其他一些数值开始显示为日期。 :-(
  • 我需要保留 schema.ini 吗?我没有看到它有任何影响。
  • 其他显示为日期的值可能是因为您在单元格 1-8 中有日期,并且 OLEDB 已为该列分配了日期/时间数据类型。我从未使用过 schema.ini,也从未调查过它的用途,所以我无法发表评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多