using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using Aspose.Cells; using Kreta.BusinessLogic.Classes; using Kreta.BusinessLogic.HelperClasses; using Kreta.BusinessLogic.Utils; using Kreta.Core; using Kreta.Core.CustomAttributes; using Kreta.Enums.ManualEnums; using Kreta.Resources; namespace Kreta.BusinessLogic.Logic { public static class SimpleExportLogic { /// /// A sablon MemoryStream összeállítása adatok nélkül. /// /// A generálandó worksheet neve. /// A Co lista, ami leírja az oszlopok tulajdonságait/viselkedéseit, amik alapján kigeneráljuk az excel-t. public static MemoryStream GetTemplate(string worksheetName, List simpleExportColumnCos) { using (var workbook = new Workbook()) { Worksheet worksheet = GetWorksheet(workbook, worksheetName, simpleExportColumnCos); SetColumnsStyle(worksheet, simpleExportColumnCos); MemoryStream memoryStream = GetWorkbookMemoryStream(workbook); return memoryStream; } } /// /// Az export MemoryStream összeállítása feltöltve adatokkal. /// public static MemoryStream GetExport(string worksheetName, List simpleExportColumnCos, List itemList, int tanevId) { return GetExport(worksheetName, simpleExportColumnCos, itemList, null, null, tanevId); } /// /// Az export MemoryStream összeállítása feltöltve adatokkal. /// public static MemoryStream GetExport(string worksheetName, List simpleExportColumnCos, List itemList, Action worksheetAction, int tanevId) { return GetExport(worksheetName, simpleExportColumnCos, itemList, worksheetAction, null, tanevId); } /// /// Az export MemoryStream összeállítása feltöltve adatokkal. /// public static MemoryStream GetExport(string worksheetName, List simpleExportColumnCos, List itemList, Action> worksheetWithItemListAction, int tanevId) { return GetExport(worksheetName, simpleExportColumnCos, itemList, null, worksheetWithItemListAction, tanevId); } /// /// Az export MemoryStream összeállítása feltöltve adatokkal. /// /// A co vagy model típusa, aminek a property-jein lévő SimpleExportColumnAttribute alapján generáljuk az excel-t. /// A generálandó worksheet neve. /// A Co lista, ami leírja az oszlopok tulajdonságait/viselkedéseit, amik alapján kigeneráljuk az excel-t. /// Az adatok, amikkel feltöltjük az excel-t. Ide már rendezve kerlüjenek, mert olyan sorrendben kerülnek be az excel-be! /// Egyedi logika a worksheeten. /// Egyedi logika a worksheeten a listával. private static MemoryStream GetExport(string worksheetName, List simpleExportColumnCos, List itemList, Action worksheetAction, Action> worksheetWithItemListAction, int tanevId) { using (var workbook = new Workbook()) { Worksheet worksheet = GetWorksheet(workbook, worksheetName, simpleExportColumnCos); worksheet.FillWithData(itemList, simpleExportColumnCos, tanevId); worksheetAction?.Invoke(worksheet); worksheetWithItemListAction?.Invoke(worksheet, itemList); MemoryStream memoryStream = GetWorkbookMemoryStream(workbook); return memoryStream; } } /// /// Sorba rendezve visszaadja a generikus objektumból a SimpleExportColumnCo-ket. /// /// A co vagy model típusa, aminek a property-jein lévő SimpleExportColumnAttribute alapján generáljuk az excel-t. /// A property-ken lévő SimpleExportColumnAttribute-nak átadott azonsító, ami meghatározza, hogy mely oszlopkat kell generálni. /// Az oszlopohoz tartozó adatforrások, amiket külön sheet-ekbe generálunk bele. public static List GetSimpleExportColumnCos(string attributeId, Dictionary> dropDownColumnSourceDictionary = null) { var simpleExportColumnCos = new List(); if (dropDownColumnSourceDictionary == null) { dropDownColumnSourceDictionary = new Dictionary>(); } List propertyInfos = typeof(T) .GetProperties() .Where(p => Attribute.IsDefined(p, typeof(SimpleExportColumnAttribute)) && p.GetCustomAttributes(typeof(SimpleExportColumnAttribute), false) .Any(a => ((SimpleExportColumnAttribute)a).AttributeId == attributeId)) .ToList(); foreach (PropertyInfo propertyInfo in propertyInfos) { var attribute = (SimpleExportColumnAttribute)propertyInfo .GetCustomAttributes(typeof(SimpleExportColumnAttribute), false) .SingleOrDefault(p => ((SimpleExportColumnAttribute)p).AttributeId == attributeId); if (attribute == null) { throw new NullReferenceException(string.Format(ErrorResource.Az0ValtozoErtekeNemLehetNull, nameof(attribute))); } //NOTE: Azért kell kiemelni ezeket külön változóba, mert a reflection miatt, minden hivatkozánál belassul. // Viszont ha változókba vannak kiemelve ezek, akkor nem jön elő lassulás. Type propertyType = propertyInfo.PropertyType; string propertyName = propertyInfo.Name; Type forcedType = attribute.ForcedType; BooleanDisplayFormatEnum booleanDisplayFormat = attribute.BooleanDisplayFormat; int columnIndex = attribute.Index; string columnHeaderName = attribute.HeaderName; string dropDownColumnSourceSheetGroupName = attribute.DropDownColumnSourceSheetGroupName; ExcelAggregateFunctionEnum aggregateFunction = attribute.AggregateFunction; string dateTimeToStringPattern = attribute.DateTimeToStringPattern; int decimalDigitCount = attribute.DecimalDigitCount; bool asHtml = attribute.AsHtml; Type columnType = forcedType ?? propertyType; //NOTE: Ha van bool mező, akkor létrehozunk egy source-t, ami alapján majd lenyíló listát csinálunk. if (columnType == typeof(bool) && !dropDownColumnSourceDictionary.ContainsKey(CommonResource.Logikai)) { dropDownColumnSourceDictionary.Add(CommonResource.Logikai, CommonUtils.GetIgenNemList(booleanDisplayFormat)); } var dropDownColumnSource = dropDownColumnSourceDictionary.SingleOrDefault(x => columnType == typeof(bool) && x.Key == CommonResource.Logikai || x.Key == columnHeaderName); simpleExportColumnCos.Add(new SimpleExportColumnCo( columnIndex, columnHeaderName, columnType, dropDownColumnSource.Value, dropDownColumnSourceSheetGroupName ?? dropDownColumnSource.Key, aggregateFunction, booleanDisplayFormat, dateTimeToStringPattern, decimalDigitCount, asHtml, propertyName)); } //NOTE: Validáljuk, hogy csak egy fajta logikai oszlop megjelenítés lehessen! List booleanDisplayFormatList = simpleExportColumnCos .Where(x => x.Type == typeof(bool)) .GroupBy(x => x.BooleanDisplayFormat) .Select(x => x.Key) .ToList(); if (booleanDisplayFormatList.Count > 1) { throw new ApplicationException(ErrorResource.EgyExportbanCsakEgyfeleLogikaiOszlopMegjelenitesLehetseges); } return simpleExportColumnCos.OrderBy(o => o.Index).ToList(); } /// /// Sorba rendezve visszaadja egy header dictionary alapján a a SimpleExportColumnCo-ket. /// /// A header nevek dictionary-ja, ami az oszlop index-ét és a header nevét tartalmazza. /// Az oszlopohoz tartozó adatforrások, amiket külön sheet-ekbe generálunk bele. public static List GetSimpleExportColumnCos(Dictionary headerNameDictionary, Dictionary> dropDownColumnSourceDictionary = null) { var simpleExportColumnCos = new List(); if (dropDownColumnSourceDictionary == null) { dropDownColumnSourceDictionary = new Dictionary>(); } foreach (KeyValuePair item in headerNameDictionary) { var dropDownColumnSource = dropDownColumnSourceDictionary.SingleOrDefault(x => x.Key == item.Value); simpleExportColumnCos.Add(new SimpleExportColumnCo( item.Key, item.Value, null, dropDownColumnSource.Value, dropDownColumnSource.Key) ); } return simpleExportColumnCos.OrderBy(o => o.Index).ToList(); } /// /// A worksheet összeállítása a törzsadatlista sheet-ekkel együtt. /// /// A workbook, amiben létrehozzuk a worksheet-et és a törzsadatlista sheet-eket. /// A worksheet neve. /// A Co lista, ami leírja az oszlopok tulajdonságait/viselkedéseit, amik alapján a header-öket és törzsadatlistákat beállítjuk. /// a worksheet indexe. public static Worksheet GetWorksheet(Workbook workbook, string worksheetName, List simpleExportColumnCos, int worksheetIndex = 0) { string safeWorksheetName = CellsHelper.CreateSafeSheetName(worksheetName); Worksheet worksheet = workbook.Worksheets.ElementAtOrDefault(worksheetIndex) != null ? workbook.Worksheets[worksheetIndex] : workbook.Worksheets.Add(safeWorksheetName); worksheet.Name = safeWorksheetName; worksheet.CreateWorksheetHeaders(simpleExportColumnCos); CreateDropDownColumnSourceSheets(workbook, simpleExportColumnCos, worksheet.Validations); return worksheet; } /// /// Adatsorok feltöltése a worksheet-en. /// /// Az objektum típusa, amiből feltöltjük az adatokat. /// A worksheet, aminek a sorait feltöltjük a SimpleExportColumnCo lista alapján. /// A sorok listája, amikkel feltöltjük a worksheet sorait a SimpleExportColumnCo alapján. /// A Co lista, ami leírja az oszlopok tulajdonságait/viselkedéseit, amik alapján a worksheetbe feltöltjük a sorokat. public static void FillWithData(this Worksheet worksheet, List rows, List simpleExportColumnCos, int tanevId) { int rowNumber = 1; Type type = typeof(T); var simpleExportColumnCosToAggregate = new List(); //NOTE: Feltöltjük adatokkal az excel-t! foreach (T row in rows) { foreach (SimpleExportColumnCo simpleExportColumnCo in simpleExportColumnCos) { PropertyInfo propertyInfo = type.GetProperty(simpleExportColumnCo.PropertyName); if (propertyInfo == null) { throw new NullReferenceException(string.Format(ErrorResource.Az0ValtozoErtekeNemLehetNull, nameof(propertyInfo))); } object cellValue = propertyInfo.GetValue(row); worksheet.Cells[rowNumber, simpleExportColumnCo.Index].SetCellValue(cellValue, simpleExportColumnCo.BooleanDisplayFormat, simpleExportColumnCo.AsHtml, tanevId); //NOTE: Kiemeljük azokat az oszlopokat, ahol szeretnénk(azaz megadtuk SimpleExportColumnAttribute-ban az AggregateFunction-t) az utolsó adatsor után valamilyen összegzést csinálni. if (simpleExportColumnCo.AggregateFunction != ExcelAggregateFunctionEnum.NONE) { simpleExportColumnCosToAggregate.Add(simpleExportColumnCo); } } rowNumber++; } foreach (var simpleExportColumnCo in simpleExportColumnCosToAggregate) { string columnName = CellsHelper.ColumnIndexToName(simpleExportColumnCo.Index); //NOTE: Itt állítjuk be a megjelölt oszlopokra a kiválasztott aggregációs függvényt az excel-es AGGREGATE függvénnyel. // =AGGREGATE(function_num, options, array) // - A function_num paraméter az ExcelAggregateFunctionEnum-ból jön. // - Az options = 3 - Ignorálja a rejtett sorokat, hibás értékeket, beágyazott SUBTOTAL és AGGREGATE függvényeket. // - Az array paraméter pedig beállítja az aggregálandó adatokat - Pl: H2:H54 // Azért 2-től, mert az első sorban a fejléc van, ami nem aggregálandó, a rowNumber pedig az utolsó adatsor utánra mutat. // FONTOS: AGGREGATE function is designed vertical ranges, not horizontal ranges. // https://support.microsoft.com/en-us/office/aggregate-function-43b9278e-6aa7-4f17-92b6-e19993fa26df worksheet.Cells[rowNumber, simpleExportColumnCo.Index].Formula = $"=AGGREGATE({(int)simpleExportColumnCo.AggregateFunction}, 3, {columnName}2:{columnName}{rowNumber})"; } //NOTE: Beállítjuk az oszlopok stílusát! SetColumnsStyle(worksheet, simpleExportColumnCos); } /// /// A már elkészült workbook MemoryStream összeállítása és a sheet-eken lévő oszlopok/sorok szélességének/magasságának beállítása. /// /// A már elkészült workbook, amiből MemoryStrem-et készítünk. /// Az adott kódú sheet-eken lévő adott index-ű oszlopok sortöréseinek beállításához kell. Pl.: Amikor több sorba kell törni egy adott cella értékét. public static MemoryStream GetWorkbookMemoryStream(Workbook workbook, Dictionary> sheetCodeNameAndColumnsToWrapIndexDictionary = null) { //NOTE: Beállítjuk a default style-t. Ez van alapból az excel-ben. Style style = InitializeDefaultStyle(workbook.CreateStyle()); workbook.DefaultStyle = style; foreach (Worksheet worksheet in workbook.Worksheets) { //NOTE: Beállítjuk a cella magasságokat és szélességeket. //FONTOS: Hogy ebben a sorrendben történjen, az esetleges text wrap-ok miatt, amikor sortörések vannak a cellákban. worksheet.AutoFitRows(); worksheet.AutoFitColumns(); foreach (Column column in worksheet.Cells.Columns) { List columnsToWrapIndexList = sheetCodeNameAndColumnsToWrapIndexDictionary?.SingleOrDefault(x => x.Key == worksheet.CodeName).Value; if (columnsToWrapIndexList != null && columnsToWrapIndexList.Any() && columnsToWrapIndexList.Contains(column.Index)) { //NOTE: Erre azért van szükség, hogy ha a cellákban van Environment.NewLine és be van állítva IsTextWrapped = true, akkor AutoFitColumns szavanként fogja törni a szöveget. // Viszont, ha kiszélesítjük, majd úgy hívjuk meg az AutoFitColumn-ot, akkor a sortörésekig állítja be a szélességet. worksheet.Cells.SetColumnWidth(column.Index, 254.86); worksheet.AutoFitColumn(column.Index); //NOTE: Miután beállítottuk a szélességet, az Aspose valamiért rövidebbre vágja a wrap-olt sorokat és emiatt plusz sortörések jelenhetnek meg hibásan. // Ezért hozzáadunk 5-öt a már beállított szélességhez és így jól fog megjelenni. Extrém széles/hosszú szövegnél jöhet csak elő a probléma, // mivel az excel, a sortöréseket, valamiért arányosan hosszabbított szélességgel tudja csak rendesen megjeleníteni. De max 150 széles legyen. double columnWidth = worksheet.Cells.GetColumnWidth(column.Index); worksheet.Cells.SetColumnWidth(column.Index, columnWidth + 5 > 150 ? 150 : columnWidth + 5); } //Note: Erre azért van szükség, hogyha túl szélesek lennék az oszlopok, akkor max 150 széles lehessen, hogy ne tolja nagyon szét az excel-t. if (column.Width > 150) { column.Width = 150; } } } var memorystream = new MemoryStream(); workbook.Save(memorystream, SaveFormat.Xlsx); memorystream.Position = 0; return memorystream; } /// /// Törzsadatlista beszúrása az excelbe külön sheet-eken. /// /// A workbook, amiben létrehozzuk a törzsadatlista sheet-eket. /// A Co lista, ami leírja az oszlopok tulajdonságait/viselkedéseit, amik alapján a törzsadatlistákat beállítjuk. /// Az adott worksheet-hez tartozó ValidationCollection, a lenyílólista beállításához. private static void CreateDropDownColumnSourceSheets(Workbook workbook, List simpleExportColumnCos, ValidationCollection validationCollection) { foreach (var simpleExportColumnCo in simpleExportColumnCos) { if (simpleExportColumnCo.IsDropDownColumn) { string safeWorksheetName = CellsHelper.CreateSafeSheetName(simpleExportColumnCo.DropDownColumnSourceSheetGroupName); IList dropDownColumnSource = simpleExportColumnCo.DropDownColumnSource; CreateDropDownColumnSourceSheet(workbook, safeWorksheetName, dropDownColumnSource); var cellArea = new CellArea(); cellArea.StartColumn = cellArea.EndColumn = simpleExportColumnCo.Index; cellArea.StartRow = 1; cellArea.EndRow = Constants.General.MaxRowNumberXlsx - 1; Aspose.Cells.Validation validation = validationCollection[validationCollection.Add(cellArea)]; validation.Type = ValidationType.List; validation.Operator = OperatorType.None; validation.InCellDropDown = true; validation.Formula1 = $"={safeWorksheetName.RemoveSpecialCharacters()}"; validation.ShowError = false; } } } /// /// Fejléc sor feltöltése és a stílusának beállítása. /// /// A worksheet, aminek a worksheet, aminek a fejléc sorát beállítjuk. /// A Co lista, ami leírja az oszlopok tulajdonságait/viselkedéseit, amik alapján a fejléceket beállítjuk. private static void CreateWorksheetHeaders(this Worksheet worksheet, List simpleExportColumnCos) { Style style = InitializeDefaultHeaderStyle(); foreach (SimpleExportColumnCo simpleExportColumnCo in simpleExportColumnCos) { int columnIndex = simpleExportColumnCo.Index; worksheet.Cells[0, columnIndex].Value = simpleExportColumnCo.HeaderName; worksheet.Cells[0, columnIndex].SetStyle(style); } } /// /// Törzsadatlista beszúrása az excelbe külön sheet-en. /// /// A workbook, amiben létrehozzuk a törzsadatlista sheet-et. /// A sheet neve, amibe beszúrjuk a törzsadatlistát. /// A törzsadatlista, amit beszúrúnk a külön sheet-be. private static void CreateDropDownColumnSourceSheet(Workbook workbook, string worksheetName, IList dropDownColumnSource) { if (workbook.Worksheets[worksheetName] != null) { return; } Worksheet validationWorksheet = workbook.Worksheets.Add(worksheetName); Range range = validationWorksheet.Cells.CreateRange(0, 0, Math.Max(dropDownColumnSource.Count, 1), 1); range.Name = worksheetName.RemoveSpecialCharacters(); for (int index = 0; index < dropDownColumnSource.Count; index++) { string item = dropDownColumnSource[index]; range[index, 0].PutValue(item); } } /// /// Beállítjuk a cella értékét a bejövő stílus alapján. /// /// Az érték típusa, ami alapján formázva beállítjuk a cella értékét. /// A cella, aminek beállítjuk az értékét. /// Az érték, amit beállítunk a cellának, típus szerint formázva. /// Ha az oszlop bool típusú, akkor annak a megjelenítéséhez használható paraméter. private static void SetCellValue(this Cell cell, T value, BooleanDisplayFormatEnum booleanDisplayFormatEnum, bool asHtml, int tanevId) { switch (value) { case string nullableStringValue: var stringValue = !string.IsNullOrWhiteSpace(nullableStringValue) ? nullableStringValue : string.Empty; if (asHtml) { cell.HtmlString = stringValue; } else { cell.Value = stringValue; } break; case int intValue: cell.Value = intValue; break; case decimal decimalValue: cell.Value = decimalValue; break; case double doubleValue: cell.Value = doubleValue; break; case DateTime dateValue: cell.Value = dateValue; break; case bool boolvalue: cell.Value = boolvalue.GetDisplayName(booleanDisplayFormatEnum); break; case Enum enumValue: cell.Value = enumValue.GetDisplayName(tanevId); break; default: cell.Value = value != null ? value.ToString() : string.Empty; break; } } /// /// Beállítjuk a worksheet oszlopainak a stílusait. /// /// A worksheet, aminek a worksheet, aminek az oszlopainak a stílusait állítjuk. /// A Co lista, ami leírja az oszlopok tulajdonságait/viselkedéseit, amik alapján a stílusokat állítjuk. private static void SetColumnsStyle(Worksheet worksheet, List simpleExportColumnCos) { //NOTE: Beállítjuk az oszlopok stílusát! foreach (SimpleExportColumnCo simpleExportColumnCo in simpleExportColumnCos) { Style columnStyle = InitializeDefaultStyle(); Type columnType = simpleExportColumnCo.Type; if (columnType == typeof(string)) { columnStyle.Number = 49; //NOTE: Text (https://docs.aspose.com/display/cellsnet/Data+Formatting) } else if (columnType == typeof(int)) { columnStyle.Number = 1; //NOTE: Decimal 0 (https://docs.aspose.com/display/cellsnet/Data+Formatting) } else if (columnType == typeof(int?)) { columnStyle.Number = 1; //NOTE: Decimal 0 (https://docs.aspose.com/display/cellsnet/Data+Formatting) } else if (columnType == typeof(decimal)) { columnStyle.Custom = GetDecimalCustom(simpleExportColumnCo.DecimalDigitCount); } else if (columnType == typeof(decimal?)) { columnStyle.Custom = GetDecimalCustom(simpleExportColumnCo.DecimalDigitCount); } else if (columnType == typeof(double)) { columnStyle.Custom = GetDecimalCustom(simpleExportColumnCo.DecimalDigitCount); } else if (columnType == typeof(double?)) { columnStyle.Custom = GetDecimalCustom(simpleExportColumnCo.DecimalDigitCount); } else if (columnType == typeof(DateTime)) { columnStyle.Custom = string.IsNullOrWhiteSpace(simpleExportColumnCo.DateTimeToStringPattern) ? Constants.ToStringPattern.HungarianDate : simpleExportColumnCo.DateTimeToStringPattern; } else if (columnType == typeof(DateTime?)) { columnStyle.Custom = string.IsNullOrWhiteSpace(simpleExportColumnCo.DateTimeToStringPattern) ? Constants.ToStringPattern.HungarianDate : simpleExportColumnCo.DateTimeToStringPattern; } else if (columnType == typeof(bool)) { columnStyle.Number = 0; //NOTE: General (https://docs.aspose.com/display/cellsnet/Data+Formatting) } else if (columnType == typeof(bool?)) { columnStyle.Number = 0; //NOTE: General (https://docs.aspose.com/display/cellsnet/Data+Formatting) } else if (columnType == typeof(Enum)) { columnStyle.Number = 0; //NOTE: General (https://docs.aspose.com/display/cellsnet/Data+Formatting) } else { columnStyle.Number = 0; //NOTE: General (https://docs.aspose.com/display/cellsnet/Data+Formatting) } worksheet.Cells.Columns[simpleExportColumnCo.Index].ApplyStyle(columnStyle, new StyleFlag { All = true }); } Style defaultHeaderStyle = InitializeDefaultHeaderStyle(); //NOTE: Beállítjuk a header-ök(azaz az első sor) stílusát, mivel ezek eltérnek az adott osztloptól! foreach (SimpleExportColumnCo simpleExportColumnCo in simpleExportColumnCos) { worksheet.Cells[0, simpleExportColumnCo.Index].SetStyle(defaultHeaderStyle); } } /// /// Visszaadjuk a stílusnak decimalDigitCount által tizedesjegyekkel formázott custom-ot. /// https://docs.aspose.com/display/cellsnet/Data+Formatting /// /// Az excel-ben megjelenő tizedes jegyek számát határozza meg. private static string GetDecimalCustom(int? decimalDigitCount) { var custom = "# ##0"; if (decimalDigitCount.IsNotNullAndPositive()) { //NOTE: Az IsNotNullAndPositive vizsgálat miatt a decimalDigitCount nem lehet soha null! // ReSharper disable once PossibleInvalidOperationException custom += $".{new string('0', decimalDigitCount.Value)}"; } return custom; } /// /// A cellák default stílusának inicializálása. /// /// A stílus, aminek bizonyos property-jeit módosítjuk a default értékekre. Ha null, akkor új stílust hozunk létre. private static Style InitializeDefaultStyle(Style style = null) { if (style == null) { var cellFactory = new CellsFactory(); style = cellFactory.CreateStyle(); } style.Font.Name = "Calibri"; style.Font.Size = 11; return style; } /// /// A header cellák default stílusának inicializálása. /// /// A stílus, aminek bizonyos property-jeit módosítjuk a default értékekre. Ha null, akkor új stílust hozunk létre. private static Style InitializeDefaultHeaderStyle(Style style = null) { if (style == null) { var cellFactory = new CellsFactory(); style = cellFactory.CreateStyle(); } style = InitializeDefaultStyle(style); style.Number = 0; //NOTE: General (https://docs.aspose.com/display/cellsnet/Data+Formatting) style.VerticalAlignment = TextAlignmentType.Center; style.HorizontalAlignment = TextAlignmentType.Center; style.Font.IsBold = Constants.Export.HeaderIsBold; style.ForegroundColor = Constants.Export.HeaderColor; style.Pattern = BackgroundType.Solid; return style; } public static void EgyediSzovegesOszlopFormazas(this Worksheet worksheet, int column) { Style columnStyle = SimpleExportLogic.InitializeDefaultStyle(); columnStyle.Number = 49; //NOTE: Text (https://docs.aspose.com/display/cellsnet/Data+Formatting) worksheet.Cells.Columns[column].ApplyStyle(columnStyle, new StyleFlag { FontName = true, FontSize = true }); Style defaultHeaderStyle = SimpleExportLogic.InitializeDefaultHeaderStyle(); worksheet.Cells[0, column].SetStyle(defaultHeaderStyle); } } }