2014-09-30 98 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