I have an MVC5/Code-First application I'm developing using Entity Framework. Currently I'm trying to add Export to Excel functionality to output user selected properties of my INV_Assets model dynamically. Using the EPPlus Libary and Linq.Dynamic I have managed to export my data to excel, but not quite correctly.
I've gotten the Headers to export into Row 1, but I'm still having difficulty getting the data to export. Currently the data for my selected fields all comes across, but each value is exported as a long string into it's own row in Column A. For example, if I select the following fields (Status, ip_address, mac_address, note, owner, cost, po_number, and description) I get the following:
Row1: [Status][ip_address][mac_address][note][owner][cost][po_number][description]
Row2: [{Status=SIGNEDOUT, ip_address=10.10.121.25, mac_address=10.10.134.11, note=, owner=John Smith, cost=35.00, po_number=G348, description=This is a description of the item.}][][][][][][][]
Here is a visual of the output I'm currently getting in Excel:
When I set my IQueryable variable (selectStatement) as a Watch variable in VS2013 I am able to drill down into the contents, but I can't figure out how to access these contents individually in code:
Currently I use my IQueryable and load it into Excel via the EPPlus LoadFromCollection() method, but if I can figure out how to access individual contents of my IQueryable I can then set up some counters and loops to appropriately set the cells I want instead of everything dumping into ColumnA.
Can anyone assist with this? Full code for my ExportController below:
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach (var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
IQueryable selectStatement = DynamicSelectionColumns(exportFields);
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++)
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
// Place contents of IQueryable into Excel -- currently dumps selected value for each record into rows with all values for the row as a long string in ColumnA
if (selectStatement.Count() > 0)
{
ws.Cells["A2"].LoadFromCollection(selectStatement.Cast<object>(), true);
}
int cnt = 20;
foreach (var item in selectStatement)
{
ws.Cells["A" + cnt].LoadFromCollection(selectStatement.Cast<object>(), false);
cnt++;
}
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
public IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
using (var db = new InventoryTrackerContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
//string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
string select = "new ( " + string.Join(", ", fieldsForExport) + ")";
//return db.INV_Assets.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(),
return db.INV_Assets.ToList().Select(t => new DynamicColumns()
{
Id = t.Id,
Manufacturer = Convert.ToString(t.Manufacturer.manufacturer_description),
Type = t.Type.type_description,
Location = t.Location.location_room,
Vendor = t.Vendor.vendor_name,
Status = t.Status.status_description,
ip_address = t.ip_address,
mac_address = t.mac_address,
note = t.note,
owner = t.owner,
//Module = t.Module != null ? t.Module.Name : "",
cost = t.cost,
po_number = t.po_number,
description = t.description,
invoice_number = t.invoice_number,
serial_number = t.serial_number,
asset_tag_number = t.asset_tag_number,
acquired_date = t.acquired_date,
disposed_date = t.disposed_date,
verified_date = t.verified_date,
created_date = t.created_date,
created_by = t.created_by,
modified_date = t.modified_date,
modified_by = t.modified_by
}).ToList().AsQueryable().Select(select);
}
}
}
public class DynamicColumns : INV_Assets
{
public string Model { get; set; }
public string Manufacturer { get; set; }
public string Type { get; set; }
public string Location { get; set; }
public string Vendor { get; set; }
public string Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public decimal cost { get; set; }
public string po_number { get; set; }
public string description { get; set; }
public int invoice_number { get; set; }
public string serial_number { get; set; }
public string asset_tag_number { get; set; }
public DateTime? acquired_date { get; set; }
public DateTime? disposed_date { get; set; }
public DateTime? verified_date { get; set; }
public DateTime created_date { get; set; }
public string created_by { get; set; }
public DateTime? modified_date { get; set; }
public string modified_by { get; set; }
}
public enum EnumTasks
{
Model = 1,
Manufacturer = 2,
Type = 3,
Location = 4,
Vendor = 5,
Status = 6,
ip_address = 7,
mac_address = 8,
note = 9,
owner = 10,
cost = 11,
po_number = 12,
description = 13,
invoice_number = 14,
serial_number = 15,
asset_tag_number = 16,
acquired_date = 17,
disposed_date = 18,
verified_date = 19,
created_date = 20,
created_by = 21,
modified_date = 22,
modified_by = 23
}
The output you are getting in your non-header cells:
Status=SIGNEDOUT, ip_address=10.10.121.25, mac_address=10.10.134.11, note=, owner=John Smith, cost=35.00, po_number=G348, description=This is a description of the item.
looks like the object represented as property=value, separated by commas. I would guess that the object's ToString() method is overridden and creating that output.
Since you are casting your strongly typed objects to System.Object
selectStatement.Cast<object>()
that is probably the best that EPPlus can do.
Try not casting it to System.Object, e.g.
ws.Cells["A2"].LoadFromCollection(selectStatement, true);
Here's an article that shows proper use of LoadFromCollection
http://www.sitecorecleveland.com/resources/blogs-posts/easy_excel_interaction_pt5
UPDATE
The error
The type arguments for method 'OfficeOpenXml.ExcelRangeBase.LoadFromCollection(System.Collection.Generic.IEnumerable, bool)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
is telling you that you need to specify the actual type returned by the query (rather than specifying object).
ws.Cells["A2"].LoadFromCollection(selectStatement.Cast<DynamicColumns>(), true);
Related
I have taken a question and modified it to form my question. I have a query that is mapping correctly from the initial class, to the second class and elements attached to the second class (3rd) but not elements attached to the 3rd class. an example as follows.
public class Part {
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address {
public int Id { get; set; }
public string Street { get; set; }
public SiteOu Ou { get; set; }
}
public class SiteOu {
public int Id { get; set; }
public SiteOuName SiteOuN { get; set; }
}
public class SiteOuName
{
public int Id { get; set; }
public string Name { get; set; }
}
Dapper:
public void TestSplitOn()
{
var conn = new SqlConnection(#"Data Source=.\SQLEXPRESS;Integrated Security=true;Initial Catalog=db");
conn.Open();
const string sql = "select Id = 1, Name = 'My Part', " +
"Id = 2, Street = 'My Street', " +
"Id = 1, SiteOuNameId = '1'" +
"Id = 1, Name = 'My Site', " +;
var result = conn.Query<Part, Address, SiteOu, SiteOuName, Part>(sql, (part, address, siteOu, siteOuName) =>
{
part.Address = address;
address.Ou = siteOu;
SiteOu.SiteOuName = siteOuName
return part;
},
commandType: CommandType.Text
).FirstOrDefault();
}
If I remove SiteOuName from the Dapper mapping, the code works but doesn't map the SiteOuName object, but when I leave it as it is, it shows me that the address object reference is null.
As far as I can see there are couple of issues in your Dapper code.
Firstly, your query should be like;
const string sql = "select Id = 1, Name = 'My Part', " +
"Id = 2, Street = 'My Street', " +
"Id = 1, SiteOuNameId = '1'," +
"Id = 1, Name = 'My Site'";
You are missing a comma next to the SiteOuNameId = '1' and you have extra comma and '+' sign next to Name = 'My Site'
Secondly, your mapping is wrong, it should be like
part.Address = address;
address.Ou = siteOu;
siteOu.SiteOuN = siteOuName;
return part;
In your code, S is upper case which makes complier think you are using the SiteOu class.
Also, SiteOu class doesn't have a property named SiteOuName, it should be SiteOuN.
As an overview I am attempting to add Export() functionality to my application -- allowing the user to specify certain model fields and only export the values in those fields by querying with LINQ and using the EPPlus library to Export. I am attempting to implement Dynamic LINQ functionality in my MVC5/EF Code-First application based on THIS example, but not having much luck so far.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Linq.Dynamic;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
InventoryTrackerContext _db = new InventoryTrackerContext();
public static List<DynamicColumns> DynamicColumnsCollection = new List<DynamicColumns>();
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach(var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
//int cnt = 0;
//foreach(var column in exportFields)
for (int cnt = 0; cnt < 10; cnt++ )
{
DynamicColumnsCollection.Add(new DynamicColumns()
{
Id = cnt,
ip_address = "ip_address" + cnt,
mac_address = "mac_address" + cnt,
note = "note" + cnt,
owner = "owner" + cnt,
cost = "cost" + cnt,
po_number = "po_number" + cnt,
description = "description" + cnt,
invoice_number = "invoice_number" + cnt,
serial_number = "serial_number" + cnt,
asset_tag_number = "asset_tag_number" + cnt,
acquired_date = "acquired_date" + cnt,
disposed_date = "disposed_date" + cnt,
verified_date = "verified_date" + cnt,
created_date = "created_date" + cnt,
created_by = "created_by" + cnt,
modified_date = "modified_date" + cnt,
modified_by = "modified_by" + cnt
});
}
//var selectStatement = DynamicSelectionColumns(exportFields);
IQueryable collection = DynamicSelectionColumns(new List<string>() {
"id",
"owner",
"note"
});
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++ )
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
// Process data from [collectin] into Excel???
ws.Cells["A2"].LoadFromCollection(collection.ToString());
// ws.Cells["A2"].LoadFromCollection(selectStatement.ToString());
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
public IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
using (var db = new InventoryTrackerContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
//var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString());
////string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
//string select = "new ( " + string.Join(", ", fieldsForExport) + ")";
////return db.INV_Assets.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(),
if (!fieldsForExport.Any())
{
return null;
}
string select = string.Format("new ( {0} )", string.Join(", ", fieldsForExport.ToArray()));
var collection = DynamicColumnsCollection.Select(t => new DynamicColumns()
{
Id = t.Id,
//Manufacturer = Convert.ToString(t.Manufacturer.manufacturer_description),
//Type = t.Type.type_description,
//Location = t.Location.location_room,
//Vendor = t.Vendor.vendor_name,
//Status = t.Status.status_description,
ip_address = t.ip_address,
mac_address = t.mac_address,
note = t.note,
owner = t.owner,
cost = t.cost,
po_number = t.po_number,
description = t.description,
invoice_number = t.invoice_number,
serial_number = t.serial_number,
asset_tag_number = t.asset_tag_number,
acquired_date = t.acquired_date,
disposed_date = t.disposed_date,
verified_date = t.verified_date,
created_date = t.created_date,
created_by = t.created_by,
modified_date = t.modified_date,
modified_by = t.modified_by
}).ToList().AsQueryable().Select(select);
return collection;
}
}
}
public class DynamicColumns : INV_Assets
{
public string Model { get; set; }
public string Manufacturer { get; set; }
public string Type { get; set; }
public string Location { get; set; }
public string Vendor { get; set; }
public string Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public string cost { get; set; }
public string po_number { get; set; }
public string description { get; set; }
public string invoice_number { get; set; }
public string serial_number { get; set; }
public string asset_tag_number { get; set; }
public string acquired_date { get; set; }
public string disposed_date { get; set; }
public string verified_date { get; set; }
public string created_date { get; set; }
public string created_by { get; set; }
public string modified_date { get; set; }
public string modified_by { get; set; }
}
public enum EnumTasks
{
Model = 1,
Manufacturer = 2,
Type = 3,
Location = 4,
Vendor = 5,
Status = 6,
ip_address = 7,
mac_address = 8,
note = 9,
owner = 10,
cost = 11,
po_number = 12,
description = 13,
invoice_number = 14,
serial_number = 15,
asset_tag_number = 16,
acquired_date = 17,
disposed_date = 18,
verified_date = 19,
created_date = 20,
created_by = 21,
modified_date = 22,
modified_by = 23
}
//https://stackoverflow.com/questions/5796151/export-model-data-to-excel-mvc
//https://landokal.wordpress.com/2011/04/28/asp-net-mvc-export-to-excel-trick/
}
My code is exporting my selected columns values from my MultiSelectList on my View into Row 1 of the Excel spreadsheet, but I have something amiss with my dynamic linq querying as the data that gets output is simply the value 0 in A2:A180 no matter how many fields I specify for output.
Can anyone with more experience or who has used System.Linq.Dynamic weigh in on this?
Here is something that I am using for some time:
public class ExcelExportHelper
{
public static string ExcelContentType { get { return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; } }
public static DataTable ToDataTable<T>(List<T> data)
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
//table.Columns.Add(prop.Name, prop.PropertyType);
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); // to avoid nullable types
}
object[] values = new object[props.Count];
foreach (T item in data)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = props[i].GetValue(item);
}
table.Rows.Add(values);
}
return table;
}
public static byte[] ExportExcel(DataTable dt, string Heading = "", params string[] IgnoredColumns)
{
byte[] result = null;
using (ExcelPackage pck = new ExcelPackage())
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Exported Data");
int StartFromRow = String.IsNullOrEmpty(Heading) ? 1: 3;
// add the content into the Excel file
ws.Cells["A" + StartFromRow].LoadFromDataTable(dt, true);
// autofit width of cells with small content
int colindex = 1;
foreach (DataColumn col in dt.Columns)
{
ExcelRange columnCells = ws.Cells[ws.Dimension.Start.Row, colindex, ws.Dimension.End.Row, colindex];
int maxLength = columnCells.Max(cell => cell.Value.ToString().Count());
if (maxLength < 150)
ws.Column(colindex).AutoFit();
colindex++;
}
// format header - bold, yellow on black
using (ExcelRange r = ws.Cells[StartFromRow, 1, StartFromRow, dt.Columns.Count])
{
r.Style.Font.Color.SetColor(System.Drawing.Color.Yellow);
r.Style.Font.Bold = true;
r.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
r.Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.Black);
}
// format cells - add borders
using (ExcelRange r = ws.Cells[StartFromRow + 1, 1, StartFromRow + dt.Rows.Count, dt.Columns.Count])
{
r.Style.Border.Top.Style = ExcelBorderStyle.Thin;
r.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
r.Style.Border.Left.Style = ExcelBorderStyle.Thin;
r.Style.Border.Right.Style = ExcelBorderStyle.Thin;
r.Style.Border.Top.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Bottom.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Left.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Right.Color.SetColor(System.Drawing.Color.Black);
}
// removed ignored columns
for (int i = dt.Columns.Count - 1; i >= 0; i--)
{
if (IgnoredColumns.Contains(dt.Columns[i].ColumnName))
{
ws.DeleteColumn(i + 1);
}
}
// add header and an additional column (left) and row (top)
if (!String.IsNullOrEmpty(Heading))
{
ws.Cells["A1"].Value = Heading;
ws.Cells["A1"].Style.Font.Size = 20;
ws.InsertColumn(1, 1);
ws.InsertRow(1, 1);
ws.Column(1).Width = 5;
}
result = pck.GetAsByteArray();
}
return result;
}
public static byte[] ExportExcel<T>(List<T> data, string Heading = "", params string[] IgnoredColumns)
{
return ExportExcel(ToDataTable<T>(data), Heading, IgnoredColumns);
}
}
With these you can export a list of objects or a datatable to an Excel file. Additionally, you can specify a header and columns/properties to be ignored (like ID). Also, there are some formatting added and also small cells will auto fit in width.
Using this code you can use this in your controller action that is expecting a FileResult:
byte[] filecontent = ExcelExportHelper.ExportExcel(...);
return File(filecontent, ExcelExportHelper.ExcelContentType, "FileName.xlsx");
I hope this helps!
As an overview I am attempting to add Export() functionality to my application -- allowing the user to specify certain model fields and only export the values in those fields by querying with LINQ and using the EPPlus library to Export. I am attempting to implement Dynamic LINQ functionality in my MVC5/EF Code-First application based on THIS example, but seem to be missing some things to get it working or not understanding something.
First I added a new class file to my main project folder called DynamicLibrary.cs. When I download the .zip HERE, I "believe" the code I wanted was the Dynamic.cs file code which I copied into DynamicLibrary.cs in my project. Doing this allowed me to reference using System.Linq.Dynamic in my project.
Now I'm stuck trying to figure out how to setup the rest for Dynamic LINQ.
In my ExportController within the namespace InventoryTracker.Controllers {} but outside the public class ExportController : Controller { } I added the example code based upon the fields in my INV_Assets model I am attempting to Export:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Linq.Dynamic;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
InventoryTrackerContext _db = new InventoryTrackerContext();
// GET: Export
public ActionResult Index()
{
ExportAssetsViewModel expViewMod = new ExportAssetsViewModel();
return View(expViewMod);
}
public ActionResult Export()
{
GridView gv = new GridView();
gv.DataSource = _db.INV_Assets.ToList();
gv.DataBind();
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=InventoryAssets-" + DateTime.Now + ".xls");
Response.ContentType = "application/ms-excel";
Response.Charset = "";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
gv.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
return RedirectToAction("StudentDetails");
}
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach(var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++ )
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
// INVALID - Need to query table INV_Assets for all values of selected fields and insert into appropriate columns.
if (exportFields.Count() > 0)
{
var exportAssets = from ia in _db.INV_Assets
select new {
ia.ip_address,
}
ws.Cells["A2"].LoadFromCollection(exportFields);
}
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
}
public class DynamicColumns : INV_Assets
{
//public int Id { get; set; }
//public int Model_Id { get; set; }
public virtual INV_Models Model { get; set; }
//public int Manufacturer_Id { get; set; }
public virtual INV_Manufacturers Manufacturer { get; set; }
//public int Type_Id { get; set; }
public virtual INV_Types Type { get; set; }
//public int Location_Id { get; set; }
public virtual INV_Locations Location { get; set; }
//public int Vendor_Id { get; set; }
public virtual INV_Vendors Vendor { get; set; }
//public int Status_Id { get; set; }
public virtual INV_Statuses Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public decimal cost { get; set; }
public string po_number { get; set; }
public string description { get; set; }
public int invoice_number { get; set; }
public string serial_number { get; set; }
public string asset_tag_number { get; set; }
public DateTime? acquired_date { get; set; }
public DateTime? disposed_date { get; set; }
public DateTime? verified_date { get; set; }
public DateTime created_date { get; set; }
public string created_by { get; set; }
public DateTime? modified_date { get; set; }
public string modified_by { get; set; }
}
public enum EnumTasks
{
Model = 1,
Manufacturer = 2,
Type = 3,
Location = 4,
Vendor = 5,
Status = 6,
ip_address = 7,
mac_address = 8,
note = 9,
owner = 10,
cost = 11,
po_number = 12,
description = 13,
invoice_number = 14,
serial_number = 15,
asset_tag_number = 16,
acquired_date = 17,
disposed_date = 18,
verified_date = 19,
created_date = 20,
created_by = 21,
modified_date = 22,
modified_by = 23
}
public IQueryable DynamicSelectionColumns()
{
using (var db = new TrackerDataContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
return db.Task.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(), ActualTime = t.ActualTime, AssignedBy = t.AssignedBy.ToString(), AssignedDate = t.AssignedDate, AssignedTo = t.AssignedTo.ToString(), CreatedDate = t.CreatedDate, Details = t.Details, EstimatedTime = t.EstimatedTime, FileName = t.FileName, LogWork = t.LogWork, Module = t.Module != null ? t.Module.Name : "", Priority = t.Priority != null ? t.Priority.Name : "", Project = t.Project != null ? t.Project.Name : "", ResolveDate = t.ResolveDate, Status = t.Status != null ? t.Status.Name : "", Subject = t.Subject, TaskType = t.TaskType != null ? t.TaskType.Type : "", Version = t.Version != null ? t.Version.Name : "" }).ToList().AsQueryable().Select(select);
}
}
}
I am not 100% sure this is set up in the right location. The last method below has 5 errors:
IQueryable - Expected class, delegate, enum, interface, or struct.
InventoryTrackerContext - Expected class, delegate, enum, interface, or struct.
DynamicColumns() - Expected class, delegate, enum, interface, or struct.
Closing } for public IQueryable DynamicSelectionColumns() - Type or namespace definition, or end-of-file expected.
Closing } for namespace InventoryTracker.Controllers - Type or namespace definition, or end-of-file expected.
public IQueryable DynamicSelectionColumns()
{
using (var db = new InventoryTrackerContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
return db.Task.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(), ActualTime = t.ActualTime, AssignedBy = t.AssignedBy.ToString(), AssignedDate = t.AssignedDate, AssignedTo = t.AssignedTo.ToString(), CreatedDate = t.CreatedDate, Details = t.Details, EstimatedTime = t.EstimatedTime, FileName = t.FileName, LogWork = t.LogWork, Module = t.Module != null ? t.Module.Name : "", Priority = t.Priority != null ? t.Priority.Name : "", Project = t.Project != null ? t.Project.Name : "", ResolveDate = t.ResolveDate, Status = t.Status != null ? t.Status.Name : "", Subject = t.Subject, TaskType = t.TaskType != null ? t.TaskType.Type : "", Version = t.Version != null ? t.Version.Name : "" }).ToList().AsQueryable().Select(select);
}
}
Can anyone with more experience in this kind of thing weigh-in? I also checked out ScottGu's Blog, but seem to be missing or not understanding something.
EDIT:
REDACTED FOR SPACE
EDIT2:
Using the return from DynamicSelectionColumns() into my variable selectStatement, I have the following coded:
public IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
using (var db = new InventoryTrackerContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
//string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
string select = "new ( " + string.Join(", ", fieldsForExport) + ")";
//return db.INV_Assets.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(),
return db.INV_Assets.ToList().Select(t => new DynamicColumns() {
Id = t.Id,
Manufacturer = Convert.ToString(t.Manufacturer.manufacturer_description),
Type = t.Type.type_description,
Location = t.Location.location_room,
Vendor = t.Vendor.vendor_name,
Status = t.Status.status_description,
ip_address = t.ip_address,
mac_address = t.mac_address,
note = t.note,
owner = t.owner,
//Module = t.Module != null ? t.Module.Name : "",
cost = t.cost,
po_number = t.po_number,
description = t.description,
invoice_number = t.invoice_number,
serial_number = t.serial_number,
asset_tag_number = t.asset_tag_number,
acquired_date = t.acquired_date,
disposed_date = t.disposed_date,
verified_date = t.verified_date,
created_date = t.created_date,
created_by = t.created_by,
modified_date = t.modified_date,
modified_by = t.modified_by
}).ToList().AsQueryable().Select(select);
}
}
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach(var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
var selectStatement = DynamicSelectionColumns(exportFields);
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++ )
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
if (selectStatement.Count() > 0)
{
ws.Cells["A2"].LoadFromCollection(selectStatement.ToString());
}
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
This yields an Excel output with columns [ip_address], [mac_address], [note], [owner], and [cost] (the fields I selected), but no data. Instead of data, I get 251 rows of 0 in column A and nothing in the others.
How do I implement the dynamic select query results into my Excel spreadsheet?
EDIT3:
Attempting ThulasiRam's suggestion (ExportController below):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Linq.Dynamic;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
InventoryTrackerContext _db = new InventoryTrackerContext();
public static List<DynamicColumns> DynamicColumnsCollection = new List<DynamicColumns>();
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach(var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
int cnt = 0;
foreach(var column in exportFields)
{
DynamicColumnsCollection.Add(new DynamicColumns()
{
Id = cnt,
ip_address = "ip_address" + cnt,
mac_address = "mac_address" + cnt,
note = "note" + cnt,
owner = "owner" + cnt,
cost = "cost" + cnt,
po_number = "po_number" + cnt,
description = "description" + cnt,
invoice_number = "invoice_number" + cnt,
serial_number = "serial_number" + cnt,
asset_tag_number = "asset_tag_number" + cnt,
acquired_date = "acquired_date" + cnt,
disposed_date = "disposed_date" + cnt,
verified_date = "verified_date" + cnt,
created_date = "created_date" + cnt,
created_by = "created_by" + cnt,
modified_date = "modified_date" + cnt,
modified_by = "modified_by" + cnt
});
}
//var selectStatement = DynamicSelectionColumns(exportFields);
IQueryable collection = DynamicSelectionColumns(new List<string>() {
"id",
"owner",
"note"
});
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++ )
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
ws.Cells["A2"].LoadFromCollection(collection.ToString());
// ws.Cells["A2"].LoadFromCollection(selectStatement.ToString());
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
public IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
using (var db = new InventoryTrackerContext())
{
if (!fieldsForExport.Any())
{
return null;
}
string select = string.Format("new ( {0} )", string.Join(", ", fieldsForExport.ToArray()));
var collection = DynamicColumnsCollection.Select(t => new DynamicColumns()
{
Id = t.Id,
//Manufacturer = Convert.ToString(t.Manufacturer.manufacturer_description),
//Type = t.Type.type_description,
//Location = t.Location.location_room,
//Vendor = t.Vendor.vendor_name,
//Status = t.Status.status_description,
ip_address = t.ip_address,
mac_address = t.mac_address,
note = t.note,
owner = t.owner,
//Module = t.Module != null ? t.Module.Name : "",
cost = t.cost,
po_number = t.po_number,
description = t.description,
invoice_number = t.invoice_number,
serial_number = t.serial_number,
asset_tag_number = t.asset_tag_number,
acquired_date = t.acquired_date,
disposed_date = t.disposed_date,
verified_date = t.verified_date,
created_date = t.created_date,
created_by = t.created_by,
modified_date = t.modified_date,
modified_by = t.modified_by
}).ToList().AsQueryable().Select(select);
return collection;
}
}
public class DynamicColumns : INV_Assets
{
public string Model { get; set; }
public string Manufacturer { get; set; }
public string Type { get; set; }
public string Location { get; set; }
public string Vendor { get; set; }
public string Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public string cost { get; set; }
public string po_number { get; set; }
public string description { get; set; }
public string invoice_number { get; set; }
public string serial_number { get; set; }
public string asset_tag_number { get; set; }
public string acquired_date { get; set; }
public string disposed_date { get; set; }
public string verified_date { get; set; }
public string created_date { get; set; }
public string created_by { get; set; }
public string modified_date { get; set; }
public string modified_by { get; set; }
}
public enum EnumTasks
{
Model = 1,
Manufacturer = 2,
Type = 3,
Location = 4,
Vendor = 5,
Status = 6,
ip_address = 7,
mac_address = 8,
note = 9,
owner = 10,
cost = 11,
po_number = 12,
description = 13,
invoice_number = 14,
serial_number = 15,
asset_tag_number = 16,
acquired_date = 17,
disposed_date = 18,
verified_date = 19,
created_date = 20,
created_by = 21,
modified_date = 22,
modified_by = 23
}
What I can't figure out is where to put this relevant piece of code from their suggestion (or set it up) within my MVC application:
static void Main(string[] args)
{
IQueryable collection = DynamicSelectionColumns(new List<string>() { "id", "name" });
Console.ReadLine();
}
Any thoughts? I'm not sure how to structure the static Program() or Main() used in the example for my MVC app. In my code listed above (should I select just the note/owner field), I receive an output Excel sheet with "note" in A1, "owner" in B1, and then just the number 0 in cells A2:A180...?
The errors you're getting has nothing to do with linq or the other libraries you imported into your project.
You're declaring the function DynamicSelectionColumns in the namespace, not in the ExportController class.
After your Edit:
if your exportFields is already a list of Task columns, you can simply pass that list to DynamicSelectionColumns and have this inside:
string select = "new ( " + string.Join(", ", exportFields) + ")";
After Edit2:
Replace
ws.Cells["A2"].LoadFromCollection(selectStatement.ToString());
with
ws.Cells["A2"].LoadFromCollection(selectStatement, false);
After Edit3:
After this trial and error approaches, I decided to indeed lookup the EPPlus library you mentioned. I found out that you don't need any of this DynamicQuery. You can specify into LoadFromCollection the fields you want to show.
I didn't get to compile this (because it's your code) but It worked on my machine with fake data.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Reflection;
using OfficeOpenXml.Table;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
private InventoryTrackerContext _db = new InventoryTrackerContext();
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach (var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++)
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
var membersToShow = typeof(INV_Asset).GetMembers()
.Where(p => exportFields.Contains(p.Name))
.ToArray();
ws.Cells["A2"].LoadFromCollection(_db.INV_Assets.ToList(), false, TableStyles.None, BindingFlags.Default, membersToShow);
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
}
}
1. TaskId property not exist in DynamicColumns class.
2. Remove .Replace("_", "") from
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
3.exportFields.Count should be > 0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
namespace Dynamic
{
public class Program
{
public static List<DynamicColumns> DynamicColumnsCollection = new List<DynamicColumns>();
static Program()
{
for (int i = 0; i < 10; i++)
{
DynamicColumnsCollection.Add(new DynamicColumns() { Id = i, Name = "Name" + i, ip_address = "ip_" + i });
}
}
static void Main(string[] args)
{
IQueryable collection = DynamicSelectionColumns(new List<string>() { "id", "name" });
Console.ReadLine();
}
public class DynamicColumns
{
public int Id { get; set; }
public string Name { get; set; }
public string ip_address { get; set; }
}
public static IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
if (!fieldsForExport.Any())
return null;
string select = string.Format("new ( {0} )", string.Join(", ", fieldsForExport.ToArray()));
var collection = DynamicColumnsCollection.Select(t => new DynamicColumns()
{
Id = t.Id,
Name = t.Name,
ip_address = t.ip_address,
}).ToList().AsQueryable().Select(select);
return collection;
}
}
}
Further any problem let me know.
Regards,
Ram.S
I am attempting to add Excel Export functionality to my MVC5/Code-First Entity Framework application via the EPPlus library and System.Linq.Dynamic. On my Export View I have filled a MultiSelectList with each of my INV_Assets model properties. These then get passed into my ExportController to designate which fields of the model are to be exported.
I've gotten the Headers to export into Row 1, but I'm still having difficulty getting the data to export. Currently the data for my selected fields all comes across, but each value is exported as a long string into it's own row in Column A. For example, if I select the following fields (Status, ip_address, mac_address, note, owner, cost, po_number, and description) I get the following:
Row1: [Status][ip_address][mac_address][note][owner][cost][po_number][description]
Row2: [{Status=SIGNEDOUT, ip_address=10.10.121.25, mac_address=10.10.134.11, note=, owner=John Smith, cost=35.00, po_number=G348, description=This is a description of the item.}][][][][][][][]
Does anyone know how to break this up to where the values actually go into the correct column cells instead of as one long giant string?
Code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Linq.Dynamic;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
InventoryTrackerContext _db = new InventoryTrackerContext();
public static List<DynamicColumns> DynamicColumnsCollection = new List<DynamicColumns>();
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach (var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
IQueryable selectStatement = DynamicSelectionColumns(exportFields);
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++)
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
// Insert Data -- Currently all one long string in Column A per record
if (selectStatement.Count() > 0)
{
ws.Cells["A2"].LoadFromCollection(selectStatement.Cast<object>(), true);
}
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
public IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
using (var db = new InventoryTrackerContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
string select = "new ( " + string.Join(", ", fieldsForExport) + ")";
return db.INV_Assets.ToList().Select(t => new DynamicColumns()
{
Id = t.Id,
Manufacturer = Convert.ToString(t.Manufacturer.manufacturer_description),
Type = t.Type.type_description,
Location = t.Location.location_room,
Vendor = t.Vendor.vendor_name,
Status = t.Status.status_description,
ip_address = t.ip_address,
mac_address = t.mac_address,
note = t.note,
owner = t.owner,
//Module = t.Module != null ? t.Module.Name : "",
cost = t.cost,
po_number = t.po_number,
description = t.description,
invoice_number = t.invoice_number,
serial_number = t.serial_number,
asset_tag_number = t.asset_tag_number,
acquired_date = t.acquired_date,
disposed_date = t.disposed_date,
verified_date = t.verified_date,
created_date = t.created_date,
created_by = t.created_by,
modified_date = t.modified_date,
modified_by = t.modified_by
}).ToList().AsQueryable().Select(select);
}
}
}
public class DynamicColumns : INV_Assets
{
public string Model { get; set; }
public string Manufacturer { get; set; }
public string Type { get; set; }
public string Location { get; set; }
public string Vendor { get; set; }
public string Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public decimal cost { get; set; }
public string po_number { get; set; }
public string description { get; set; }
public int invoice_number { get; set; }
public string serial_number { get; set; }
public string asset_tag_number { get; set; }
public DateTime? acquired_date { get; set; }
public DateTime? disposed_date { get; set; }
public DateTime? verified_date { get; set; }
public DateTime created_date { get; set; }
public string created_by { get; set; }
public DateTime? modified_date { get; set; }
public string modified_by { get; set; }
}
public enum EnumTasks
{
Model = 1,
Manufacturer = 2,
Type = 3,
Location = 4,
Vendor = 5,
Status = 6,
ip_address = 7,
mac_address = 8,
note = 9,
owner = 10,
cost = 11,
po_number = 12,
description = 13,
invoice_number = 14,
serial_number = 15,
asset_tag_number = 16,
acquired_date = 17,
disposed_date = 18,
verified_date = 19,
created_date = 20,
created_by = 21,
modified_date = 22,
modified_by = 23
}
}
EDIT:
Thanks to João Silva's suggestion, the fields now come across into their own individual cells within proper selected columns:
Code:
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach (var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
var membersToShow = typeof(INV_Assets).GetMembers().Where(p => exportFields.Contains(p.Name)).ToArray();
ws.Cells["A2"].LoadFromCollection(_db.INV_Assets.ToList(), false, TableStyles.None, BindingFlags.Default, membersToShow);
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
Output:
The only issue I still have is the ForeignKey fields within my model. For example, [Status] is defined in my INV_Assets Model as:
[Required]
public int Status_Id { get; set; }
[ForeignKey("Status_Id")]
public virtual INV_Statuses Status { get; set; }
When the current export executes though, instead of getting say AVAILABLE/RECYCLED, the [Status] column in excel contains InventoryTracker.Models.INV_Statuses in every cell for each record exported.
Can anyone offer insight into how to get not only the direct INV_Assets fields exported, but the ForeignKey values for Model, Location, Status, Vendor, Manufacturer, and Type also into Excel?
You don't need the DynamicQuery. You can specify into LoadFromCollection the fields you want to show.
I didn't get to compile this (because it's your code) but It worked on my machine with fake data.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Reflection;
using OfficeOpenXml.Table;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
private InventoryTrackerContext _db = new InventoryTrackerContext();
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach (var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++)
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
var membersToShow = typeof(INV_Asset).GetMembers()
.Where(p => exportFields.Contains(p.Name))
.ToArray();
ws.Cells["A2"].LoadFromCollection(_db.INV_Assets.ToList(), false, TableStyles.None, BindingFlags.Default, membersToShow);
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
}
}
Answer Founrd Here
Added a ToString() override on each of my desired Models to ensure the value came through instead of just the object type:
public class INV_Models
{
public override string ToString()
{
return this.model_description;
}
}
public class INV_Manufacturers
{
public override string ToString()
{
return this.manufacturer_description;
}
}
public class INV_Locations
{
public override string ToString()
{
return this.location_dept + "|" + this.location_room;
}
}
public class INV_Vendors
{
public override string ToString()
{
return this.vendor_name;
}
}
public class INV_Types
{
public override string ToString()
{
return this.type_description;
}
}
public class INV_Statuses
{
public override string ToString()
{
return this.status_description;
}
}
ExportController:
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach (var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++)
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
var membersToShow = typeof(INV_Assets).GetMembers().Where(p => exportFields.Contains(p.Name)).ToArray();
ws.Cells["A2"].LoadFromCollection(_db.INV_Assets.ToList(), false, TableStyles.None, BindingFlags.Default, membersToShow);
var membersToShow = typeof(INV_Assets).GetMembers().Where(p => exportFields.Contains(p.Name)).ToArray();
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
And the output Excel file:
I have a check box list in that user can check or uncheck the check box.
Based on the selected check box I used to store that value by comma separated. Now the problem is based on selected check box I need to get that particular column alone. in "select"**
db.Tasks.OrderBy(t => t.CreatedDate).ToList()
.Select(t => new {
Id = t.Id,
PriorityId = t.ProjectId,
Priority = t.Priority,
StatusId = t.StatusId,
Status = t.Status,
EstimatedTime = t.EstimatedTime,
ActualTime = t.ActualTime,
Subject = t.Subject,
FileName = t.FileName,
AssignedTo = t.AssignedTo,
Project = t.Project
}).ToList();
if i select in check box list ActualTime, Subject, it should be like
db.Tasks.OrderBy(t => t.CreatedDate).ToList()
.Select(t => new {
Id = t.Id,
ActualTime = t.ActualTime,
Subject = t.Subject
}).ToList();
if i select in check box list Subject, FileName, AssignedTo, it should be like
db.Tasks.OrderBy(t => t.CreatedDate).ToList()
.Select(t => new {
Id = t.Id,
Subject = t.Subject,
FileName = t.FileName,
AssignedTo = t.AssignedTo
}).ToList();
the select will be dynamic based on selected check box list.
add DynamicLibrary.cs to your project.
You can get it from this link . It's a zip file that contains the dynamic link source. It's not a dll.
Originally posted on ScottGu's blog here.
for reference see this stack overflow link .
using System.Linq.Dynamic;
public class DynamicColumns : BaseEntity
{
public string User { get; set; }
public string TaskId { get; set; }
public string Project { get; set; }
public string Priority { get; set; }
public string TaskType { get; set; }
public string Version { get; set; }
public string Module { get; set; }
public string Subject { get; set; }
public string Details { get; set; }
public string FileName { get; set; }
public string Status { get; set; }
public string AssignedBy { get; set; }
public string AssignedTo { get; set; }
public int ActualTime { get; set; }
public int LogWork { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime AssignedDate { get; set; }
public DateTime ResolveDate { get; set; }
public int EstimatedTime { get; set; }
}
public enum EnumTasks
{
User = 1,
Project = 2,
Priority = 3,
TaskType = 4,
Version = 5,
Module = 6,
Subject = 7,
Details = 8,
Status = 9,
Assigned_By = 10,
Assigned_To = 11,
Created_Date = 12,
Assigned_Date = 13,
Resolve_Date = 14,
Estimated_Time = 15,
Actual_Time = 16,
LogWork = 17
}
public IQueryable DynamicSelectionColumns()
{
using (var db = new TrackerDataContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
return db.Task.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(), ActualTime = t.ActualTime, AssignedBy = t.AssignedBy.ToString(), AssignedDate = t.AssignedDate, AssignedTo = t.AssignedTo.ToString(), CreatedDate = t.CreatedDate, Details = t.Details, EstimatedTime = t.EstimatedTime, FileName = t.FileName, LogWork = t.LogWork, Module = t.Module != null ? t.Module.Name : "", Priority = t.Priority != null ? t.Priority.Name : "", Project = t.Project != null ? t.Project.Name : "", ResolveDate = t.ResolveDate, Status = t.Status != null ? t.Status.Name : "", Subject = t.Subject, TaskType = t.TaskType != null ? t.TaskType.Type : "", Version = t.Version != null ? t.Version.Name : "" }).ToList().AsQueryable().Select(select);
}
}