从Excel单元格中读取十进制值(在C#中)

4

当从包含小数的Excel单元格中读取值时,我遇到了以下问题:如果我在Excel单元格中输入9.95,则C#中的CellValue.InnerText返回“9.9499999999999993”。

如何获取实际输入的值,即“9.95”,并知道试图获取这些值的代码事先不知道它是十进制数还是数字。


1
你看过这个 MSDN 页面吗?向下滚动到“检索值”部分。 - gunr2171
1
@gunr2171 我已经看过了,它并没有回答问题。 - Luis Ferrao
@pnuts,我只是想以Excel显示的方式获取(文本)值,为什么你要给我讲浮点算术课呢? - Luis Ferrao
你把实际输入的值(由用户输入为9.95)和Excel存储的值(9.94999993)混淆了。 - Luis Ferrao
2
如果 Excel 不能确定,那么当您更改格式以显示 20 个小数位时,为什么它仍然会显示 9.950000000000000000,而不是存储的值 9.9499999999993 呢? - Luis Ferrao
显示剩余2条评论
3个回答

4

Excel将值存储为双精度浮点数,因此许多时候您在Excel中输入的内容并不能精确地存储为浮点数。

http://blogs.office.com/2008/04/10/understanding-floating-point-precision-aka-why-does-excel-give-me-seemingly-wrong-answers/

如果您真的想看看Excel是如何存储您的值的,可以将.xlsx扩展名更改为.zip,打开它,然后在文件中查看。这是存储在您的单元格中的所有信息:

<sheetData>
    <row r="1" spans="1:1" x14ac:dyDescent="0.3">
        <c r="A1">
            <v>9.9499999999999993</v> 
        </c>
    </row>
</sheetData>

Excel可以设计成存储您输入的确切值(通过将它们存储为十进制而不是浮点数),但算术运算速度会慢很多,因为所有计算都将在软件中而非硬件中进行。


1
我知道它被存储为浮点数,但我想知道在OPENXML SDK中是否有一种方法可以检索以用户所见方式显示的值。 - Luis Ferrao
@Luis Ferrao:我不认为有这样的功能。OpenXml SDK没有内置逻辑,它只提供了一个原始对象,您可以将xlsx文件反序列化并操纵它们。但是,您可能可以通过检查应用于单元格的列宽和样式来自己找出应显示多少位数字。 - Seth Moore

1
你无法检索数值输入的实际值。我不相信它被存储在任何地方。你看到的值就是存储的值;你也可以检索显示的值(在VBA中,它将是单元格的.Text属性),但是我认为你无法访问输入的值。
该问题与在二进制中表示某些十进制数的固有不可能性有关。
另请参阅Excel XML格式的评论

1
有没有一种方法可以在C# / OPENXML SDK中获取这个.Text - Luis Ferrao
@LuisFerrao 我不知道。它必须存储在表示工作簿的 XML 文档中,至少作为格式,因此应该以某种方式可访问,但我不熟悉 C#/OPENXML SDK。 - Ron Rosenfeld
@LuisFerrao 在这里看一下对Excel XML格式的批评:http://www.codeproject.com/Articles/20246/Microsoft-Office-XML-formats-Defective-by-design#2 - Ron Rosenfeld
我接受这个答案,因为CodeProject上的最后一个链接真的很有用,谢谢。 - Luis Ferrao
@LuisFerrao 谢谢。我会将那个链接添加到我的答案中。 - Ron Rosenfeld

0

由于Excel以浮点数存储,因此尝试从浮点数解析:

string curSep = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;
string value = CellValue.InnerText.Replace(".", curSep);
value = value.Replace(",", curSep);
return float.Parse(value);

这个可以工作吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接