Pergunta

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.pngThis is what my View displays

Foi útil?

Solução

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" />
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top