2013-02-25 15 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