0

I am trying to download an excel file generated from data entered through a webpage in an MVC application.

This ajax call is executed when a button is pressed, and calls two methods in my controller. One to generate the excel file and another to download the file:

$.ajax({
            type: 'POST',
            data: myDataObject,
            url: 'MyController/GenerateExcel/',
            success: function(data) {
                if (data.id != "") {
                    $http.get('MyController/DownloadExcel?id=' + encodeURIComponent(data.id) + '&name=' + encodeURIComponent(data.name));
                    return true;
                }
            }
        });

Here is my POST method that generates the excel file and saves it to TempData:

[HttpPost]
    public JsonResult GenerateExcel(Object model)
    {
        var fileName = "myexcel.xlsx";
        var fileID = Guid.NewGuid().ToString();

        var generatedReport = GenerateCustomExcel(model);
        using (MemoryStream memoryStream = new MemoryStream())
        {
            generatedReport.SaveAs(memoryStream);
            generatedReport.Dispose();
            memoryStream.Position = 0;
            TempData[fileID] = memoryStream.ToArray();
        }


        return Json(new { id = fileID, name = fileName });
    }

Here is my GET method that downloads the saved excel from TempData:

[HttpGet]
    public FileResult DownloadExcel(string id, string name)
    {
        if (TempData[id] != null)
        {
            byte[] fileBytes = TempData[id] as byte[];
            return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", name);
        }
        else
        {
            return null;
        }
    }

This works flawlessly in Google Chrome and Firefox browsers. However, when using either Internet Explorer or Microsoft Edge browsers, the file refuses to download.

The debug console doesn't produce any useful errors. I have tried changing the returned File type to an octet stream and using window.location.href instead of a get request to download the file, but nothing appears to work. All of the functions are called and data passed between them correctly, so routes are not the problem.

Does anyone know how I can make the returned FileResult download?

Sam Kline
  • 41
  • 6
  • This might help, although the accepted answer is only for PDFs, you might be able to adapt for your case: https://stackoverflow.com/questions/9996353/internet-explorer-error-using-asp-mvc-4-0-fileresult/11267754 – hmiedema9 Jan 17 '19 at 20:57

1 Answers1

1

Here is a solution. It uses the same code as in my question except for the changes listed here.

Add an iframe element to your webpage:

<iframe id="iFrameFileDownload" style="display: none;"></iframe>

In the javascript, instead of a call using $http.get(), set the 'src' attribute of the iframe element to the controller function url:

$.ajax({
        type: 'POST',
        data: myDataObject,
        url: 'MyController/GenerateExcel/',
        success: function(data) {
            if (data.id != "") {
                $("#iFrameFileDownload").attr("src", 'MyController/DownloadExcel?id=' + encodeURIComponent(data.id) + '&name=' + encodeURIComponent(data.name));
                return true;
            }
        }
    });

Another solution that I considered is using the window.open() function instead of $http.get(). (source: Download a file with mvc) However, that solution uses popups and would require users to enable popups in their browser before downloading the file.

Sam Kline
  • 41
  • 6