【问题标题】:Reading data from Excel file: one column is retrieving System.DBNull value instead of real value从 Excel 文件中读取数据:一列正在检索 System.DBNull 值而不是实际值
【发布时间】:2015-12-11 07:51:35
【问题描述】:

我正在构建一个读取 Excel 2013 文件 (*.xlsx) 的 Windows 窗体应用程序。 该文件包含结构类似表格的数据。 这里描述了我用来从这个文件中读取数据的方法:

How to read data from excel file using c# [duplicate]

此方法使用OleDbConnection 对象以及连接字符串,例如连接到数据库。 还使用OleDbCommand 对象提供查询以检索数据。 并且还使用OleDbDataReader 对象来读取检索到的数据。

问题是,当我读取此 Excel 文件的某些特定行时,OleDbDataReader 对象在某些列中检索正确的值,但在某一列中特别检索 @987654326 @value 当该列中确实有数据时!!!

示例:
- 我的 Excel 文件:

ClientId    ClientName    Total     InvoiceNumber
---------------------------------------------------
...
4           CLIENT_4      400.00    EV1234
5           CLIENT_5      500.00    EV56.78
6           CLIENT_6      600.00    EV9012
...

逐行调试我的应用程序,在“检查 1”窗口中添加一个表达式,当我到达“CLIENT_4”的第 4 行时:值正在正确检索:

对于列ClientId ==> 数据为4.0,类型为object{double}
对于列ClientName ==> 数据为CLIENT_4,类型为object{String}
对于列Total ==> 数据为400.00,类型为object{decimal}
对于列InvoiceNumber ==> 数据为EV1234,类型为object{double}

但是当我到达“CLIENT_5”的第 5 行时:InvoiceNumber 列值正在检索不正确

对于列ClientId ==> 数据为5.0,类型为object{double}
对于列ClientName ==> 数据为CLIENT_5,类型为object{String}
对于列Total ==> 数据为500.00,类型为object{decimal}
对于列InvoiceNumber ==> 数据为{},类型为object{System.DBNull}
当 Excel 文件中的列值确实为“EV56.78”时

对于具有相同模式(带有数字和小数点的字符串)的每一列都会发生这种情况。

1.为什么OleDbDataReader对象在值类似于这种模式时将此列值作为NULL,而不是像String一样读取它???数据读取器检索时,小数点是否与数据类型混淆???
2. 我的 Excel 文件中的单元格格式是否与数据类型混淆??? “InvoiceNumber”列中的整列和所有单元格都具有“常规”格式。
3.我是否必须在OleDbDataReader对象中添加一个额外的参数来解析列值或类似的东西???

我正在 Visual Studio 2010 Ultimate Edition 上进行开发; 64位操作系统;从 MS-Office 2013 读取 Excel 文件。
如果您需要额外的信息或代码 sn-ps,我将编辑问题以进一步解释自己(我认为这些信息已经足够了)。


如果您遇到与此问题类似的问题,感谢您提供任何帮助!!!

【问题讨论】:

    标签: c# excel visual-studio oledbdatareader


    【解决方案1】:

    在你的连接字符串中添加IMEX=1

    Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcelFile.xlsx;
    Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";
    

    原因:

    Excel 从前几行推断每列的数据类型。当它遇到与推断的数据类型不匹配的值时,它会将其视为 null。

    资源:

    来自ConnectionStrings

    如果您想将列标题读入结果集中(使用 HDR=NO 即使有标题)并且列数据是数字, 使用 IMEX=1 来避免崩溃。

    始终使用 IMEX=1 是一种更安全的方式 检索混合数据列的数据。考虑一个场景 Excel 文件可能工作正常,因为该文件的数据会导致驱动程序 猜测一种数据类型,而另一个包含其他数据的文件导致 驱动程序猜测另一种数据类型。这可能会导致您的应用 崩溃。

    【讨论】:

    • 这个参数不起作用。它仅适用于将列标题作为文本读取,例如,如果您的标题列数据是数字并避免崩溃。这不适用于表的数据。我已经尝试过了,它的行为仍然相同.....看看this answer
    【解决方案2】:
    Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;
    Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";
    

    当您想将文件中的所有数据都视为文本时,请使用上述一种,覆盖 Excels 列类型“常规”以猜测列中的数据类型。

    始终使用IMEX=1 是一种更安全的方式来检索混合数据列的数据。考虑这样一种情况:一个 Excel 文件可能工作正常,导致该文件的数据导致驱动程序猜测一种数据类型,而另一个包含其他数据的文件导致驱动程序猜测另一种数据类型。这可能会导致您的应用崩溃。 Excel connection strings

    【讨论】:

    • 这个参数不起作用。它仅适用于将列标题作为文本读取,例如,如果您的标题列数据是数字并避免崩溃。这不适用于表的数据。我已经尝试过了,它的行为仍然相同.....看看this answer
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多