2014-09-30 77 views
4

我使用OpenXML SDK來解析.xlsx文件。OpenXml SDK爲大數返回科學值

當我在Excel文件中有非常大的數字時,即344230125015305000,OpenXML將它轉換爲科學版本,即3.4423012501530502E+17。這很奇怪,因爲「完整」值存在於Excel文件中,這意味着它沒有被截斷,並且它應該在Cell對象中的某個地方可用。

enter image description here

任何建議者居多。

UPDATE:

@AlexeiLevenkov建議我看看XML文件,並將其顯示在值存儲在科學的形式。有趣的是,Excel仍然顯示完整的表單。

enter image description here

實例:

344110425109461000 -> 3.4411042510946099E+17 
344230125015305000 -> 3.4423012501530502E+17 
344770124807291000 -> 3.4477012480729101E+17 
344770224905172000 -> 3.4477022490517197E+17 

試圖隱蔽回滿形式,即

(long)Double.Parse("3.4411042510946099E+17", CultureInfo.InvariantCulture) 

返回一個不正確的值(344110425109460992對於上面的片段)。

向該值添加單引號前綴可修復問題(另一個指示器,表示完整表單值隱藏在某處),但這不是此方案的解決方案,因爲我嘗試構建自動處理的用戶上傳文件。

+0

您的科學記數法版本具有比您在Excel中讀取的**更高的**精確度? – 2014-09-30 14:26:33

+0

據我所知,它有一個較低的精度?嘗試轉換它會返回一個不同的數字,即'(long)Double.Parse(「3.4411042510946099E + 17」,CultureInfo.InvariantCulture)'是'344110425109460992'。 – 2014-09-30 14:36:55

+0

XML是文本文件...首先檢查打開並查看內部,看看是否確實值您正在尋找。 – 2014-09-30 14:40:18

回答

1

使用Open XML Productivity Tool並反映您的文件的代碼。 我做到了,這裏什麼工具提供

public class GeneratedClass 
{ 
    // Creates an Cell instance and adds its children. 
    public Cell GenerateCell() 
    { 
     Cell cell1 = new Cell(){ CellReference = "A1", StyleIndex = (UInt32Value)1U }; 
     CellValue cellValue1 = new CellValue(); 
     cellValue1.Text = "3.4411042510946099E+17"; 

     cell1.Append(cellValue1); 
     return cell1; 
    } 
} 

所以你可以看到大量只有在科學記數法是商店,那麼你絕對需要

Double value = Double.Parse("3.4411042510946099E+17", 
    NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint, 
    System.Globalization.CultureInfo.InvariantCulture); 

值這將是確定! 有趣的事實(也許一些C#大師可以告訴我們爲什麼)是那麼你必須首先轉換爲字符串。

String strdouble = value.ToString("#", System.Globalization.CultureInfo.InvariantCulture); 
Int64 conv = Convert.ToInt64(value); 
// conv will be: 344110425109460992 
Int64 conv1 = Convert.ToInt64(strdouble, System.Globalization.CultureInfo.InvariantCulture); 
// conv1 will be: 344110425109461000 
+0

'NumberStyles.AllowExponent'標誌是我正在尋找的 – AeroX 2016-03-29 15:56:55

+0

您需要首先轉換爲字符串的原因是因爲該值太大而無法存儲在Double或Int32中:) – 2018-01-09 15:07:53

+0

這不是重點!關鍵是爲什麼將double轉換爲字符串會讓您獲得正確的值,而將同樣的double轉換爲Int64則不會 – 2018-01-10 10:31:58

0

你的風格需要聲明如下:

CellStyleFormats cellStyleFormats1 = new CellStyleFormats() { Count = (UInt32Value)1U }; 
      CellFormat cellFormat1 = new CellFormat() { NumberFormatId = (UInt32Value)1U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U, ApplyNumberFormat = true }; 

通知的NumberFormatId和ApplyNumberFormat,此ID必須是這樣,在XML看起來是這樣的:

<xf numFmtId="1" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1"/> 

PS: 來自MSDN: https://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.numberingformat(v=office.14).aspx