I have a .Net 6 Razor pages application where I need to download an excel on a button click via Ajax. I am able to successfully do that by creating a new excel workbook in memory stream using OpenXML like this.
C# Code
public IActionResult OnPostAjaxExport(string somedata)
{
// Create a dummy data table
DataSet ds = MakeDummyDataSet();
//Export Excel via Memory Stream
MemoryStream ms = ExportDataSetViaMemoryStream(ds);
return new FileStreamResult(ms, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
private MemoryStream ExportDataSetViaMemoryStream(DataSet ds)
{
MemoryStream memoryStream = new MemoryStream();
using (var workbook = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new Workbook();
// Further code to populate the workbook...
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
}
Ajax code
$.ajax({
type: "POST",
url: "/Index?handler=AjaxExport",
data: payload,
xhrFields: {
responseType: 'blob'
},
headers: {
RequestVerificationToken:
$('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (result) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(result);
a.href = url;
a.download = 'download.xlsx';
a.click();
window.URL.revokeObjectURL(url);
},
error: function (result) {
alert("error: " + JSON.stringify(result));
}
});
This is working fine. On Ajax button click I am able to download the excel in the browser.
However now I have a new requirement to download some pre-existing excel files that are saved into a physical location in the server.
The path of these files are not directly accessible in the browser. So I tried to read the files into memory stream and return them to the Ajax function the same way I was doing earlier.
Here is what I have tried.
public IActionResult OnPostDownloadPreGeneratedFile()
{
string FilePath = @"C:\Manas\FilePath\DownloadTest\payload2.xlsx";
string ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//read the file and prepare memory stream
MemoryStream ms = new MemoryStream();
FileStream file = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
ms.Seek(0, SeekOrigin.Begin);
file.CopyTo(ms);
return new FileStreamResult(ms, ContentType);
}
But this does not work, although I am creating the same memorystream type I was creating earlier.
The console or Ajax call does not show any error. Just the C# code returns the FilestreamResult and then nothing happens in the browser.
How can I make this work?
Nevermind, I found the solution. I just needed to do this: