I'm trying to import an Excel file. This is how my Import method looks like. What I'm doing here is just adding the excel data into a data-table and converting that data-table into a dynamic list and returning it to the controller method:
public List<dynamic> ImportFile(Stream stream)
{
var productList = new List<Products>();
using (var package = new ExcelPackage(stream))
{
var currentSheet = package.Workbook.Worksheets;
var workSheet = currentSheet.First();
//Creating a DataTable
DataTable tbl = new DataTable();
bool hasHeader = true; // adjust it accordingly( i've mentioned that this is a simple approach)
//Creating the header
foreach (var firstRowCell in workSheet.Cells[1, 1, 1, workSheet.Dimension.End.Column])
{
tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
}
var startRow = hasHeader ? 2 : 1;
////Inserting the stream into DataTable
for (var rowNum = startRow; rowNum <= workSheet.Dimension.End.Row; rowNum++)
{
var wsRow = workSheet.Cells[rowNum, 1, rowNum, workSheet.Dimension.End.Column];
var row = tbl.NewRow();
foreach (var cell in wsRow)
{
row[cell.Start.Column - 1] = cell.Text;
}
tbl.Rows.Add(row);
}
//Convert datatable into dynamic list
var dynamicDt = new List<dynamic>();
foreach (DataRow row in tbl.Rows)
{
dynamic dyn = new ExpandoObject();
dynamicDt.Add(dyn);
foreach (DataColumn column in tbl.Columns)
{
var dic = (IDictionary<string, object>)dyn;
dic[column.ColumnName] = row[column];
}
}
return dynamicDt;
}
}
This is how my controller method looks like:
[HttpPost]
public ActionResult Upload(HttpPostedFileBase upload)
{
IExcelImporter reader = new ExcelImporter();
var res = new List<dynamic>();
List<Products> send = new List<Products>();
if (ModelState.IsValid)
{
if (upload != null && upload.ContentLength > 0)
{
Stream stream = upload.InputStream;
if (upload.FileName.EndsWith(".xlsx"))
{
//getting the dynamic list(returning dynamic list)
res = reader.ImportFile(stream);
//need to bind it a model-class(Products)
send = res.Select(x=>
new Products
{
ID = res.GetType().GetProperty("ID").ToString(),
Name = res.GetType().GetProperty("Name").ToString(),
//res.Select(e=>e.Price).ToString()//res.GetType().GetProperty("Price").GetValue(res, null).ToString()
}).ToList();
}
}
}
return View("Index", send);
}
Question: What I want is to bind the dynamic list to a model-class(Products). So that I can return it to the View. How do I map the dynamic list to List Products?
This is how my IExcelImporter looks like:
public interface IExcelImporter
{
List<dynamic> ImportFile(Stream stream);
}
This is how my Products Model looks like:
public class Products
{
public string ID { get; set; }
public string Name { get; set; }
public string Price { get; set; }
}
Can someone please give me an idea how to solve this. Thank you in advance.