1
votes

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); });
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 stackoverflow.com/a/4212908/534109Tieson T.
@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 AJAXprogrammerboy

1 Answers

1
votes

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); });