Как вставить дату в рабочий лист Open XML?

Я использую Microsoft Open XML SDK 2, и мне очень сложно вставить дату в ячейку. Я могу вставлять числа без проблем, установив Cell.DataType = CellValues.Number, но когда я делаю то же самое с дата (Cell.DataType = CellValues.Date) Excel 2010 аварийно завершает работу (2007 тоже).

Я попытался установить Cell.Text значение для многих форматов даты, а также дата/числовой формат Excel безрезультатно. Я также попытался использовать стили, удалив атрибут type, а также многие другие пиццы, которые я бросил в стену...

Can кто-нибудь указывает мне на пример вставки даты в рабочий лист?

6 ответов


вы должны преобразовать DateTime to double С помощью функции ToOADate т. е.:

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

затем установите его как CellValue

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

Не забудьте отформатировать ячейку с помощью DateTime форматирование, иначе вы увидите double значение, а не дата.


я использовал код, предоставленный Andrew J, но DataType CellValues.Date создал поврежденный xlsx-файл для меня.

на DataType CellValues.Number отлично сработало для меня (не забудьте указать NumberFormatId):

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

весь мой код:

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

мой параметру cellformat для этой ячейки в таблице стилей выглядит так:

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

если вы хотите отформатировать дату по-другому, Вот список всех по умолчанию В 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  @

источник списка: http://closedxml.codeplex.com/wikipage?title=NumberFormatId%20Lookup%20Table

Я знаю, что этот список из ClosedXML, но это то же самое в OpenXML.


при создании новых SpreadsheetDocument С нуля, для Date форматирование для работы, минимальное Stylesheet должен быть создан.

критичны эти несколько строк:

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

полное Stylesheet класс:

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

после Stylesheet добавляется DateTime можно отформатировать:

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

отметим, что StyleIndex значение зависит от порядка CellFormat элементов CellFormats массив или


существует 2 способа хранения дат в OpenXml; написав число (используя ToOADate) и задание DataType to Number или писать ISO 8601 отформатированная дата и установка DataType to Date. Обратите внимание, что по умолчанию DataType и Number поэтому, если вы идете с первым вариантом, вам не нужно устанавливать DataType.

какой бы метод вы ни выбрали, вам нужно будет установить стиль, поскольку Excel отображает оба метода одинаково. Следующий код показывает пример о написании даты с помощью Number формат (С и без явной установки DataType) и с использованием формата 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();
}

Использовать Общую Строку:

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

потом в коде:

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

следующее работало для нас:

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

задайте для типа данных значение CellValues.Номер, а затем обязательно отформатируйте ячейку с соответствующим индексом стиля из CellFormats. В нашем случае мы строим таблицу стилей внутри листа, а StyleDate-это индекс в CellFormats в таблице стилей.