C# 如何在打开的XML工作表中插入日期?

C# 如何在打开的XML工作表中插入日期?,c#,excel,openxml,openxml-sdk,C#,Excel,Openxml,Openxml Sdk,我使用的是MicrosoftOpenXMLSDK2,我很难在单元格中插入日期。通过设置Cell.DataType=CellValues.Number,我可以毫无问题地插入数字,但当我对日期(Cell.DataType=CellValues.date)执行相同操作时,Excel 2010也会崩溃(2007) 我尝试将Cell.Text值设置为多种日期格式以及Excel的日期/数字格式,但均无效。我还尝试使用样式,删除了type属性,以及我扔在墙上的许多其他比萨饼 有人能给我举一个向工作表中插入日期

我使用的是MicrosoftOpenXMLSDK2,我很难在单元格中插入日期。通过设置
Cell.DataType=CellValues.Number
,我可以毫无问题地插入数字,但当我对日期(
Cell.DataType=CellValues.date
)执行相同操作时,Excel 2010也会崩溃(2007)

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


有人能给我举一个向工作表中插入日期的例子吗?

您必须使用函数
toadate将
DateTime
转换为
double
,即:

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);
细胞;
cell.DataType=新的枚举值(CellValues.Date);
cell.CellValue=新的CellValue(strValue);
请记住使用
DateTime
格式设置单元格格式,否则您将看到
double
值,而不是日期。

使用共享字符串:

// 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.Number,然后确保使用CellFormats中的适当样式索引格式化单元格。在我们的例子中,我们在工作表中构建了一个样式表,StyleDate是样式表中单元格格式的索引。

我使用了Andrew J提供的代码,但是
数据类型
为我生成了一个损坏的xlsx文件

DataType
CellValues.Number对我来说很好(别忘了设置
NumberFormatId
):

如果您想以另一种方式设置日期格式,下面是所有默认Excel格式的列表

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 @ ID格式代码 0一般 1 0 2 0.00 3 #,##0 4 #,##0.00 9 0% 10 0.00% 11 0.00E+00 12 # ?/? 13 # ??/?? 14年月日 15d-mmm-yy 16d-mmm yy月17日 18小时:毫米tt 19H:mm:ss tt 20小时:毫米 21h:mm:ss 22年月日小时:毫米 37 #,##0 ;(#,##0) 38 #,##0 ;[红色](#,#0) 39 #,##0.00;(#,##0.00) 40 #,##0.00;[红色](#,#0.00) 45毫米:不锈钢 46[h]:毫米:不锈钢 47mmss.0 48##0.0E+0 49 @ 名单来源:


我知道这个列表来自ClosedXML,但在OpenXML中它是相同的。

当从头开始创建新的
电子表格文档时,要使
日期
格式有效,必须创建最小的
样式表

关键是以下几行:

new CellFormat
{
    NumberFormatId = 14,
    ApplyNumberFormat = true
})
完整的
样式表
类:

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

请注意,
StyleIndex
值取决于
CellFormats
数组或
Stylesheet
对象中
CellFormat
项的顺序。在本例中,数组中第二项的
NumberFormatId=14
项。

有两种方法在OpenXml中存储日期;通过写入一个数字(使用
ToOADate
)并将
数据类型设置为
number
,或者通过写入格式化日期并将
数据类型设置为
日期
。请注意,默认的
数据类型
数字
,因此如果使用第一个选项,则不必设置
数据类型

无论选择哪种方法,都需要将样式设置为Excel以相同方式显示这两种方法。以下代码显示了使用
数字
格式(有无明确设置
数据类型
)和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();
}
使用(电子表格文档=电子表格文档.Create(文件名,电子表格文档类型.工作簿))
{
//绒毛以生成工作簿等
WorkbookPart WorkbookPart=document.AddWorkbookPart();
workbookPart.工作簿=新工作簿();
var worksheetPart=workbookPart.AddNewPart();
工作表部分。工作表=新工作表();
Sheets Sheets=workbookPart.工作簿.AppendChild(新工作表());
Sheet Sheet=new Sheet(){Id=workbookPart.GetIdOfPart(worksheetPart),SheetId=1,Name=“Sheet”};
附页(页);
workbookPart.Workbook.Save();
var sheetData=worksheetPart.Worksheet.AppendChild(new sheetData());
//添加样式
样式表样式表=新样式表();
CellFormat cf=新的CellFormat();
cf.NumberFormatId=14;
cf.ApplyNumberFormat=true;
CellFormats cfs=新的CellFormats();
追加(cf);
styleSheet.CellFormats=cfs;
styleSheet.Borders=新边框();
styleSheet.Borders.Append(newborder());
styleSheet.Fills=新填充();
styleSheet.Fills.Append(newfill());
styleSheet.Fonts=新字体();
styleSheet.Fonts.Append(新字体());
workbookPart.AddNewPart();
workbookPart.WorkbookStylesPart.Stylesheet=样式表;
CellStyles css=新的CellStyles();
CellStyle cs=新的CellStyle();
cs.FormatId=0;
cs.BuiltinId=0;
css.Append(cs);
css.Count=uint32 value.fromunit32((uint)css.ChildElements.Count);
追加样式表(css);
行=新行();
DateTime日期=新的日期时间(2017年6月24日);
/***这里是日期代码***/
//使用数字类型写入OADate
Cell cell1=新的Cell();
cell1.CellReference=“A1”;
cell1.CellValue=新的CellValue(date.ToOADate().ToString());
cell1.DataType=新的枚举值(CellValues.Number);
cell1.StyleIndex=0;
行。追加(单元格1);
//写入没有类型的OADate(默认为数字)
Cell cell2=新的Cell();
cell2.CellReference=“B1”;
cell2.CellValue=新的CellValue(date.ToOADate().ToString());
cell1.StyleIndex=0;
行。追加(单元格2);
//使用日期类型写入ISO 8601日期
Cell cell3=新的Cell();
cell3.CellReference=“C1”;
cell3.CellValue=新的CellValue(date.ToString(“yyyy-MM-dd”);
cell3.DataType=新的枚举值(CellValues.Date);
cell1.StyleIndex=0;
行。追加(第3单元格);
sheetData.AppendChild(行);
worksheetPart.Worksheet.Save();
}
a)获得兼容性
new CellFormat
{
    NumberFormatId = 14,
    ApplyNumberFormat = true
})
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`...
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; 
}
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();
}
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());
}