Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Export to CSV from MVC Controller and View displays CSV raw data on Page

Tags:

asp.net-mvc

I've just got my MVC view export to Excel working great, however, because i'm setting location.href this is leaving me with a page full of CSV data rather than the neat grid results before the user hit EXPORT button.

I'm trying to think how to change the following script to do what its doing but to leave the page alone. I tried making a call to the search to go back to server again but at runtime user see's the CSV on the webpage momentarily, which is not good.

Any ideas much appreciated, Cheers

    $(function() {
        $('#exportButton').click(function() {
            var url = $('#AbsolutePath').val() + 'Waste.mvc/Export';

            var data = {
                searchText: $('#SearchTextBox').val().toString(),
                searchTextSite: $('#SearchTextBoxSite').val().toString(),
                StartDate: $('#StartDate').val(),
                EndDate: $('#EndDate').val()
            };
            $('#ResultsList').load(url, data, function() {
                $('#LoadingGif').empty();
                location.href = url + "?searchText=" + data.searchText + "&searchTextSite=" + data.searchTextSite + "&StartDate=" + data.StartDate + "&EndDate=" + data.EndDate;
            });
            //Search(); this fixes because grid is displayed again after csv results
        });
    });

My Controller Code:

    public FileStreamResult Export(string searchText, string searchTextSite, string StartDate, string EndDate)
    {

        var searchResults = getSearchResults(searchText, searchTextSite, StartDate, EndDate);
        HttpContext.Response.AddHeader("content-disposition", "attachment; filename=Export.csv");

        var sw = new StreamWriter(new MemoryStream());

        sw.WriteLine("\"Ref\",\"Source\",\"Collected\"");
        foreach (var line in searchResults.ToList())
        {
            sw.WriteLine(string.Format("\"{0}\",\"{1}\",\"{2}\"",
                                       line.WasteId,
                                       line.SourceWasteTypeId.ToDescription(),
                                       line.CollectedDate.ToShortDateString()));
        }
        sw.Flush();
        sw.BaseStream.Seek(0, SeekOrigin.Begin);

        return new FileStreamResult(sw.BaseStream, "text/csv");
        // return File(sw.BaseStream, "text/csv", "report.csv"); Renders the same result

    }
like image 711
John Avatar asked Jul 21 '11 11:07

John


1 Answers

You could have the controller action return the CSV file as attachment (it will use the Content-Disposition: attachment; filename=report.csv HTTP header):

public ActionResult GetCsv()
{
    byte[] csvData = ...
    return File(csvData, "text/csv", "report.csv");
}

Now you can safely do a window.location.href = '/reports/getcsv'; and the user will be prompted to download the CSV report but it will stay on the same page.

like image 128
Darin Dimitrov Avatar answered Oct 26 '22 15:10

Darin Dimitrov