8

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

    }
0

2 Answers 2

10

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.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks, but I changed the last line of my controller to "return File(sw.BaseStream, "text/csv","Export.csv");" and it does the same. In my controller I specify attachment already. I'll put my controller code onto description now
@John, unfortunately I am unable to reproduce your problem. Can you try returning some hardcoded value instead of using all those streams: return File(Encoding.UTF8.GetBytes("foo;bar;baz"), "text/csv", "report.csv");? So comment your entire code in this action and try hardcoding to see if it makes any difference. For me it works. When I redirect to this controller action the browser prompts me to download the CSV file and stays on the same page.
0

Thanks for the guidance, it helped get me there. I set a DIV with visibility to hidden:

<div id="ExportList" style="visibility:hidden;clear:both;">                       
</div>

I placed this hidden div below the DIV that has the grid results, the grid results stay in place and the hidden CSV stream is written to page and popup prompt appears then open to Excel

Here is the Javascipt I finished on, I think this could be neater though. Not having to use the extra DIV, but its not too bad :

    $(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()
            };
            $('#ExportList').load(url, data, function() {
                $('#LoadingGif').empty();
                location.href = url + "?searchText=" + data.searchText + "&searchTextSite=" + data.searchTextSite + "&StartDate=" + data.StartDate + "&EndDate=" + data.EndDate;
            });

        });
    });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.