1

I am trying to download Excel File through WebAPI. Basically Excel file is created through Memory Stream with the help of this Post

Excel Content is generating fine however I am unable to download the Excel as the Response itself is pure XML when I see it in Response Tab of Chrome Network Tools. Following is my code for C#

var sheet = linq.ExportToExcel(userAddedList);

            var stream = new MemoryStream();
            var sw = new StreamWriter(stream);
            sw.Write(sheet);
            sw.Flush();

            var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(stream.GetBuffer()) };
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "Report.xml" };
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/ms-excel");

            var response = ResponseMessage(result);
            return response;

And this is how I call it through Angular.

var httpRequest = commonFunctions.getRequestObject("GET", requestURL, {}, null);

        $http(httpRequest).then(function (response) {
            vm.isProcessing = false;
        }, function (error) { displayError(error); });
Community
  • 1
  • 1
programmerboy
  • 341
  • 5
  • 15
  • 1
    You're specifying an XML extension, and then setting the content type to the BIFF version of Excel. What exactly are you expecting as a result? I would take a look at http://stackoverflow.com/a/4212908/534109 – Tieson T. Sep 02 '16 at 16:15
  • @TiesonT.As I mentioned I just followed the example in the post. Anyways, as you suggested I changed the extension to xls and MIME type to application/vnd.ms-excel. Without AJAX request it works fine, however I would love to know how to make it work with AJAX – programmerboy Sep 02 '16 at 22:24

1 Answers1

1

If the browsers you are targeting support the File API you can use the Blob object. Here it is, wrapped in a function, taken from this fiddle:

var setFile = function( data, fileName, fileType ) {
    // Set objects for file generation.
    var blob, url, a, extension;

    // Get time stamp for fileName.
    var stamp = new Date().getTime();

    // Set MIME type and encoding.
    fileType = ( fileType || "text/csv;charset=UTF-8" );
    extension = fileType.split( "/" )[1].split( ";" )[0];
    // Set file name.
    fileName = ( fileName || "ActiveVoice_" + stamp + "." + extension );

    // Set data on blob.
    blob = new Blob( [ data ], { type: fileType } );

    // Set view.
    if ( blob ) {
        // Read blob.
        url = window.URL.createObjectURL( blob );

        // Create link.
        a = document.createElement( "a" );
        // Set link on DOM.
        document.body.appendChild( a );
        // Set link's visibility.
        a.style = "display: none";
        // Set href on link.
        a.href = url;
        // Set file name on link.
        a.download = fileName;

        // Trigger click of link.
        a.click();

        // Clear.
        window.URL.revokeObjectURL( url );
    } else {
        // Handle error.
    }
};

You would use it as part of your code like this:

$http(httpRequest).then(function (response) {
    vm.isProcessing = false;
    setFile(response.data, "Report.xls", "application/ms-excel");
}, function (error) { displayError(error); });
mlhDev
  • 2,235
  • 1
  • 22
  • 43
  • Advising the OP to *'research/google for a javascript solution'* and only providing a link to to a third party library demo is not a complete response nor an answer. This should have been a comment. –  Sep 02 '16 at 16:22
  • @Jeeped - Updated answer to be more specific. – mlhDev Sep 16 '16 at 17:12