Pregunta

Estoy usando Microsoft Open XML SDK 2 y estoy teniendo un momento muy difícil insertar una fecha en una celda. Puedo insertar números sin ningún problema estableciendo Cell.DataType = CellValues.Number, pero cuando lo haga lo mismo con una fecha (Cell.DataType = CellValues.Date) Excel 2010 se bloquea (2007 también).

He intentado establecer el valor Cell.Text a muchos formatos de fecha, así como la fecha / formato numérico de Excel en vano. También traté de estilos de uso, eliminando el atributo de tipo, además de muchas otras pizzas me tiró en la pared ...

me puede punto cualquiera a un ejemplo de insertar una fecha para una hoja de cálculo?

¿Fue útil?

Solución

Se tiene que convertir a DateTime double usando la función ToOADate es decir:.

DateTime dtValue = DateTime.Now;
string strValue = dtValue.ToOADate().ToString(CultureInfo.InvariantCulture);

a continuación, establecer como CellValue

Cell cell;
cell.DataType = new EnumValue<CellValues>(CellValues.Date);
cell.CellValue = new CellValue(strValue);

Recuerde formato de celda usando DateTime formato, de lo contrario se verá double valor, no la fecha.

Otros consejos

He utilizado el código proporcionado por Andrew J, pero el DataType CellValues.Date produje un xlsx-archivo dañado para mí.

El DataType CellValues.Number funcionó bien para mí (no se olvide de conjunto NumberFormatId)

cell.DataType = new EnumValue<CellValues>(CellValues.Number);

Mi código de conjunto:

DateTime valueDate = DateTime.Now;
string valueString = valueDate.ToOADate().ToString();
CellValue cellValue = new CellValue(valueString);

Cell cell = new Cell();
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
cell.StyleIndex = yourStyle; //StyleIndex of CellFormat cfBaseDate -> See below
cell.Append(cellValue);

Mi CellFormat para este celular en las miradas de hojas de estilo como:

CellFormat cfBaseDate = new CellFormat() { 
 ApplyNumberFormat = true,
 NumberFormatId = 14, //14 is a localized short Date (d/m/yyyy) -> See list below
 //Some further styling parameters
}; 

Si desea dar formato a la fecha de otra manera, aquí hay una lista de todos por defecto Excel de NumberFormatId

ID  FORMAT CODE
0   General
1   0
2   0.00
3   #,##0
4   #,##0.00
9   0%
10  0.00%
11  0.00E+00
12  # ?/?
13  # ??/??
14  d/m/yyyy
15  d-mmm-yy
16  d-mmm
17  mmm-yy
18  h:mm tt
19  h:mm:ss tt
20  H:mm
21  H:mm:ss
22  m/d/yyyy H:mm
37  #,##0 ;(#,##0)
38  #,##0 ;[Red](#,##0)
39  #,##0.00;(#,##0.00)
40  #,##0.00;[Red](#,##0.00)
45  mm:ss
46  [h]:mm:ss
47  mmss.0
48  ##0.0E+0
49  @

Fuente de lista: https://github.com/ClosedXML/ClosedXML / wiki / IdFormatoNumerico-Lookup-Table

Sé que esta lista es de ClosedXML, pero es lo mismo en OpenXML.

Al crear nuevo SpreadsheetDocument desde cero, para Date formato a trabajo, mínimo Stylesheet tiene que ser creado.

críticas son aquellas pocas líneas:

new CellFormat
{
    NumberFormatId = 14,
    ApplyNumberFormat = true
})

clase Stylesheet completo:

using (var spreadSheet = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook))
{
    // Workbook
    var workbookPart = spreadSheet.AddWorkbookPart();
    workbookPart.Workbook =
        new Workbook(new Sheets(new Sheet { Name = "Sheet1", SheetId = (UInt32Value) 1U, Id = "rId1" }));

    // Add minimal Stylesheet
    var stylesPart = spreadSheet.WorkbookPart.AddNewPart<WorkbookStylesPart>();
    stylesPart.Stylesheet = new Stylesheet
    {
        Fonts = new Fonts(new Font()),
        Fills = new Fills(new Fill()),
        Borders = new Borders(new Border()),
        CellStyleFormats = new CellStyleFormats(new CellFormat()),
        CellFormats =
            new CellFormats(
                new CellFormat(),
                new CellFormat
                {
                    NumberFormatId = 14,
                    ApplyNumberFormat = true
                })
    };

    // Continue creating `WorksheetPart`...

Después se añade Stylesheet, DateTime se puede formatear:

if (valueType == typeof(DateTime))
{
    DateTime date = (DateTime)value;
    cell.CellValue = new CellValue(date.ToOADate().ToString(CultureInfo.InvariantCulture));

    // "StyleIndex" is "1", because "NumberFormatId=14"
    // is in the 2nd item of `CellFormats` array.
    cell.StyleIndex = 1; 
}

Tenga en cuenta que el valor StyleIndex depende del orden de los elementos de la matriz CellFormat CellFormats o el objeto Stylesheet. En este ejemplo elemento NumberFormatId = 14 en el segundo elemento de la matriz.

Hay 2 maneras de almacenar fechas en OpenXml; escribiendo un número (usando ToOADate) y ajuste de la DataType a Number o escribiendo un ISO 8601 fecha y establecer el DataType a Date formateado. Tenga en cuenta que el valor predeterminado es DataType Number así que si vas con la primera opción que no tiene que establecer el DataType.

Independientemente del método que elija, tendrá que definir el estilo como Excel muestra ambos métodos de forma idéntica. A continuación se muestra un ejemplo de código de escribir una fecha con el formato Number (con y sin establecer explícitamente la DataType) y usando el formato ISO 8601.

using (SpreadsheetDocument document = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook))
{
    //fluff to generate the workbook etc
    WorkbookPart workbookPart = document.AddWorkbookPart();
    workbookPart.Workbook = new Workbook();

    var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
    worksheetPart.Worksheet = new Worksheet();

    Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());

    Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Sheet" };
    sheets.Append(sheet);

    workbookPart.Workbook.Save();

    var sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());

    //add the style
    Stylesheet styleSheet = new Stylesheet();

    CellFormat cf = new CellFormat();
    cf.NumberFormatId = 14;
    cf.ApplyNumberFormat = true;

    CellFormats cfs = new CellFormats();
    cfs.Append(cf);
    styleSheet.CellFormats = cfs;

    styleSheet.Borders = new Borders();
    styleSheet.Borders.Append(new Border());
    styleSheet.Fills = new Fills();
    styleSheet.Fills.Append(new Fill());
    styleSheet.Fonts = new Fonts();
    styleSheet.Fonts.Append(new Font());

    workbookPart.AddNewPart<WorkbookStylesPart>();
    workbookPart.WorkbookStylesPart.Stylesheet = styleSheet;

    CellStyles css = new CellStyles();
    CellStyle cs = new CellStyle();
    cs.FormatId = 0;
    cs.BuiltinId = 0;
    css.Append(cs);
    css.Count = UInt32Value.FromUInt32((uint)css.ChildElements.Count);
    styleSheet.Append(css);

    Row row = new Row();

    DateTime date = new DateTime(2017, 6, 24);

    /*** Date code here ***/
    //write an OADate with type of Number
    Cell cell1 = new Cell();
    cell1.CellReference = "A1";
    cell1.CellValue = new CellValue(date.ToOADate().ToString());
    cell1.DataType = new EnumValue<CellValues>(CellValues.Number);
    cell1.StyleIndex = 0;
    row.Append(cell1);

    //write an OADate with no type (defaults to Number)
    Cell cell2 = new Cell();
    cell2.CellReference = "B1";
    cell2.CellValue = new CellValue(date.ToOADate().ToString());
    cell1.StyleIndex = 0;
    row.Append(cell2);

    //write an ISO 8601 date with type of Date
    Cell cell3 = new Cell();
    cell3.CellReference = "C1";
    cell3.CellValue = new CellValue(date.ToString("yyyy-MM-dd"));
    cell3.DataType = new EnumValue<CellValues>(CellValues.Date);
    cell1.StyleIndex = 0;
    row.Append(cell3);

    sheetData.AppendChild(row);

    worksheetPart.Worksheet.Save();
}

Uso compartido de la secuencia:

// assuming it's the first item in the shared string table
SharedStringItem sharedStringItem = new SharedStringItem();
Text text = new Text();
text.Text = DateTime.Today.ToString("MM/dd/yyyy hh:mm");
sharedStringTable1.Append(sharedStringItem);

Luego, más tarde en el código:

// assuming it's the first item in the shared string table
var cell = new Cell {CellReference = "A1", DataType = CellValues.SharedString};
var cellValue = new CellValue("0");
cell.Append(cellValue);

Los siguientes trabajó para nosotros:

c.CellValue = new CellValue(datetimeValue).ToOADate().ToString());
c.DataType = CellValues.Number;
c.StyleIndex = StyleDate;

Configurar el Tipo de datos a CellValues.Number y luego asegúrese de formatear la celda con el índice de estilo en cuestión en los CellFormats. En nuestro caso, construimos una hoja de estilo dentro de la hoja de cálculo y StyleDate es un índice en los CellFormats en la hoja de estilo.

a) Obtener la compatibilidad con Excel 2007, Excel 2007 Visor etc. b) Fecha y hora antes del 01/01/1900 escritura como cadena.

DateTime dat = (DateTime)dr[dc.ColumnName];

//Not working with Excel 2007
//cell.DataType = CellValues.Date;
//cell.CellValue = new CellValue(dat.ToString("s"));

double diff = (dat - new DateTime(1899, 12, 30)).TotalSeconds / 86400.0;
if (diff > 1)
{
    cell.DataType = CellValues.Number;
    cell.CellValue = new CellValue(diff.ToString().Replace(",", "."));

    if (dat.TimeOfDay == new TimeSpan(0))
    {                                
        cell.StyleIndex = 2;   //Custom Style NumberFormatId = 14 ( d/m/yyyy)
    }
    else
    {
        cell.StyleIndex = 1;   //Custom Style NumberFormatId = 22 (m/d/yyyy H:mm)
    }
}
else
{
    cell.DataType = CellValues.String;
    cell.CellValue = new CellValue(dat.ToString());
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top