Estoy trabajando en una tarea, en la que tengo que descargar un informe en formato xlsx. El archivo de informe se genera correctamente desde el servidor y también se recibe en el lado del cliente. Pero no se abre y produce un error de formato no válido.
A continuación se muestra el código del lado del servidor.
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; }
Aquí está el código para el lado del cliente:
var saveData = function (response) { if (response.status === 200) { var reportData = response.data; var b = new Blob([reportData], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); saveAs(b,"ReportFile.xlsx");//this is FileSaver.js function } else { console.log(response.statusText); } }; $scope.getExcelFile = function(reportName, reportParams) { reportDataService.getExcelReportData(reportName, reportParams, saveData); }
A continuación se muestra el mensaje de error:
Excel no pudo abrir newFile.xlsx porque parte del contenido es ilegible. ¿Quiere abrir y reparar este libro?
Al hacer clic en reparar, aparece el siguiente error: Excel no puede abrir este archivo.
El formato de archivo o la extensión del archivo no es válido. Verifique que el archivo no esté dañado y que la extensión del archivo coincida con el formato del archivo.
Alguien me puede orientar que estoy haciendo mal? Mientras tanto, los mismos objetos del generador de archivos del lado del servidor funcionan sin problemas en la aplicación de formularios ASP.Net, y el archivo también se abre sin ningún error.
Gracias.
Espero que a su llamada $http
le falte la configuración del tipo de respuesta. Esta es la forma en que descargo los archivos de Office:
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); deferred.resolve(defaultFileName); }, function (data, status) { var e = /* error */ deferred.reject(e); }); return deferred.promise; }
Estaba enfrentando el mismo error, el contenido estaba en formato hexa, así que agregué un tipo de respuesta como arraybuffer, el problema se resolvió. por favor ver más abajo.
$http({ url: '/api/sendPMOToBackendUpdate', method: "POST", headers: {'Content-type': 'application/json'}, data: backendTsData, responseType: 'arraybuffer' }).success(function(data, status, headers){ var file = new Blob([ data ], { type : 'application/vnd.ms-excel'}); var defaultFileName ="TSC-"+$scope.user.name+"-"+$scope.user.ohrId+".xls"; saveAs(file,defaultFileName); }).error(function(err) { console.log('Error: ' + err); });
Solo necesitas hacer una cosa solo eso. incluya los siguientes js para guardar el archivo localmente. Descárguelo de " https://github.com/eligrey/FileSaver.js/ " sus datos de respuesta deben estar en tipo blob.
Lo he implementado y funciona.
function downloadfile(url,defaultFileName){ var self = this; var deferred = $q.defer(); $http.get(url, { responseType: "blob" }).then( function (data){ saveAs(data.data, defaultFileName) deferred.resolve(defaultFileName); }, function (data) { var e = /* error */ deferred.reject(e); }); return deferred.promise; }