2011-01-20 7 views
2

Office Open XML SDKまたはサードパーティに既存のAPIがあり、SpreadsheetML/.xlsxファイルの日付を正しく読み取ることができますか?SpreadsheetMLファイルから日付を読み取るための既存のAPIはありますか?

値が日付(numFmtId +カスタム数値形式)であることを検出し、日付シリアルをDateTime値(標準、下位互換性、および1904-super-backward-compatibleワークブック)、これは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

私は以前にDateを読んだことはありませんでしたが、読んでいるセルのスタイルインデックスをx:cellStyleにあるx:numFmts要素の日付スタイルインデックスと比較する必要があると思います。私はオフィス2010年のデータ型インジケータがセルにあることを知っています。<x:c t='d'>です。そのバージョンを使用している場合は、データが日付であるかどうかを見つけるのがずっと簡単です。

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

を私はあなたがしなければならないすべてはcellValueがダブルでDateTime.FromOADate(cellvalue)であると考えていたDateTimeにデータを変換するには:これは、Office 2010のように見えるものです。私は私たちがExcelドキュメントに日付を挿入する前にDateTimeをOADateに変換することを知っています。私はFromOADateメソッドを使ってうまくいくと思います。

これらの機能を実行するAPIについては、あなたが望むものを実行するものは何も認識していませんが、SDKの将来のバージョンに含まれることを望みます。

+0

ご意見ありがとうございます。私はすでに日付を特定し、それを読む方法の技術的な詳細について質問し、良い答えを得ました。実際には、答えが示すよりもはるかに複雑です。私は現在の日付を読むためのカスタムコードを書くのに十分な情報を持っていますが、これは一般的な問題であり、それを扱うための既存のコードを見つけることができなかったことに驚いていました。 –

+0

@サミュエル - うん、私の答えは、どのようにしてエクセルで日付を特定するかについての50,000フィートの見解ですが、あなたが書いたものよりも複雑であるということは間違いありません。 Open XML SDKの基本的な質問に対する答えを見つけるのは難しいので、コードを理解したいと思います。 – amurra

+1

完了したら、プロジェクトを投稿します。私は、Open XML SDKのSAXスタイルの処理を使用して、xlsxからDataSetへの変換を行っています。 –

関連する問題