如何在Open XML工作表中插入日期?
我正在使用Microsoft Open XML SDK 2,我很难在单元格中插入日期。 我可以通过设置Cell.DataType = CellValues.Number
来插入数字而没有问题,但是当我对日期( Cell.DataType = CellValues.Date
)执行相同操作时,Excel 2010会崩溃(2007年也是如此)。
我尝试将Cell.Text
值设置为多种日期格式以及Excel的日期/数字格式无济于事。 我还尝试使用样式,删除type属性,以及我扔在墙上的许多其他比萨…
有人能指出我在工作表中插入日期的例子吗?
您必须使用函数ToOADate
将DateTime
转换为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
。 请注意,默认的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.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的索引。
- 用于SSH和Telnet的C#库
- 使用regex c#validation密码
- c#enumerable class – 与VBA兼容
- 将值转换为我的json中的’System.Collections.Generic.List`类型时出错
- MongoDB:仅更新特定字段
- 由于在调用Application.Exit()时修改集合而导致的System.InvalidOperationException
- WCF请求/响应包大小
- HttpModule.Init – 在IIS7集成模式下安全地添加HttpApplication.BeginRequest处理程序
- 如何从VB.NET中的事件中获取实际的EventHandler委托实例?