如何在Open XML工作表中插入日期?

我正在使用Microsoft Open XML SDK 2,我很难在单元格中插入日期。 我可以通过设置Cell.DataType = CellValues.Number来插入数字而没有问题,但是当我对日期( Cell.DataType = CellValues.Date )执行相同操作时,Excel 2010会崩溃(2007年也是如此)。

我尝试将Cell.Text值设置为多种日期格式以及Excel的日期/数字格式无济于事。 我还尝试使用样式,删除type属性,以及我扔在墙上的许多其他比萨…

有人能指出我在工作表中插入日期的例子吗?

您必须使用函数ToOADateDateTime转换为double即:

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

然后将其设置为CellValue

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

请记住使用DateTime格式化格式化单元格,否则您将看到double值,而不是日期。

我使用了Andrew J提供的代码,但DataType CellValues.Date为我生成了一个损坏的xlsx文件。

DataType CellValues.Number对我来说很好(不要忘记设置NumberFormatId

 cell.DataType = new EnumValue(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.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的列表

 ID格式代码
 0一般
 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小时:mm tt
 19小时:mm:ss tt
 20 H:mm
 21 H:mm:ss
 22 m / d / yyyy H:mm
 37#,## 0;(#,## 0)
 38#,## 0; [红色](#,## 0)
 39#,## 0.00;(#,## 0.00)
 40#,## 0.00; [红色](#,## 0.00)
 45毫米: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 ,必须创建最小的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(); 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值取决于CellFormats数组或Stylesheet对象中CellFormat项的顺序。 在此示例中,数组中第二项上的NumberFormatId = 14项。

有两种方法可以在OpenXml中存储日期; 通过编写一个数字(使用ToOADate )并将DataType设置为Number或写入ISO 8601格式化日期并将DataType设置为Date 。 请注意,默认的DataTypeNumber因此如果您使用第一个选项,则不必设置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.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(); 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.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.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; 

将DataType设置为CellValues.Number,然后确保使用CellFormats中的相应样式索引格式化单元格。 在我们的例子中,我们在工作表中构建样式表,StyleDate是样式表中CellFormats的索引。