Reputation: 5242
I have a method which is calling my CreateAnnuityExcelSheet when pressed on a "Save button".
The method to call CreateAnnuityExcelSheet:
[HttpPost]
public ActionResult ShowAnnuityPMT(FormCollection form, string SubmitValue, string fileName)
{
//Code for finalList
if (SubmitValue == "Save")
{
CreateAnnuityExcelSheet(finalList, form, DTCyear); //When I call this method I want the user/browser to download the Excelfile created in CreateAnnuityExcelSheet
}
return PartialView("ShowDetail", finalList);
}
The method looks like this:
public void CreateAnnuityExcelSheet(List<Calculation> cList, FormCollection form, int DTCyear)
{
List<Calculation> newList = new List<Calculation>();
newList.Add(cList.First()); //Getting the values for the first row
var StartValue = newList[0].StartValue;
var radio = form["advanceOrArrears"];
string fileName = newList[0].CalculationName;
string path = @"C:\ExcelFiles\" + fileName + ".xlsx"; //Path for the file
FileInfo info = new FileInfo(path);
info.Directory.Create(); //If C:\ExcelFiles does not exist, create it
if (!info.Exists)
{
using (ExcelPackage package = new ExcelPackage(info))
{
ExcelWorksheet ws = package.Workbook.Worksheets.Add(fileName);
//Styles for the sheet
var stream = new MemoryStream();
package.SaveAs(stream);
stream.Position = 0;
byte[] bytes = stream.GetBuffer();
Response.Buffer = true;
Response.Clear();
Response.ContentType = "application/xlsx";
Response.AddHeader("content-disposition", "attachment; filename=report.xlsx");
Response.BinaryWrite(bytes);
Response.Flush();
}
The main problem is that I am creating a excelsheet on the serverside and then want to send it back to the browser for download. How can I send my package back to the browser for download?
Right now the method is returning void, should I return File? But if I do, how do I send the file with a view so the user can start downloading the Excelfile?
This is what my View displays: http://cdn.imghack.se/images/6c513c233f4ee5df36e18a428c9b8d1f.png
Upvotes: 1
Views: 1864
Reputation: 1189
Your action should return an ActionResult and if you have a stream, an easy way is to use the FilestreamResult
Notice there's a property to set the name of the file.
return new FileStreamResult(stream, "application/vnd.ms-excel")
{
FileDownloadName = "myfile.xslx"
};
Here's a sample to post the data from your form and download the generated file.
Create a model to hold the form values :
public class DownloadModel
{
public int InputA { get; set; }
public string InputB { get; set; }
}
Create a controller with two actions : one to display the form (Index) and an other to submit data and get the file (DownloadFile)
public class DownloadController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult DownloadFile(DownloadModel model)
{
// read form value via model
System.Diagnostics.Debug.WriteLine(model.InputA);
System.Diagnostics.Debug.WriteLine(model.InputB);
// assume we create an an excel stream...
MemoryStream excelStream = new MemoryStream();
return new FileStreamResult(excelStream, "application/vnd.ms-excel")
{
FileDownloadName = "myfile.xslx"
};
}
}
Set the action form in the razor view Download/Index.cshtml to the DownloadFile action
@model WebApp.Models.DownloadModel
@{
ViewBag.Title = "DownloadFile";
}
<h2>DownloadFile</h2>
@using (Html.BeginForm("DownloadFile", "Download"))
{
@Html.TextBoxFor(model => model.InputA);
@Html.TextBoxFor(model => model.InputB);
<input type="submit" value="Save" name="submitButton" />
}
Upvotes: 3