I have the following view inside my asp.net mvc web application:, it simply display the model data inside a table and there are three check boxes at the table Colum heads to select which columns should be extracted to excel (.xls) or text (.csv) files.
The view is:-
@model MvcApplication4.Models.SelectedCustomers
@{
ViewBag.Title = "CustomerDetials";
}
<h3>Select Customers Detials</h3>
<table>
<tr>
<th>
NAME @Html.CheckBox("Name",true)
</th>
<th>
Description @Html.CheckBox("Description",true)
</th>
<th>
Address @Html.CheckBox("Address",true)
</th>
</tr>
@foreach (var item in Model.Info) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.description)
</td>
<td>
@Html.DisplayFor(modelItem => item.address)
</td>
</tr>
}
</table>
<p>
@Html.ActionLink("Back","customer","Home") |
<a href="">extract to excel</a> |
<a href="">extract to text file</a>
</p>
But can anyone provide some help on how i can accomplish the following:-
-
Develop a action methods that will return & open an excel sheet containing the SelectedCustomer model objects when the user click on the ” extract to excel ” link.
-
Develop a action methods that will return & open a .csv file containing the SelectedCustomer model objects when the user click on the ” extract to text file ” link.
-
How can i only extract the columns that have their check box “selected”.
Thanks & Best Regards
:::UPDATED:::
I have updated my view to the following:-
@model MvcApplication4.Models.SelectedCustomers
@{
ViewBag.Title = "CustomerDetials";
}
<h3>Select Customers Detials</h3>
@using (Html.BeginForm("Export", null))
{
<table>
<tr>
<th>
NAME @Html.CheckBox("IncludeName",true)
</th>
<th>
Description @Html.CheckBox("IncludeDescription",true)
</th>
<th>
Address @Html.CheckBox("IncludeAddress",true)
</th>
</tr>
@foreach (var item in Model.Info) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.description)
</td>
<td>
@Html.DisplayFor(modelItem => item.address)
</td>
</tr>
}
</table>
<p>
@Html.ActionLink("Back","customer","Home") |
<button type="submit" name="format" value="xls">extract to excel</button> |
<button type="submit" name="format" value="csv">extract to text file</button>
</p>}
Then have added the folloiwng action metthods:-
[HttpPost]
public ActionResult Export(ExportViewModel exportOptions,IEnumerable<Account> sc)
{
// var accounts = GetAccounts();
if (exportOptions.Format == "csv")
{
return sc.AsCsvResult(exportOptions);
}
else if (exportOptions.Format == "xls")
{
return sc.AsXlsResult(exportOptions);
}
throw new NotSupportedException(
string.Format("Unsupported format: {0}", exportOptions.Format)
);
}
And the following Model class:-
public abstract class ExportAccountsResult : ActionResult
{
protected ExportAccountsResult(IEnumerable<Account> accounts, ExportViewModel exportOptions)
{
this.Accounts = accounts;
this.ExportOptions = exportOptions;
}
protected IEnumerable<Account> Accounts { get; private set; }
protected ExportViewModel ExportOptions { get; private set; }
protected abstract string ContentType { get; }
protected abstract string Filename { get; }
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.ContentType = ContentType;
var cd = new ContentDisposition
{
FileName = this.Filename,
Inline = false
};
response.AddHeader("Content-Disposition", cd.ToString());
// TODO: Use a real CSV parser here such as https://github.com/JoshClose/CsvHelper/wiki/Basics
// and never roll your own parser as shown in this oversimplified
// example. Here's why: http://secretgeek.net/csv_trouble.asp
using (var writer = new StreamWriter(response.OutputStream))
{
foreach (var account in this.Accounts)
{
var values = new List<object>();
if (this.ExportOptions.IncludeName)
{
values.Add(account.Name);
}
if (this.ExportOptions.IncludeDescription)
{
values.Add(account.Description);
}
if (this.ExportOptions.IncludeAddress)
{
values.Add(account.Address);
}
writer.WriteLine(string.Join(", ", values));
}
}
}
}
}
and the following model class:-
namespace MvcApplication4.Models
{
public class ExportViewModel
{
public string Format { get; set; }
public bool IncludeName { get; set; }
public bool IncludeDescription { get; set; }
public bool IncludeAddress { get; set; }
}
}
And the folloiwng model class:-
namespace MvcApplication4.Models
{
public class CsvResult : ExportAccountsResult
{
public CsvResult(IEnumerable<Account> accounts, ExportViewModel exportOptions)
: base(accounts, exportOptions)
{
}
protected override string ContentType
{
get { return "text/csv"; }
}
protected override string Filename
{
get { return "accounts.csv"; }
}
}
}
and the folloiwng model class:-
namespace MvcApplication4.Models
{
public class XlsResult : ExportAccountsResult
{
public XlsResult(IEnumerable<Account> accounts, ExportViewModel exportOptions)
: base(accounts, exportOptions)
{
}
protected override string ContentType
{
get { return "application/vnd.ms-excel"; }
}
protected override string Filename
{
get { return "accounts.csv"; }
}
}
}
And finally the folloiwng model class:-
namespace MvcApplication4.Models
{
public class SelectedCustomers
{
public IEnumerable<Account> Info { get; set; }
}
public static class ActionResultextensions
{
public static ActionResult AsCsvResult(this IEnumerable<Account> accounts, ExportViewModel exportOptions)
{
return new CsvResult(accounts, exportOptions);
}
public static ActionResult AsXlsResult(this IEnumerable<Account> accounts, ExportViewModel exportOptions)
{
return new XlsResult(accounts, exportOptions);
}
}
}
But when i run the application i got the following exception :-
System.NullReferenceException was unhandled by user code
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=MvcApplication4
StackTrace:
at MvcApplication4.Models.ExportAccountsResult.ExecuteResult(ControllerContext context) in c:\Users\Administrator\Documents\Visual Studio 2012\Projects\MvcApplication4\MvcApplication4\Models\ExportAccountResult.cs:line 43
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
InnerException:
on this code inside the ExportAccountResult.cs:-
foreach (var account in this.Accounts)
So what might be getting wrong?
BR
You could put the records into a form and make the 2 links submit buttons. Let’s take an example. We will use CSV for both the text file and Excel file format because Excel understands CSV. If you need to apply some special formatting for the Excel export you will could use a third party library such as OpenXML.
Let’s start by defining our view models:
then we could have a controller with 2 actions – one that renders the records on the view and one that exports them:
then we define the corresponding view:
Next we implement the custom extension methods used in the controller that return the 2 custom action results:
And the last part of course is to define the
CsvResultandXlsResultcustom action results. Since we will be using CSV in both cases we could have a base class:And then we could have the 2 implementations: