2010-07-22 9 views
6

Ich habe Probleme, dieses zu finden.C# Open Xml SDK 2.0 Tabellenkalkulationseinstellung Cell DateTime Format

meine Situation:

  • SDK 2.0
  • keine Vorlage Tabelle
  • C# 4.0 in VS2010

mein Problem:
Bestimmte Daten in den Excel-Dateien, die ich mag bauen existieren im DateTime-Format. Da ich nicht nur Strings verwenden möchte (stringed datetimes können nicht richtig sortiert werden), möchte ich die Zellen, die DateTime enthalten, auf ein Format meiner Wahl setzen, wie ich es in Excel tun würde.
Zu meinem Verständnis muss ich ein Stylesheet verwenden, um zu diesem Punkt zu gelangen. Ich surfe schon seit einer Weile im Internet, um jemanden zu finden, der eine einfache Erklärung für dieses Problem hat, aber es scheint, dass es schwer zu finden ist.

Ich habe bereits eine Tabelle in Mem, mit der Möglichkeit, Daten über SheetData hinzuzufügen. fehlt mir nur das Formatieren/Stylen der Zellen.

dies ist, wie weit ich habe:

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(); 

wo und wie kann ich einfache Ergänzungen Stil wie Datum Zeit (ex, „dd-MM-yyyy“), und vielleicht fortgeschritteneren Styling hinzufügen später ?

Ich hoffe, ich war spezifisch genug :) in der Zwischenzeit sucht ich halten werde ...

THX !!!

+0

Hast du das jemals funktioniert? –

+0

Haben Sie die Office Open XML-Spezifikationen nicht gelesen? Es sind nur 6.000 Seiten ... :-) jk Natürlich kämpfe ich gerade mit ähnlichen "kleinen" Problemen. –

+1

nein ich tat nie, tut mir leid, dass ... wir entschieden uns, ein Drittanbieter-Tool zu verwenden, das die Blätter macht :) –

Antwort

3

Es ist viel mit der Formatierung von Zahlen als Daten zu tun.

Sie müssen mit dem Zahlenformat beginnen. Identifizieren Sie entweder das integrierte Format, das dem gewünschten Muster entspricht, oder erstellen Sie ein benutzerdefiniertes Format. Die integrierten Formate sind in ECMA-376, zweite Ausgabe, Teil 1 - Grundlagen und Markup Language Referencesection 18.8.30 (die Referenz für Stile und <numFmt>. Wenn Sie ein benutzerdefiniertes Format erstellen müssen, beginnen Sie mit ID 164 und fügen Sie sie hinzu . das <numFmts> Element in Ihrer styles.xml Datei Dies ist im SDK zugänglich:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.NumberingFormats 

Weiter Sie ein Zellenformat haben müssen, die in ein Datumsformat bezieht sich Sie immer ein Zellenformat benötigen, gibt es keine integrierte. Der Zellstil bezieht sich auf das Zahlenformat von numFmtId und ist innerhalb styles.xml innerhalb <cellXfs> definiert.Dies ist in der SDK wie folgt:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.CellStyles 

Zellstile selbst haben keine ID. Sie werden durch die Nullindexposition innerhalb der Zellstile-Liste bezeichnet. Wenn Sie also Zellen erstellen, legen Sie ihren Stilindex auf den Stil fest, den Sie für Ihre Daten verwenden möchten.

Für den Wert können Sie sie im Format ISO 8601 speichern, aber Excel 2010 verwendet weiterhin das serielle Datum, um seine Daten zu speichern. Wenn Sie eine andere als 1900-basierte Datumsserie verwenden, müssen Sie sie in den Eigenschaften der Arbeitsmappe angeben.

doc.WorkbookPart.Workbook.WorkbookProperties.DateCompatibility 

Es gibt zwei Datumskompatibilitätseinstellungen für die Speicherung von Datum serielle Werte, können sie Basis sein 1900 oder Base 1904. 1900 ist das, was Excel 2010 verwendet und 1904 ist für die Abwärtskompatibilität mit alter Excel für Mac.

In 1900 basierten Datumsserien die Zahl ist die Tage seit dem 31. Dezember 1899 mit der zusätzlichen Komplikation, dass Sie 29. Februar 1900 als ein gültiges Datum behandeln müssen, obwohl 1900 technisch kein Schaltjahr ist.

Unten ist die Methode, die ich für das Konvertieren von seriellen Datenwerten in DateTime geschrieben hat. Du brauchst das Gegenteil.

/// <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); 
    }