Download Excel Via MemoryStream through Ajax works for New Excel, but not for existing excel files in the server

18 Views Asked by At

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?

1

There are 1 best solutions below

0
Bluemarble On

Nevermind, I found the solution. I just needed to do this:

 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

     var stream = new FileStream(FilePath, FileMode.Open);
     return new FileStreamResult(stream, ContentType);         
    
}