2010-05-07 78 views
11

我正在使用Microsoft Open XML SDK 2,而且我很難將日期插入到單元格中。通過設置Cell.DataType = CellValues.Number,我可以插入數字而不會出現問題,但是當我對日期(Cell.DataType = CellValues.Date)執行相同操作時,Excel 2010崩潰(2007年也是如此)。如何將日期插入到Open XML工作表?

我嘗試設置Cell.Text值爲許多日期格式以及Excel的日期/數字格式無濟於事。我也嘗試使用樣式,刪除類型屬性,加上我扔在牆上的許多其他披薩...

任何人都可以指向插入日期到工作表的示例嗎?

感謝,

回答

7

你要轉換的日期時間使用功能ToODate即翻番:

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

rembember使用日期時間的格式來格式化單元格,否則你會看到雙重價值,而不是日期:)

+0

注意1904年國旗 - 日期可以設置爲1-1-1900或1-1-1904(因爲它計算閏年的錯誤)。 – 2011-10-07 12:03:24

+1

這個解決方案對我來說很合適,謝謝 – Selwyn 2011-10-19 05:55:31

+3

奇怪的是,沒有爲我工作。即使在Excel 2010.(CellValues.Date不應該在2007年支持) – GaussZ 2011-12-22 15:06:55

0

使用共享S特林:

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

以下爲我們工作:

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

設置數據類型來CellValues.Number,然後務必將細胞與格式來自CellFormats的適當樣式索引。在我們的例子中,我們在工作表中創建了一個樣式表,StyleDate是樣式表中CellFormats的索引。

+1

你如何看StyleDate? – user236215 2012-11-17 07:09:02

20

我使用了Andrew J提供的代碼,但DataType CellValues.Date爲我生成了一個損壞的xlsx文件。

數據類型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的

 
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中是一樣的。

+0

這對我很好,謝謝!正如你所說,接受的解決方案對我來說不起作用,Date類型實際上不受支持。 – 2015-09-14 15:58:43

8

從零開始創建新的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數組或Stylesheet對象。在此示例中,數組中第二項的NumberFormatId = 14項目。

2

有兩種方法可以在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>(); 
    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(); 
}