7

これが見つからなくて困っています。

私の状況:

  • SDK2.0
  • テンプレート スプレッドシートなし
  • VS2010 の C# 4.0

私の問題:
ビルドしたい Excel ファイルの特定のデータが DateTime 形式で存在します。文字列だけを使用したくないので (文字列の日時を正しく並べ替えることができません)、DateTime を含むセルを、Excel で行うように、選択した形式に設定したいと考えています。
私の理解では、その点に到達するにはスタイルシートを使用する必要があります。この問題について簡単な説明を持っている人を見つけるために、しばらくの間 Web を閲覧してきましたが、見つけるのは難しいようです。

私はすでに、SheetData を介してデータを追加できるスプレッドシートを mem に持っています。私が見逃しているのは、セルのフォーマット/スタイリングだけです。

これは私が得た距離です:

DocumentFormat.OpenXml.Packaging.SpreadsheetDocument doc = SpreadsheetDocument.Create("test.xlsx", SpreadsheetDocumentType.Workbook);

WorkbookPart wbPart = doc.AddWorkbookPart();
wbPart.Workbook = new Workbook();

SheetData data = new SheetData(
            new Row(...etc));

WorksheetPart wsPart = wbPart.AddNewPart<WorksheetPart>();
wsPart.Worksheet = new Worksheet(data);

Sheets sheets = doc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());

Sheet sheet = new Sheet() { Id = doc.WorkbookPart.GetIdOfPart(wsPart), SheetId = 1, Name = "TestSheet" };
sheets.Append(sheet);

wbPart.Workbook.Save();

doc.Close();

日付時刻 (例: "dd-MM-yyyy") などのスタイルへの簡単な追加や、後でより高度なスタイリングをどこにどのように追加できますか?

私が十分に具体的だったことを願っています:)その間、私は探し続けます...

THX !!!

4

2 に答える 2

3

数値を日付としてフォーマットすることには多くのことが関係しています。

数値形式から始める必要があります。必要なパターンに一致する組み込みフォーマットを特定するか、カスタムフォーマットを作成します。組み込みフォーマットは、ECMA-376、第2版、パート1-基本およびマークアップ言語リファレンス セクション18.8.30(スタイルおよびのリファレンスです<numFmt>。カスタムフォーマットを作成する必要がある場合は、ID164から始めてに追加してください。ファイル内の<numFmts>要素styles.xml。これは、SDKで次のようにアクセスできます。

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.NumberingFormats

次に、日付形式を参照するセル形式が必要です。常にセル形式が必要です。組み込みの形式はありません。セルスタイルは、によって数値形式を参照し、内部numFmtIdで定義されます。これは、SDKで次のようにアクセスできます。styles.xml<cellXfs>

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.CellStyles

セルスタイル自体にはIDがありません。それらは、セルスタイルリスト内のゼロインデックス位置によって参照されます。したがって、セルを作成するときは、セルのスタイルインデックスを日付に必要なスタイルに設定します。

値については、 ISO 8601形式で保存できますが、Excel2010では日付シリアル形式を使用して日付を保存します。1900ベースの日付シリアル以外のものを使用する場合は、ブックのプロパティで指定する必要があります。

doc.WorkbookPart.Workbook.WorkbookProperties.DateCompatibility

日付のシリアル値を格納するための2つの日付互換性設定があります。ベース1900またはベース1904です。1900はExcel2010が使用するもので、1904は古いExcelforMacとの下位互換性のためです。

1900年ベースの日付シリアルでは、数値は1899年12月31日以降の日数であり、1900年は技術的にうるう年ではありませんが、1900年2月29日を有効な日付として扱う必要があるという複雑さが加わります。

以下は、日付シリアル値からDateTimeに変換するために作成したメソッドです。逆が必要です。

/// <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-01-27T16:46:00.943 に答える
0

Closed XMLのようなライブラリを使用することを提案する人もいます

このスタック オーバーフローの議論からOpen XML と Date Formats

于 2012-05-22T00:46:07.520 に答える