【问题标题】:OpenXML value different from Excel valueOpenXML 值不同于 Excel 值
【发布时间】:2013-02-25 10:55:23
【问题描述】:

我目前正在使用 OpenXML SDK,与 OpenXML 中的值相比,Excel 中显示的值存在问题。

基本上我有一个 Excel 电子表格,其中 B4 中的值为“202”。但是当我使用 OpenXml 从电子表格中读取值时,我收到的值是“201.99999999999997”。

我编写了一个测试应用程序来检查值,我使用 OpenXml 读取 Excel 文件的代码如下:

using (SpreadsheetDocument document = SpreadsheetDocument.Open(_excelFile1, false))
{
    WorkbookPart wbPart = document.WorkbookPart;

    var sheet = wbPart.Workbook.Descendants<Sheet>().First();

    var wsPart = (WorksheetPart)(wbPart.GetPartById(sheet.Id));

    Cell cell1 = wsPart.Worksheet.Descendants<Cell>().Where(c => c.CellReference == "B4").FirstOrDefault();
    Cell cell2 = wsPart.Worksheet.Descendants<Cell>().Where(c => c.CellReference == "C4").FirstOrDefault();
    Cell cell3 = wsPart.Worksheet.Descendants<Cell>().Where(c => c.CellReference == "D4").FirstOrDefault();

    Console.WriteLine(String.Format("Cell B4: {0}", GetCellValue(cell1)));
    Console.WriteLine(String.Format("Cell C4: {0}", GetCellValue(cell2)));
    Console.WriteLine(String.Format("Cell D4: {0}", GetCellValue(cell3)));
}

private static string GetCellValue(Cell cell)
{
    if (cell != null) return cell.CellValue.InnerText;
    else return string.Empty;
}

那么我得到的值如下:

Cell B4: 201.99999999999997

[更新 - 来自 XLSX 文件的原始 XML]

<row r="4" spans="1:4" x14ac:dyDescent="0.2">
    <c r="A4" s="2">
        <v>39797</v>
    </c>
  <c r="B4" s="3">
    <v>201.99999999999997</v>
  </c>
  <c r="C4" s="3">
    <v>373</v>
  </c>
  <c r="D4" s="3">
    <v>398</v>
  </c>
</row>

从 XLSX 文件 XML 中可以看出,OpenXML 正在读取正确的值。但是,Excel 必须应用某种格式才能将值“201.99999999999997”显示为“202”。这是用户看到的值,因此这是他们在使用 OpenXML 从 XLSX 文件中读取时所期望的值。

所以现在我想知道是否有人知道 Excel 应用了任何格式来获取用户在电子表格中看到的值,但使用的是 OpenXML。

作为一项测试,我尝试重新创建电子表格,但有时在电子表格中输入整数后,这些值显示为与小数相同。这是非常间歇性的,我无法解释或解决问题。

【问题讨论】:

  • 我假设GetCellValue 是“你自己的”方法。请同时提供此方法的实现。
  • 如果您能提取并呈现单元格 B4 的完整 XML 数据,那就太好了。
  • 完成!很抱歉错过了!
  • 我在百分比值和小数方面也有类似的问题。你有没有找到任何解决方法来防止这种转换?
  • @Harshini - 我也面临类似的问题。您找到解决此问题的任何解决方案了吗?

标签: c# .net openxml


【解决方案1】:

201.99999999999997 是浮点数的真实表示。它可能并不总是准确的,有关更多信息,请查看例如 here。所以你是对的,excel应用某种格式 - 有效数字。 .NET 也可以这样做,看看这个:

    static void Main(string[] args)
    {
        string s = "201.99999999999997";
        // print s as string
        Console.WriteLine(s);
        // print s as double
        Console.WriteLine(double.Parse(s, System.Globalization.CultureInfo.InvariantCulture));
        // print s as double, converted back to string
        Console.WriteLine(double.Parse(s, System.Globalization.CultureInfo.InvariantCulture).ToString());
        Console.ReadKey();

        // output is:
        // 201.99999999999997
        // 202
        // 202
    }

因此,如果您需要数字,请将“201.99999999999997”转换为数字。如果您需要数字的字符串表示形式,请将其转换为数字,然后再转换回字符串。

【讨论】:

  • 在使用 CultureInfo.InvariantCulture 并将其转换回字符串时值得一提,您也应该将 InvariantCulture 应用于 ToString 以避免格式不正确。即ToString(CultureInfo.InvariantCulture)
猜你喜欢
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
  • 2017-05-29
  • 2020-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多