使用open xml sdk从xlsx读取日期

我在其中一个单元格的xlsx文件中有一个格式为“4/5/2011”(月/日/年)的日期。 我试图解析文件并在某些类中加载这些数据。

到目前为止,我解析单元格的部分如下所示:

string cellValue = cell.InnerText; if (cell.DataType != null) { switch (cell.DataType.Value) { case CellValues.SharedString: // get string from shared string table cellValue = this.GetStringFromSharedStringTable(int.Parse(cellValue)); break; } } 

我希望date可以是cell.DataType。 事实是,在使用日期“4/5/2011”解析单元格时,cell.DataType的值为null,单元格的值为“40638”,并且它不是共享字符串表的索引。 (我之前尝试过,结果是exception。)

有任何想法吗? 谢谢

Open XML存储日期为1900年1月1日的天数。好吧,跳过1900年2月29日的错误作为有效日期。 您应该能够找到算法来帮助您计算正确的值。 我相信一些开发人员使用DateTime.FromOADate()作为帮助器。

此外,默认情况下, Cell类的DataType属性为Number。 因此,如果它为null,则为一个数字,其中包括我们的日期。

当存储的日期早于纪元(在本例中为1900年1月1日)时,您只前往共享字符串表。 然后在这种情况下,Cell类的CellValue保存共享字符串表的索引。

你可以使用DateTime.FromOADate(41690)

我有同样的问题 – 切换到EPPlus http://epplus.codeplex.com/

请注意,它具有LGPL许可证。 因此,如果您需要保护代码库免受GPL问题的影响,只需按原样使用该库,并且您的原始代码库许可证是安全的。

加上我的2便士值得。 我正在处理模板,所以我知道给定的单元格是一个DateTime。 所以我最终在这个方法中使用包含单元格值的字符串参数excelDateTime,这通常是一个OADate数字,如“42540.041666666664”。

 public static bool TryParseExcelDateTime(string excelDateTimeAsString, out DateTime dateTime) { double oaDateAsDouble; if (!double.TryParse(excelDateTimeAsString, out oaDateAsDouble)) //this line is Culture dependent! return false; //[...] dateTime = DateTime.FromOADate(oaDateAsDouble); 

我的问题是最终用户在德国,因为这是一个网站,我们将Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture设置为“DE-de”。 当你调用double.TryParse ,它使用文化来解析数字。 所以这一行: double.TryParse("42540.041666666664", out oaDate)确实有效,但它返回42540041666666664因为在德国,dot是一个组分隔符。 DateTime.FromOADate然后失败,因为该数字超出范围( minOaDate = -657435.0,maxOaDate = +2958465.99999999 )。

这让我觉得:

  1. 无论用户机器上的语言环境如何,OpenXML文档都包含以默认语言环境格式化的数字(在任何情况下,US?不变量?以点作为小数分隔符)。 我搜索过,但没有找到这个规格。
  2. 当对潜在的OADate字符串执行double.TryParse时,我们应该使用double.TryParse(excelDateTimeAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out oaDateAsDouble)) 。 我正在使用CultureInfo.InvariantCulture,但它应该是1点,我不确定。

每个单元格有2个属性r(CellReference)和s(StyleIndex)

数字的StyleIndex为2,日期为3

它在ODate中的日期,您可以转换为字符串格式

value = DateTime.FromOADate(double.Parse(value))。ToShortDateString();