Skip to content

Commit

Permalink
Created posibility to export a list of basic objects as excel. (#84)
Browse files Browse the repository at this point in the history
Co-authored-by: Mitac Daniel <[email protected]>
  • Loading branch information
Dmitac and Mitac Daniel authored Jun 22, 2020
1 parent dc7bd8a commit da5af1c
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 31 deletions.
88 changes: 62 additions & 26 deletions src/Tools/Export/NBB.Exporter.Excel/ExcelDataExport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@ public class ExcelDataExport<T> : IAbstractDataExport<T> where T : class
{
private const string DefaultSheetName = "Sheet1";

/// <summary>
/// Exports a list of objects of a type as excel sheet.
/// </summary>
/// <param name="exportData">The data to be exported.</param>
/// <param name="properties">Additional Excel sheet properties.</param>
/// <param name="headers">The header name for each column.</param>
/// <returns></returns>
public Stream Export(List<T> exportData, Dictionary<string, string> properties = null, List<string> headers = null)
{
if (exportData == null)
throw new ArgumentNullException("exportData");

var sheetName = properties != null && properties.ContainsKey("SheetName") ? properties["SheetName"] : DefaultSheetName;
var types = new List<string>();

var excelHeaders = headers ?? new List<string>();
var hasHeaders = excelHeaders.Any();

Expand All @@ -41,7 +46,48 @@ public Stream Export(List<T> exportData, Dictionary<string, string> properties =
var name = Regex.Replace(prop.Name, "([A-Z])", " $1").Trim(); //space separated
excelHeaders.Add(name);
}



var exportDataList = new List<List<object>>();

for (var i = 0; i < exportData.Count; i++)
{
var exportDataItem = new List<object>();
var item = exportData[i];
for (var j = 0; j < excelHeaders.Count; j++)
{
var prop = props[j];
var currentCellValue = prop.GetValue(item) ?? DBNull.Value;
exportDataItem.Add(currentCellValue);
}

exportDataList.Add(exportDataItem);
}

return ExportFromListOfObjects(exportDataList, types, excelHeaders, properties);
}

/// <summary>
/// Exports a list of basic objects as excel sheet.
/// </summary>
/// <param name="exportData">The data to be exported.</param>
/// <param name="columnTypes">The types for each column. Supported types: string, int, double, datetime.</param>
/// <param name="headers">The header name for each column.</param>
/// <param name="properties">Additional Excel sheet properties.</param>
/// <returns></returns>
public Stream ExportFromListOfObjects(List<List<object>> exportData, List<string> columnTypes, List<string> headers, Dictionary<string, string> properties = null)
{
if (exportData == null)
throw new ArgumentNullException("exportData");

if (columnTypes == null)
throw new ArgumentNullException("columnTypes");

if (columnTypes == null)
throw new ArgumentNullException("headers");

var sheetName = properties != null && properties.ContainsKey("SheetName") ? properties["SheetName"] : DefaultSheetName;

var workbook = new XSSFWorkbook(); //Creating New Excel object
var sheet = workbook.CreateSheet(sheetName); //Creating New Excel Sheet object

Expand All @@ -50,47 +96,46 @@ public Stream Export(List<T> exportData, Dictionary<string, string> properties =
headerFont.IsBold = true;
headerStyle.SetFont(headerFont);


//Header
var header = sheet.CreateRow(0);
for (var i = 0; i < excelHeaders.Count; i++)
for (var i = 0; i < headers.Count; i++)
{
var cell = header.CreateCell(i);
cell.SetCellValue(excelHeaders[i]);
cell.SetCellValue(headers[i]);
cell.CellStyle = headerStyle;
}

for (var i = 0; i < exportData.Count; i++)
{
var sheetRow = sheet.CreateRow(i + 1);
var item = exportData[i];
for (var j = 0; j < excelHeaders.Count; j++)

for (var j = 0; j < headers.Count; j++)
{
var row = sheetRow.CreateCell(j);
var prop = props[j];
var prop = item[j];

var type = types[j].ToLower();
var currentCellValue = prop.GetValue(item) ?? DBNull.Value;
var type = columnTypes[j].ToLower();

if (currentCellValue != null &&
!string.IsNullOrEmpty(Convert.ToString(currentCellValue)))
if (prop != null &&
!string.IsNullOrEmpty(Convert.ToString(prop)))
{
switch (type)
{
case "string":
row.SetCellValue(Convert.ToString(currentCellValue));
row.SetCellValue(Convert.ToString(prop));
break;
case "int32":
row.SetCellValue(Convert.ToInt32(currentCellValue));
row.SetCellValue(Convert.ToInt32(prop));
break;
case "double":
row.SetCellValue(Convert.ToDouble(currentCellValue));
row.SetCellValue(Convert.ToDouble(prop));
break;
case "datetime":
row.SetCellValue(Convert.ToDateTime(currentCellValue));
row.SetCellValue(Convert.ToDateTime(prop));
break;
default:
row.SetCellValue(Convert.ToString(currentCellValue));
row.SetCellValue(Convert.ToString(prop));
break;
}
}
Expand All @@ -101,15 +146,6 @@ public Stream Export(List<T> exportData, Dictionary<string, string> properties =
}
}

// this will cause loading errors on linux.
// "Unable to load shared library 'libdl' or one of its dependencies.
// In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable:
// liblibdl: cannot open shared object file
//for (var i = 0; i < excelHeaders.Count; i++)
//{
// sheet.AutoSizeColumn(i);
//}

using (var memoryStream = new MemoryStream())
{
workbook.Write(memoryStream, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void Should_Generate_excel()

var exporter = new ExcelDataExport<Customer>();
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "excel1.xlsx");


//Act
var stream = exporter.Export(list, new Dictionary<string, string>(), null);
Expand All @@ -46,7 +46,7 @@ public void Should_Generate_excel()

var fileExistsAndNotEmpty = File.Exists(filePath) && new FileInfo(filePath).Length > 0;

if(File.Exists(filePath))
if (File.Exists(filePath))
File.Delete(filePath);

//Assert
Expand All @@ -69,7 +69,7 @@ public void Should_Generate_excel_with_custom_headers()
var exporter = new ExcelDataExport<Customer>();

//Act

var stream = exporter.Export(list, new Dictionary<string, string>(), headers);
using (var fileStream = File.Create(filePath))
{
Expand All @@ -78,8 +78,8 @@ public void Should_Generate_excel_with_custom_headers()
}

var fileExistsAndNotEmpty = File.Exists(filePath) && new FileInfo(filePath).Length > 0;
if(File.Exists(filePath))

if (File.Exists(filePath))
File.Delete(filePath);

//Assert
Expand All @@ -88,6 +88,53 @@ public void Should_Generate_excel_with_custom_headers()
stream.Length.Should().BeGreaterThan(0);
fileExistsAndNotEmpty.Should().BeTrue();
}
[Fact]
public void Should_Generate_excel_from_object_list()
{
var numberOfElements = 10;
var exportDataList = new List<List<object>>();
for (var i = 0; i < numberOfElements; i++)
{
var list = new List<object>();
var id = i;
var name = "Customer " + i;

list.Add(id);
list.Add(name);
exportDataList.Add(list);
}

var headers = new List<string>
{
"ID",
"Nume"
};
var types = new List<string>
{
"int",
"string"
};
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "excel3.xlsx");
var exporter = new ExcelDataExport<Customer>();

//Act
var stream = exporter.ExportFromListOfObjects(exportDataList, types, headers);
using (var fileStream = File.Create(filePath))
{
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(fileStream);
}

var fileExistsAndNotEmpty = File.Exists(filePath) && new FileInfo(filePath).Length > 0;

if (File.Exists(filePath))
File.Delete(filePath);

//Assert

stream.Should().NotBeNull();
stream.Length.Should().BeGreaterThan(0);
fileExistsAndNotEmpty.Should().BeTrue();
}
}
}

0 comments on commit da5af1c

Please sign in to comment.