2011-01-20 38 views
2

Office Open XML SDK中是否有现有的API或第三方从SpreadsheetML/.xlsx文件中正确读取日期?用于从SpreadsheetML文件中读取日期的现有API?

由于当值为日期时(numFmtId +自定义数字格式),会有很多变量影响检测,然后将日期序列转换为DateTime值(标准,向后兼容和1904超级向后兼容工作簿),这似乎是合乎逻辑的,这是SDK将提供的东西,或者至少有人会有现有的代码片段来处理。

我正在使用C#,但任何语言的解决方案将罚款。

回答

1

看起来没有任何东西已经专门用于此目的。这是我想出的例程。

/// <summary> 
/// Represents the formula used for converting date serial values stored within the workbook into DateTime instances. 
/// </summary> 
/// <remarks> 
/// Information on date serial conversion is available here: http://www.documentinteropinitiative.com/implnotes/ISO-IEC29500-2008/001.018.017.004.001.000.000.aspx 
/// </remarks> 
public enum XlsxDateCompatibility 
{ 
    /// <summary> 
    /// Standard dates are based on December 30, 1899 and are considered "Standard 1900" dates. 
    /// </summary> 
    StandardBase1900, 

    /// <summary> 
    /// Excel for Windows backwards compatible dates are based on December 31, 1899 are are considered "Backwards compatible 1900" dates. 
    /// </summary> 
    BackwardsCompatibleBase1900, 

    /// <summary> 
    /// Excel for Macintos backwards compatible dates are based on January 1, 1904 and are considered "1904" dates. 
    /// </summary> 
    BackwardsCompatibleBase1904 
} 

    private static readonly IDictionary<XlsxDateCompatibility, DateTime> _dateSerialBaseDates 
     = new Dictionary<XlsxDateCompatibility, DateTime> 
      { 
       {XlsxDateCompatibility.StandardBase1900, new DateTime(1899, 12, 30)}, 
       {XlsxDateCompatibility.BackwardsCompatibleBase1900, new DateTime(1899, 12, 31)}, 
       {XlsxDateCompatibility.BackwardsCompatibleBase1904, new DateTime(1904, 1, 1)} 
      }; 

    public static DateTime DateSerialToDateTime(double dateSerial, XlsxDateCompatibility dateCompatibility) 
    { 

     // special case for dateCompaitility 1900, Excel thinks 1900 is a leap year 
     // http://support.microsoft.com/kb/214019 
     if (dateCompatibility == XlsxDateCompatibility.BackwardsCompatibleBase1900 && dateSerial >= 61.0) 
     { 
      dateSerial -= 1; 
     } 

     DateTime baseDate;   
     if (!_dateSerialBaseDates.TryGetValue(dateCompatibility, out baseDate)) 
     { 
      baseDate = _dateSerialBaseDates[XlsxDateCompatibility.StandardBase1900]; 
     } 
     return baseDate.AddDays(dateSerial); 
    } 
0

我从来没有读过日期,但我想象你必须将你正在阅读的单元格的样式索引与x:numFmts元素中的日期样式索引进行比较,您可以在x:cellStyle中找到它。我知道Office 2010在单元格上有一个日期数据类型指示符,因此如果您使用该版本,那么<x:c t='d'>就会更容易找到数据是否为日期。这是它会是什么样子在Office 2010:

<x:c r="C4" t="d"> 
    <x:v>1976-11-22T08:30Z</x:v> 
</x:c> 

将数据转换成一个日期时间,我相信所有你需要做的就是一个DateTime.FromOADate(cellvalue)其中cellValue是双。我知道我们在将日期插入到我们的Excel文档之前将DateTime转换为OADate,所以我想象使用FromOADate方法可以正常工作。

就任何API来做这些功能,我没有意识到任何将执行你想要的,但我希望它将被包含在SDK的未来版本。

+0

感谢您的意见。关于如何识别日期和技术细节,我已经提出了很好的答案。这实际上比你的回答显示要复杂得多。我有足够的信息来编写自定义代码来读取日期,但我突然想到这应该是一个常见问题,并且很惊讶我找不到任何现有的代码来处理它。 – 2011-01-20 04:14:46

相关问题