2010-05-07 12 views
11

Sto utilizzando Microsoft Open XML SDK 2 e sto avendo davvero difficoltà ad inserire una data in una cella. Posso inserire numeri senza problemi impostando Cell.DataType = CellValues.Number, ma quando faccio lo stesso con una data (Cell.DataType = CellValues.Date) Excel 2010 si arresta in modo anomalo (anche nel 2007).Come inserire una data in un foglio di lavoro Open XML?

Ho provato a impostare il valore di Cell.Text su molti formati di data e sul formato data/numerico di Excel senza alcun risultato. Ho anche provato ad usare gli stili, rimuovendo l'attributo type, oltre a molte altre pizze che ho gettato al muro ...

Qualcuno può indicarmi un esempio inserendo una data in un foglio di lavoro?

Grazie,

risposta

7

Si devono convertire datetime di raddoppiare usando la funzione ToODate cioè:

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

quindi impostarlo come CellValue

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

rembember formattare cella utilizzando la formattazione datetime, altrimenti vedrai doppio valore, non data :)

+0

E fare attenzione alla bandiera del 1904: le date possono essere impostate tra 1-1-1900 o 1-1-1904 (a causa di un bug nel modo in cui calcola gli anni bisestili). –

+1

Questa soluzione ha funzionato per me, grazie – Selwyn

+3

Stranamente non ha funzionato per me. Anche su Excel 2010. (CellValues.Date non dovrebbe essere supportato nel 2007) – GaussZ

0

Usa Shared S Tring:

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

Poi più avanti nel codice:

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

Di seguito ha lavorato per noi:

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

Impostare il tipo di dati per CellValues.Number e quindi assicuratevi di formattare la cella con l'indice di stile appropriato da CellFormats. Nel nostro caso costruiamo un foglio di stile all'interno del foglio di lavoro e StyleDate è un indice nei CellFormats nel foglio di stile.

+1

Come si cerca StyleDate ?? – user236215

20

Ho utilizzato il codice fornito da Andrew J, ma il DataType CellValues.Date ha prodotto un file xlsx danneggiato per me.

il tipo di dati CellValues.Number funzionato bene per me (Non dimenticare di impostare NumberFormatId):

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

Tutto il mio codice:

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

mio CellFormat per questa cella nel foglio di stile:

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

Se vuoi formattare la data di un altro modo, ecco un elenco di tutti i predefinito Excel di 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 @ 

Fonte della lista: http://closedxml.codeplex.com/wikipage?title=NumberFormatId%20Lookup%20Table

So che questo elenco è da ClosedXML, ma è lo stesso in OpenXML.

+0

Questo ha funzionato alla grande per me, grazie! La soluzione accettata non ha funzionato per me, come dici tu, il tipo Data non è effettivamente supportato. –

8

Durante la creazione di nuova SpreadsheetDocument da zero, per Date formattazione al lavoro, il minimo Stylesheet deve essere creato.

critiche sono quelle poche righe:

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

completa Stylesheet classe: viene aggiunto

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

Dopo Stylesheet, può essere formattato 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; 
} 

noti che StyleIndex valore dipende sull'ordine di CellFormat elementi nell'array CellFormats o nell'oggetto Stylesheet. In questo esempio NumberFormatId = 14 elemento sul 2 ° elemento dell'array.

2

Ci sono 2 modi per memorizzare le date in OpenXml; scrivendo un numero (usando ToOADate) e impostando il numero DataType su o scrivendo una data formattata ISO 8601 e impostando lo DataType su Date. Si noti che il valore predefinito DataType è Number, quindi se si utilizza la prima opzione non è necessario impostare DataType.

Qualunque sia il metodo scelto, è necessario impostare lo stile in quanto Excel visualizza entrambi i metodi in modo identico. Il codice seguente mostra un esempio di scrittura di una data utilizzando il formato Number (con e senza impostazione esplicita di DataType) e utilizzando il formato 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(); 
} 
Problemi correlati