public async Task AddSheet <T>(IEnumerable <T> model, string sheetName) where T : class { if (model == default) { throw new ArgumentNullException(nameof(model)); } if (string.IsNullOrWhiteSpace(sheetName)) { throw new ArgumentException(nameof(sheetName)); } await Task.Run(() => { Sheet sheet = new Sheet() { Id = WorkbookPart.GetIdOfPart(WorksheetPart), SheetId = _sheetId++, Name = sheetName }; Sheets.AppendChild(sheet); Type type = typeof(T); PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); Row headerRow = new Row(); foreach (PropertyInfo property in properties) { headerRow.AppendChild(new Cell() { DataType = CellValues.String, CellValue = new CellValue(Localization.Get(property.Name)) }); } SheetData.AppendChild(headerRow); WorkbookPart.Workbook.Save(); Type stringType = typeof(string); foreach (T value in model) { Row row = new Row(); foreach (PropertyInfo property in properties) { object propertyValue = property.GetValue(value); if (propertyValue is IEnumerable enumerable && propertyValue.GetType() != stringType) { string tempResult = string.Empty; foreach (object childResult in enumerable) { if (childResult != null) { tempResult += $"{childResult}, "; } } propertyValue = tempResult.Length > 0 ? tempResult.Substring(0, tempResult.Length - 2) : tempResult; } Cell cell = new Cell() { CellValue = new CellValue(propertyValue?.ToString() ?? string.Empty) }; if (propertyValue is long || propertyValue is ulong || propertyValue is double || propertyValue is decimal) { cell.DataType = CellValues.Number; } else if (propertyValue is bool) { cell.DataType = CellValues.Boolean; } else { cell.DataType = CellValues.String; } row.AppendChild(cell); } SheetData.AppendChild(row); WorkbookPart.Workbook.Save(); } }); }