Nadeem Jamali Nadeem Jamali - 1 year ago 271
C# Question

Downloading Excel file xlsx in Angularjs and WebApi

I am working on a task, in which I have to download a report in xlsx format. The report file is generated successfully from server, and is received on client side as well. But it is not opening and producing invalid format error.

Below is the code of server side.

var output = await reportObj.GetExcelData(rParams);
if (output != null){
var result = new HttpResponseMessage(HttpStatusCode.OK)
Content = new ByteArrayContent(output.ConentBytes)
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
FileName = output.FileName
return result;

Here is the code for client side:

var saveData = function (response) {

if (response.status === 200) {
var reportData =;

var b = new Blob([reportData], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
saveAs(b,"ReportFile.xlsx");//this is FileSaver.js function
} else {


$scope.getExcelFile = function(reportName, reportParams) {

reportDataService.getExcelReportData(reportName, reportParams, saveData);


Below is the error message:

Excel could not open newFile.xlsx because some content is unreadable. Do you want to open and repair this workbook?

On clicking repair, following error appears:
Excel cannot open this file.

The file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.

Can some one guide me what I am doing wrong? Meanwhile, the same server side file generator objects works smoothly in ASP.Net forms application, and the file opens without any error as well.

Thank you.

Answer Source

I expect your $http call is missing the response type configuration. This is the way I download office files:

function download(url, defaultFileName) {
    var self = this;
    var deferred = $q.defer();
    $http.get(url, { responseType: "arraybuffer" }).then(
        function (data, status, headers) {
            var type = headers('Content-Type');
            var disposition = headers('Content-Disposition');
            if (disposition) {
                var match = disposition.match(/.*filename=\"?([^;\"]+)\"?.*/);
                if (match[1])
                    defaultFileName = match[1];
            defaultFileName = defaultFileName.replace(/[<>:"\/\\|?*]+/g, '_');
            var blob = new Blob([data], { type: type });
            saveAs(blob, defaultFileName);
        }, function (data, status) {
            var e = /* error */
    return deferred.promise;