From my view I make a GET call with ajax jquery to my controller, which returns a FileContentResult this is an excel file what it returns. The file is created instantly, it is not on the server, I cannot pass a url to download the file since it does not exist.
It works for me if I return the FileContentResult from the controller, but on the page the user does not know when the download will finish or if it continues to download, I need to know if the download is still in progress and if the download has finished. I can't show a popup because I don't know if the download continues, I only know that the file has been downloaded when I see it in my browser downloaded.
Controller code:
DataTable table = new DataTable("MyExcel");
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.ContentType = contentType;
Response.AddHeader("Content-disposition", "attachment; filename=MyExcel.xlsx");
return File(Utils.XLS(table), contentType, "MyExcel.xlsx");
**Utils.XLS(table):** this function return byte[] from table
The excel file is generated correctly, I have checked.
When the call Ajax is finished I retrieve the data and do the following:
$.get(url, function (data, status, xhr) {
var contentType = xhr.getResponseHeader("Content-Type");
var filename = xhr.getResponseHeader("Content-disposition");
filename = filename.substring(filename.lastIndexOf("=") + 1);
var blob = new Blob([data], {
type: contentType
);
var url = URL.createObjectURL(blob);
var link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
The excel file downloads successfully but appears corrupted and does not contain any information inside. I have tried many ways that I have been finding but none have worked for me.
Solution
In the request of the ajax request you have to add the responsetype 'arrayBuffer'
var xhrOverride = new XMLHttpRequest();
xhrOverride.responseType = 'arraybuffer';
$.ajax({
url: url,
method: 'POST',
xhr: function () {
return xhrOverride;
}
}).done(function (data, status, xhr) {
//request correct
}