Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert a date to an Open XML worksheet?

I'm using Microsoft Open XML SDK 2 and I'm having a really hard time inserting a date into a cell. I can insert numbers without a problem by setting Cell.DataType = CellValues.Number, but when I do the same with a date (Cell.DataType = CellValues.Date) Excel 2010 crashes (2007 too).

I tried setting the Cell.Text value to many date formats as well as Excel's date/numeric format to no avail. I also tried to use styles, removing the type attribute, plus many other pizzas I threw at the wall…

Can anyone point me to an example inserting a date to a worksheet?

like image 338
Manuel Avatar asked May 07 '10 23:05

Manuel


2 Answers

I used the code provided by Andrew J, but the DataType CellValues.Date produced a corrupted xlsx-file for me.

The DataType CellValues.Number worked fine for me (Don't forget to set NumberFormatId):

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

My whole code:

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

My CellFormat for this cell in the Stylesheet looks like:

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

If you'd like to format your date another way, here is a list of all default Excel NumberFormatId's

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  @

Source of list: https://github.com/ClosedXML/ClosedXML/wiki/NumberFormatId-Lookup-Table

I know this list is from ClosedXML, but it's the same in OpenXML.

like image 125
Luke Avatar answered Oct 29 '22 12:10

Luke


When creating new SpreadsheetDocument from scratch, for Date formatting to work, minimal Stylesheet has to be created.

Critical are those few lines:

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

Full Stylesheet class:

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`...

After Stylesheet is added, DateTime can be formatted:

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

Note that StyleIndex value depends on the order of CellFormat items in the CellFormats array or the Stylesheet object. In this example NumberFormatId = 14 item on the 2nd item in the array.

like image 25
Nenad Avatar answered Oct 29 '22 12:10

Nenad