2

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

値が日付である場合の検出 (numFmtId + カスタム数値形式) に影響を与える変数が非常に多いため、日付シリアルを DateTime 値 (標準、後方互換、および 1904 超後方互換ワークブック) に変換します。これは SDK が提供するものであるか、少なくとも誰かが処理する既存のコード スニペットを持っていることは論理的に思えます。

私は C# を使用していますが、どの言語のソリューションでも問題ありません。

4

2 に答える 2

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);
    }
于 2011-02-18T01:49:42.640 に答える
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 に変換するには、DateTime.FromOADate(cellvalue)cellValue が double の場所を指定するだけでよいと思います。Excel ドキュメントに日付を挿入する前に、DateTime を OADate に変換することはわかっているので、FromOADate メソッドを使用するとうまくいくと思います。

これらの機能を実行する API に関する限り、あなたが望むことを実行する API はわかりませんが、SDK の将来のバージョンに含まれることを願っています。

于 2011-01-20T03:59:11.043 に答える