2010-07-22 22 views
6

Non riesco a trovare questo.C# Open Xml SDK 2.0 Impostazione foglio di calcolo Cell DateTime Format

la mia situazione:

  • SDK 2.0
  • nessun foglio modello
  • C# 4.0 in VS2010

il mio problema:
Alcuni dati nei file excel voglio costruire esiste nel formato DateTime. Siccome non voglio usare solo stringhe (i datati a stringhe non possono essere ordinati correttamente) Voglio impostare le celle che contengono DateTime in un formato che scelgo come farei in Excel.
Per quanto mi riguarda, devo usare un foglio di stile per arrivare a quel punto. Ho navigato in rete per un po 'ora per trovare qualcuno che abbia una spiegazione semplice a questo problema, ma sembra difficile da trovare.

Ho già un foglio di calcolo in mem, con la possibilità di aggiungere dati, tramite SheetData. l'unica cosa che mi manca è la formattazione/lo stile delle celle.

questo è quanto ho ottenuto:

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

dove e come posso aggiungere semplici aggiunte allo stile come il tempo della data (ex, "dd-MM-yyyy"), e lo stile forse più avanzata in seguito ?

spero di essere stato abbastanza :) specifica nel frattempo terrò cercando ...

THX !!!

+0

Hai mai lavorare questo fuori? –

+0

Non hai letto le specifiche di Office Open XML? Sono solo 6.000 pagine ... :-) jk ovviamente, sto combattendo con simili "piccoli" problemi io stesso adesso. –

+1

no non l'ho mai fatto, mi dispiace per quello ... abbiamo deciso di utilizzare uno strumento di terze parti che rende i fogli :) –

risposta

3

Ci sono molti aspetti nella formattazione dei numeri come date.

È necessario iniziare con il formato numero. Identifica il formato integrato che corrisponde al modello desiderato o crea uno personalizzato. I formati incorporati sono in ECMA-376, Seconda edizione, Parte 1 - Riferimenti al linguaggio Fondamentali e di marcaturasection 18.8.30 (il riferimento per gli stili e <numFmt>) Se è necessario creare un formato personalizzato, iniziare con ID 164 e aggiungerli a . l'elemento <numFmts> all'interno del file styles.xml Questo è accessibile nel SDK come:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.NumberingFormats 

successivo è necessario disporre di un formato di cella che si riferisce a un formato di data Hai sempre bisogno di un formato di cella, non ci sono incorporato. in uno Lo stile di cella si riferisce al formato numerico numFmtId e sono definiti all'interno di styles.xml all'interno di <cellXfs>. Questo è accessibile nel sdk come:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.CellStyles 

Gli stili di cella stessi non hanno un ID. Si riferiscono alla posizione di indice zero all'interno dell'elenco di stili di celle. Pertanto, quando crei le celle, imposta il loro indice di stile sullo stile desiderato per le date.

Per il valore, è possibile memorizzarli nel formato ISO 8601 ma Excel 2010 utilizza ancora il formato seriale della data per memorizzare le date. Se si utilizza qualcosa di diverso da seriale di data 1900, è necessario specificarlo nelle proprietà della cartella di lavoro.

doc.WorkbookPart.Workbook.WorkbookProperties.DateCompatibility 

Ci sono due impostazioni di data e di compatibilità per la memorizzazione di valori di serie Data, possono essere di base 1900 o base 1904. 1900 è ciò che Excel 2010 utilizza e il 1904 è per la compatibilità con i vecchi Excel per Mac.

Nel 1900 i numeri di serie basati sono i giorni dal 31 dicembre 1899 con l'ulteriore complicazione che si deve trattare il 29 febbraio 1900 come data valida anche se il 1900 tecnicamente non è un anno bisestile.

Di seguito è riportato il metodo che ho scritto per la conversione dai valori seriali di data a DateTime. Hai bisogno del contrario.

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