Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何防止ADO.NET在读取Excel文件时更改双值_C#_Excel_Ado.net - Fatal编程技术网

C# 如何防止ADO.NET在读取Excel文件时更改双值

C# 如何防止ADO.NET在读取Excel文件时更改双值,c#,excel,ado.net,C#,Excel,Ado.net,我的Excel输入文件中有以下行: Column1 Column2 0-5 3.040 6 2.957 7 2.876 以及以下使用ADO.NET读取的代码: string fileName = "input.xls"; var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extende

我的Excel输入文件中有以下行:

Column1       Column2
0-5           3.040 
6             2.957 
7             2.876
以及以下使用ADO.NET读取的代码:

string fileName = "input.xls";
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", fileName);
var dbConnection = new OleDbConnection(connectionString);
dbConnection.Open();
try
{
    var dbCommand = new OleDbCommand("SELECT * FROM [Sheet1$]", dbConnection);
    var dbReader = dbCommand.ExecuteReader ();

    while (dbReader.Read())
    {
        string col1 = dbReader.GetValue(0).ToString();
        string col2 = dbReader.GetValue(1).ToString();                 
    }                
}
finally
{
    dbConnection.Close();
}
结果令人非常不安。原因如下:

第一次通过循环时每列的值:

col1 is empty (blank)

col2 is 3.04016411633586
第二次:

col1 is 6

col2 is 2.95722928448829
第三次:

col1 is 7

col2 is 2.8763272933077

第一个问题发生在col1的第一次迭代中。我希望0-5。第二个问题发生在col2的每次迭代中,ADO.NET显然会在读取值时改变这些值。如何制止这种不良行为

double类型是大多数数字的近似值,在col2中可以看到更多近似值的小数。只需将其作为双精度读入,并将其转换为小数点后有3位数字的字符串表示,它们就会匹配

string col1 = dbReader.GetString(0);
var col2Value = dbReader.GetDouble(1);
string col2 = col2Value.ToString("F3");

double
类型是大多数数字的近似值,在col2中可以看到更多近似值的小数。只需将其作为双精度读入,并将其转换为小数点后有3位数字的字符串表示,它们就会匹配

string col1 = dbReader.GetString(0);
var col2Value = dbReader.GetDouble(1);
string col2 = col2Value.ToString("F3");
试着做:

string col1 = dbReader.GetString(0); 
string col2 = dbReader.GetDecimal(1).ToString();  
您还可以选择格式化
ToString
,以适应您想要的显示方式:

string col2 = dbReader.GetDecimal(1).ToString("0.000");  
试着做:

string col1 = dbReader.GetString(0); 
string col2 = dbReader.GetDecimal(1).ToString();  
您还可以选择格式化
ToString
,以适应您想要的显示方式:

string col2 = dbReader.GetDecimal(1).ToString("0.000");  

默认情况下,ADO.NET根据前8行中的多数类型推断列类型,如果存在多个类型(在平局的情况下为数字),则假定多数类型获胜,并为与其推断的数据类型不匹配的任何行返回NULL。有关此问题以及如何解决此问题的一些注意事项,请参阅。简言之:

  • 将“IMEX=1”属性添加到连接字符串中

  • 在注册表中,设置以下键:

Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/ImportMixedTypes=“Text” Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/TypeGuessRows=0


这告诉ADO如果无法确定,则采用文本数据类型,并扫描前16384行(在早期版本的Excel中,这是所有行…)以推断类型。

默认情况下,ADO.NET根据前8行中的多数类型推断列类型,如果有多个类型,则假定多数类型获胜(在平局的情况下为数字)并为与该列的推断数据类型不匹配的任何行返回NULL。有关此问题的一些说明以及如何解决此问题,请参阅。简言之:

  • 将“IMEX=1”属性添加到连接字符串中

  • 在注册表中,设置以下键:

Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/ImportMixedTypes=“Text” Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/TypeGuessRows=0


这告诉ADO,如果无法确定,则假定为文本数据类型,并扫描前16384行(在早期版本的Excel中,这是所有行…)以推断类型。

我并不反对您的方法。但是ADO.NET认为column1的数据类型为DBTYPE_R8(这是一个双精度,这也是错误的)。因此,调用dbReader.GetString(0)将引发无效的强制转换异常。我不确定这是否可能。非常感谢您的建议,但我认为ADO.NET在此施加了限制。如果您调用
dbReader.IsDBNull(0)
,它对“0-5”行值的计算结果是否为真?如果是这样,我认为您是对的,
OleDbReader
不会为您提供与列类型不匹配的值。我并不反对您的方法。但是ADO.NET认为column1的数据类型是DBTYPE\U R8(这是双精度的,这也是错误的)。因此,调用dbReader.GetString(0)将引发无效的强制转换异常。我不确定这是否可能。非常感谢您的建议,但我认为ADO.NET在这里施加了限制。如果您调用
dbReader.IsDBNull(0)
,它对“0-5”行值的计算结果是否为真?如果是这样,我认为您是对的,
OleDbReader
不会为您提供与列类型不匹配的值。您确定ADO.Net从col2读取的那些值不是存储在.xls文件中的实际值,并且您期望的值不仅仅是Exc的值吗舍入后el显示?检查单元格的格式,看看它是否设置为小数点设置为3的数字格式。不确定我是否完全遵循了你的问题,但我发布的所有内容都是这样的。ADO.NET在读取双值时会更改双值。我不必为Excel中的单元格格式而烦恼,因为我没有控件这里的用户不是程序员,所以他们不知道什么是“数据类型”是。从一个本来主要包含数字的列中提取0-5也是一个问题。我想我的意思是,您确定第1行col2中的值实际上不是.xls文件中的3.0401661633586而不是3.040吗?如果是这种情况,那么ADO.Net实际上并没有更改值,而是给出了确切的值。是吗您确定ADO.Net从col2读取的值不是存储在.xls文件中的实际值,并且您期望的值不仅仅是Excel在舍入后显示的值吗?检查单元格的格式,看看它是否设置为小数点设置为3的数字格式。不确定我是否完全遵循了您的问题,但我会检查所有内容osted就是它发生的方式。ADO.NET在读取双值时会对其进行更改。我不必担心Excel中单元格的格式,因为我无法控制它。在这种情况下,用户不是程序员,因此他们不知道什么是“数据类型”是。从一个本来主要包含数字的列中提取0-5也是一个问题。我想我的意思是,您确定第1行col2中的值实际上不是.xls文件中的3.0401661633586而不是3.040吗?如果是这样,那么ADO.Net实际上并没有更改值,而是