I had the same issue, that you can't create a DataTable
and therefore just dump that into a sheet.
The lack of DataTable
support in Core does force you to create strongly typed objects and then loop through and map those to the output of EPPlus.
So a very simple example is to:
// Get your data directly from EF,
// or from whatever other source into a list,
// or Enumerable of the type
List<MyEntity> data = _whateverService.GetData();
using (ExcelPackage pck = new ExcelPackage())
{
// Create a new sheet
var newSheet = pck.Workbook.Worksheets.Add("Sheet 1");
// Set the header:
newSheet.Cells["A1"].Value = "Column 1 - Erm ID?";
newSheet.Cells["B1"].Value = "Column 2 - Some data";
newSheet.Cells["C1"].Value = "Column 3 - Other data";
row = 2;
foreach (var datarow in data)
{
// Set the data:
newSheet.Cells["A" + row].Value = datarow.Id;
newSheet.Cells["B" + row].Value = datarow.Column2;
newSheet.Cells["C" + row].Value = datarow.Cilumn3;
row++;
}
}
So, you're taking an enumerable source of and strongly typed object, which you can do directly from an EF query, or a view model or anything else and then looping through to map it.
I've used this and the performance appears - to an end user - on par with the DataTable
method. I've not inspected the source, but it wouldn't surprise me if the DataTable
method is just doing the same thing internally and looping through each row.
You could create an extension method to using generics to pass in the object list and use reflection to map it correctly... Maybe I'll look at the project and see if I can contribute.
Edit to add:
In .NET Core it appears, from the GitHub issues tracker that DataTable
support is pretty low down on the priority list, and do not expect it anytime soon. I think it's also a philosophical point, as the concept is generally you try to use strongly typed objects. So, it used to be that you could run a SQL Query into a DataTable
and run with that... Now, you should run that query into a Model either directly mapped to a table with Entity Framework
via a DbSet
, or with ModelBinding
and passing a type into the query.
You then have an IQueryable<T>
which serves as your strongly typed replacement to DataTables
. To be fair to this approach, for 99% of cases it a valid and better approach... However there will always be times the lack of DataTables
will cause issues and need to be worked around!
Further Edit
In ADO.NET
you can convert a datareader
to a strongly typed list of objects:
How can I easily convert DataReader to List<T>? to name but one example. With this list you can make your mapping from there.
If you want to / have to use ASP.NET Core
that targets ASP.NET Core framework
then you'll have to do this. If you can target Net 4.5 using a Core project then you'll be able to use System.Data
and have DataTables
back - the only caveat being that you then have to use Windows servers and IIS.
Do you really need the full .Net Core
framework? Do you need to host on linux? If no, and you really need DataTables, just target the older Framework.