2013-02-25 49 views
2

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

基本上我有一个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 

[更新 - 原始XML FROM XLSX档案]

<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。

作为测试我试图重新创建电子表格,但有时值会出现在同一个小数时,整数已输入到电子表格中。这是非常间歇的,我无法解释或解决这个问题。

+0

我假设'GetCellValue'是“你自己的”方法。请提供此方法的实施。 – 2013-02-25 14:40:15

+0

如果您可以提取并显示单元格B4的完整XML数据,那也将很棒。 – 2013-02-25 14:51:03

+0

完成!对不起,错过了! – Simon 2013-02-27 00:27:48

回答

2

的201.99999999999997是浮点数的真实表示。它可能并不总是准确的,更多信息请看例如here。所以你是对的,擅长应用某种格式 - 有效数字。 .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”到号码。如果您需要字符串表示形式的数字,请将其转换为数字,然后再转换为字符串。

+0

当使用CultureInfo.InvariantCulture并在将其转换回字符串时,值得一提的是,您还应该将InvariantCulture应用于ToString以避免格式不正确。 i.e..ToString(CultureInfo.InvariantCulture) – 2017-08-14 14:53:07