【问题标题】:Problem with using OleDbDataAdapter to fetch data from a Excel sheet使用 OleDbDataAdapter 从 Excel 工作表中获取数据的问题
【发布时间】:2010-11-23 10:04:30
【问题描述】:

首先,我想说的是,我是在深水中,因为我只是对公司中其他人编写的代码进行一些更改,使用 OleDbDataAdapter 与 Excel“对话”,我'我对此并不熟悉。有一个错误,我无法理解。

我正在尝试使用 OleDbDataAdapter 读取大约 450 行的 excel 文件。

在代码中是这样完成的:

connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source='" + path + "';" + "Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1;\"");
connection.Open();
OleDbDataAdapter objAdapter = new OleDbDataAdapter(objCommand.CommandText, connection);
objAdapter.Fill(objDataSet, "Excel");

foreach (DataColumn dataColumn in objTable.Columns) {
  if (dataColumn.Ordinal > objDataSet.Tables[0].Columns.Count - 1) {
    objDataSet.Tables[0].Columns.Add();
  }
  objDataSet.Tables[0].Columns[dataColumn.Ordinal].ColumnName = dataColumn.ColumnName;
  objImport.Columns.Add(dataColumn.ColumnName);
}

foreach (DataRow dataRow in objDataSet.Tables[0].Rows) {
   ...
}

除了一件事之外,一切似乎都运行良好。第二列主要填充四位数字,如 6739、3920 等,但 fice 行具有字母数字值,如 8201NO 和 8205NO。这五个单元格被报告为具有空白内容而不是其字母数字内容。我已经在excel中签入,并且该列中的所有单元格都标记为文本。

顺便说一下,这是一个 xls 文件,而不是 xlsx。

有没有人知道为什么这些单元格在 DataRow 中显示为空白,但数字单元格显示正常?还有其他包含字母数字内容的列显示得很好。

【问题讨论】:

  • 感谢大家帮助我解决这个问题。你让我明白为什么会发生这种情况,所以我可以找到合适的解决方案。我仍然认为它的工作方式非常糟糕,但那是另一回事:)

标签: c# excel jet oledbconnection


【解决方案1】:

发生的情况是,excel 正在尝试根据该列中的前几个值将数据类型分配给电子表格列。我怀疑如果您查看该列中的属性,它会说它是一个数字列。

当您开始尝试使用 jet 查询该电子表格时,问题就出现了。当它认为它正在处理一个数字列并找到一个 varchar 值时,它会悄悄地什么也不返回。甚至连一条神秘的错误信息都没有。

作为一种可能的解决方法,您可以将其中一个字母数值移动到第一行数据,然后尝试解析。我怀疑你会开始获取字母数字行的值......

看看this article。它更详细地讨论了这个问题。它还谈到了一种可能的解决方法:

但是,根据 JET 文档,我们 可以通过覆盖注册表设置 连接字符串,如果我们设置 IMEX=1( 作为扩展的一部分 属性),JET 将设置所有 列类型为 UNICODE VARCHAR 或 ADVARWCHAR 不考虑 ‘ImportMixedTypes’键值。嘿嘿

【讨论】:

  • 我现在已经对此进行了测试,确实,如果我将第一行输入字母数字,那么它可以按预期工作。我的问题是我不能将此作为一般规则,因为客户会在他们自己的工作表中阅读。但是,我的解决方案是“作弊”,因此我更改连接字符串中的 HDR=No 以确保读取字母数字标题以使列字母数字,然后我剪切生成的 DataTable 的第一行。这很讨厌,但我在这里看不到任何其他选择。非常感谢您帮助我找到正确的方向。
【解决方案2】:

IMEX=1 表示“将混合数据读取为文本”。

不过,也有一些陷阱。 Jet 只会使用几行来确定数据是否混合,如果发生这种情况,这些行都是数字,你会得到这种行为。

详情请见connectionstrings.com

查看位于注册表REG_DWORD“TypeGuessRows”的[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel]。这是不让 Excel 仅使用前 8 行来猜测列数据类型的关键。将此值设置为 0 以扫描所有行。这可能会损害性能。另请注意,添加 IMEX=1 选项可能会导致 IMEX 功能仅在 8 行后设置。改用 IMEX=0 以确保强制注册表 TypeGuessRows=0(扫描所有行)工作。

【讨论】:

  • 我不知道 Jet 在 Excel 中是如何公开的,但是在 Access 中,您可以在运行时在当前的 Jet db 引擎实例中更改类似的内容,而无需更改注册表并重新启动 Access .
  • 感谢您提供此信息。它有效,但速度慢得惊人,所以我不得不使用“读取和处理标题”技巧。
【解决方案3】:

如果您能提供帮助,我建议您不要使用 OleDb 数据提供程序来访问 Excel。由于其他人指出的原因,我除了问题之外什么都没有。当您处理大型电子表格时,性能往往也很糟糕。

您可以试试这个开源解决方案: http://exceldatareader.codeplex.com/

【讨论】:

  • 我完全同意你的观点,马克。我认为这很可怕,但在这种情况下,我没有任何选择,因为我被分配修复现有程序中的这个错误,并且没有分配时间进行任何大型重构。如果以后需要从头开始执行此操作,我会记住您的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
相关资源
最近更新 更多