La libreria OpenXML permette di creare e modificare documenti office utilizzando C#. Tra le diverse operazioni che si possono effettuare c’è la possibilità di valorizzare una o più celle di un excel.

L’interfaccia del client Excel permette in maniera molto semplice di formattare e decidere il tipo di dati di una cella e le stesse operazioni possono essere effettuate tramite l’utilizzo della libreria.

Oggi vediamo come inserire le date nelle celle di un excel e come formattarle correttamente. Per poter inserire una data in una cella excel ci dobbiamo preoccupare di due problemi:

-          In che formato scrivere il valore della cella

-          In che formato visualizzare il valore della cella.

Il primo punto si risolve abbastanza facilmente:

Lo struct DateTime di C# ha un metodo ToOADate() la cui documentazione suggerisce “Converts the value of this instance to the equivalent OLE Automation date”. L’utilizzo di questo metodo è fondamentale perché Excel salva le date come se fossero dei double e questo metodo ci da il valore corretto. Non è sufficiente però chiamare solamente il metodo perché la rappresentazione in stringa di questo double dipende dalla cultura della macchina su cui è eseguito il codice ed in generale affidarsi alla cultura di default non è una strategia sicura. Quanto detto si riassume in poche righe di codice utili a creare la cella

Cell cell = new Cell();
var value = data.ToOADate().ToString(System.Globalization.CultureInfo.InvariantCulture);
cell.CellValue = new CellValue(value);

Il punto 2 richiede che alla cella venga assegnato uno stile che abbia FontFamilyNumbering il valore 14 (che visualizza una data nel formato breve dd/MM/yyyy). Questa parte è più complicata perché richiede la creazione di uno stile ad hoc o l’utilizzo di uno già presente nel caso in cui ci sia uno adatto nel file excel in lavorazione.

Con il tool “OpenXML Office Productivity Tool” abbiamo generato il codice per la creazione dello stile di un excel vuoto. Questi stili sono obbligatori per il corretto funzionamento del file excel quindi vale sicuramente la pena avere il codice che li produce. Lo snippet inizia con le using necessarie per la corretta compilazione

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using X15 = DocumentFormat.OpenXml.Office2013.Excel;
using X14 = DocumentFormat.OpenXml.Office2010.Excel;
 
            Stylesheet stylesheet1 = new Stylesheet() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "x14ac" } };
            stylesheet1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
            stylesheet1.AddNamespaceDeclaration("x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
 
            Fonts fonts1 = new Fonts() { Count = (UInt32Value)1U, KnownFonts = true };
 
            Font font1 = new Font();
            FontSize fontSize1 = new FontSize() { Val = 11D };
            Color color1 = new Color() { Theme = (UInt32Value)1U };
            FontName fontName1 = new FontName() { Val = "Calibri" };
            FontFamilyNumbering fontFamilyNumbering1 = new FontFamilyNumbering() { Val = 2 };
            FontScheme fontScheme1 = new FontScheme() { Val = FontSchemeValues.Minor };
 
            font1.Append(fontSize1);
            font1.Append(color1);
            font1.Append(fontName1);
            font1.Append(fontFamilyNumbering1);
            font1.Append(fontScheme1);
 
            fonts1.Append(font1);
 
            Fills fills1 = new Fills() { Count = (UInt32Value)2U };
 
            Fill fill1 = new Fill();
            PatternFill patternFill1 = new PatternFill() { PatternType = PatternValues.None };
 
            fill1.Append(patternFill1);
 
            Fill fill2 = new Fill();
            PatternFill patternFill2 = new PatternFill() { PatternType = PatternValues.Gray125 };
 
            fill2.Append(patternFill2);
 
            fills1.Append(fill1);
            fills1.Append(fill2);
 
            Borders borders1 = new Borders() { Count = (UInt32Value)1U };
 
            Border border1 = new Border();
            LeftBorder leftBorder1 = new LeftBorder();
            RightBorder rightBorder1 = new RightBorder();
            TopBorder topBorder1 = new TopBorder();
            BottomBorder bottomBorder1 = new BottomBorder();
            DiagonalBorder diagonalBorder1 = new DiagonalBorder();
 
            border1.Append(leftBorder1);
            border1.Append(rightBorder1);
            border1.Append(topBorder1);
            border1.Append(bottomBorder1);
            border1.Append(diagonalBorder1);
 
            borders1.Append(border1);
 
            CellStyleFormats cellStyleFormats1 = new CellStyleFormats() { Count = (UInt32Value)1U };
            CellFormat cellFormat1 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U };
 
            cellStyleFormats1.Append(cellFormat1);
 
            CellFormats cellFormats1 = new CellFormats() { Count = (UInt32Value)1U };
            CellFormat cellFormat2 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U };
 
            cellFormats1.Append(cellFormat2);
 
            CellStyles cellStyles1 = new CellStyles() { Count = (UInt32Value)1U };
            CellStyle cellStyle1 = new CellStyle() { Name = "Normal", FormatId = (UInt32Value)0U, BuiltinId = (UInt32Value)0U };
 
            cellStyles1.Append(cellStyle1);
            DifferentialFormats differentialFormats1 = new DifferentialFormats() { Count = (UInt32Value)0U };
            TableStyles tableStyles1 = new TableStyles() { Count = (UInt32Value)0U, DefaultTableStyle = "TableStyleMedium2", DefaultPivotStyle = "PivotStyleLight16" };
 
            StylesheetExtensionList stylesheetExtensionList1 = new StylesheetExtensionList();
 
            StylesheetExtension stylesheetExtension1 = new StylesheetExtension() { Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" };
            stylesheetExtension1.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
            X14.SlicerStyles slicerStyles1 = new X14.SlicerStyles() { DefaultSlicerStyle = "SlicerStyleLight1" };
 
            stylesheetExtension1.Append(slicerStyles1);
 
            StylesheetExtension stylesheetExtension2 = new StylesheetExtension() { Uri = "{9260A510-F301-46a8-8635-F512D64BE5F5}" };
            stylesheetExtension2.AddNamespaceDeclaration("x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
            X15.TimelineStyles timelineStyles1 = new X15.TimelineStyles() { DefaultTimelineStyle = "TimeSlicerStyleLight1" };
 
            stylesheetExtension2.Append(timelineStyles1);
 
            stylesheetExtensionList1.Append(stylesheetExtension1);
            stylesheetExtensionList1.Append(stylesheetExtension2);
 
            stylesheet1.Append(fonts1);
            stylesheet1.Append(fills1);
            stylesheet1.Append(borders1);
            stylesheet1.Append(cellStyleFormats1);
            stylesheet1.Append(cellFormats1);
            stylesheet1.Append(cellStyles1);
            stylesheet1.Append(differentialFormats1);
            stylesheet1.Append(tableStyles1);
            stylesheet1.Append(stylesheetExtensionList1);
 
            part.Stylesheet = stylesheet1;

A questa carrellata di codice dobbiamo aggiungere solo un paio di righe per gestire il nuovo stile, la prima subito dopo la definizione di “cellFormat2”, la seconda subito prima la definizione di “cellStyles1”

 

CellFormat cellFormat3 = new CellFormat() { NumberFormatId = (UInt32Value)14U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U, ApplyNumberFormat = true };
 
            cellFormats1.Append(cellFormat3);


 Infine assegnamo lo stile alla nostra cella con il codice

 

cell1.StyleIndex = (UInt32Value)1U;
comments powered by Disqus