2010-07-22 52 views
6

Tengo problemas para encontrar este.C# Abrir Xml SDK 2.0 Configuración de hoja de cálculo Cell DateTime Format

mi situación:

  • SDK 2.0
  • ninguna hoja de cálculo de plantilla

mi problema C# 4.0 en VS2010:
Ciertos datos en los archivos de Excel Quiero construir existe en formato de fecha y hora. Como no quiero usar solo cadenas (los timestimes de cuerda no se pueden ordenar correctamente) quiero configurar las celdas que contienen DateTime en el formato que yo elija, como lo haría en Excel.
A mi entender, tengo que usar una hoja de estilo para llegar a ese punto. He estado navegando por la web por un tiempo para encontrar a alguien que tenga una explicación simple para este problema, pero parece que es difícil de encontrar.

Ya tengo una hoja de cálculo en mem, con la capacidad de agregar datos, a través de SheetData. lo único que me falta es el formateo/diseño de las celdas.

esto es lo lejos que llegué:

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

dónde y cómo puedo añadir simples adiciones al estilo como fecha y hora (por ejemplo, "dd-mm-aaaa"), y un estilo quizá más avanzada más adelante ?

Espero haber sido lo suficientemente :) específica, mientras tanto voy a seguir buscando ...

THX !!!

+0

¿Alguna vez se trabaja esto? –

+0

¿No leíste las especificaciones de Office Open XML? Son solo 6.000 páginas ... :-) Jk, por supuesto, estoy peleando con problemas "pequeños" similares en este momento. –

+1

no, yo nunca lo hice, lo siento por eso ... decidimos utilizar una herramienta de terceros que hace las hojas :) –

Respuesta

3

Hay mucho involucrado en el formato de números como fechas.

Debe comenzar con el formato del número. Identifique el formato integrado que coincide con el patrón que desea o cree uno personalizado. Los formatos integrados están en ECMA-376, Segunda edición, Parte 1: Fundamentos y referencia del lenguaje de marcadosection 18.8.30 (la referencia para estilos y <numFmt>. Si necesita crear un formato personalizado, comience con ID 164 y agréguelos a . <numFmts> el elemento dentro de su archivo styles.xml Esto es accesible en el SDK como:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.NumberingFormats 

continuación, tiene que tener un formato de celda que hace referencia a un formato de fecha siempre se necesita un formato de celda, no hay incorporado. en unos. El estilo de celda se refiere al formato de número por numFmtId y se define dentro de styles.xml dentro de <cellXfs>. Esto es accesible en el SDK como:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.CellStyles 

Los propios estilos de celda no tienen una ID. Se les hace referencia por posición de índice cero dentro de la lista de estilos de celda. Entonces cuando crea sus celdas, establezca su índice de estilo al estilo que desea para sus fechas.

Por el valor, puede almacenarlos en formato ISO 8601, pero Excel 2010 todavía usa el formato de fecha y hora para almacenar sus fechas. Si usa otra cosa que no sea la serie de 1900, debe especificarla en las propiedades del libro de trabajo.

doc.WorkbookPart.Workbook.WorkbookProperties.DateCompatibility 

Hay dos configuraciones de compatibilidad actualizada para almacenar los valores de serie de fecha, pueden ser de base 1900 o base 1904. 1900 es lo que Excel 2010 y 1904 usos es para la compatibilidad hacia atrás con el viejo Excel para Mac.

En 1900, el número es el número de días desde el 31 de diciembre de 1899 con la complicación adicional de que debe tratarse el 29 de febrero de 1900 como una fecha válida aunque técnicamente 1900 no es un año bisiesto.

A continuación se muestra el método que escribí para convertir los valores de serie de fecha a DateTime. Necesitas el reverso

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