Mostrar blob (.pdf) en una aplicación angular

He estado tratando de mostrar el archivo pdf que recibo como un blob de una respuesta $http.post . El pdf debe mostrarse dentro de la aplicación usando por ejemplo.

Encontré un par de publicaciones pero, de alguna manera, mi ejemplo no parece funcionar.

JS:

De acuerdo con este documento , continué y probé …

 $http.post('/postUrlHere',{myParams}).success(function (response) { var file = new Blob([response], {type: 'application/pdf'}); var fileURL = URL.createObjectURL(file); $scope.content = fileURL; }); 

Ahora, por lo que entiendo, fileURL crea una URL temporal que el blog puede usar como referencia.

HTML:

  

No estoy seguro de cómo manejar esto en Angular, la situación ideal sería (1) asignarlo a un scope, (2) ‘preparar / reconstruir’ el blob a un pdf (3) pasarlo al HTML usando porque quiero mostrarlo dentro de la aplicación.

He estado investigando durante más de un día, pero de alguna manera parece que no entiendo cómo funciona esto en Angular … Y supongamos que las bibliotecas de visor de PDF no eran una opción.

En primer lugar, debe establecer el responseType en arraybuffer . Esto es obligatorio si desea crear un blob de sus datos. Ver Sending_and_Receiving_Binary_Data . Entonces su código se verá así:

 $http.post('/postUrlHere',{myParams}, {responseType:'arraybuffer'}) .success(function (response) { var file = new Blob([response], {type: 'application/pdf'}); var fileURL = URL.createObjectURL(file); }); 

La siguiente parte es, necesitas usar el servicio $ sce para hacer que angular sea tu url. Esto se puede hacer de esta manera:

 $scope.content = $sce.trustAsResourceUrl(fileURL); 

No olvides inyectar el servicio $ sce .

Si todo está hecho, ahora puede insertar su PDF:

  

Yo uso AngularJS v1.3.4

HTML:

  

Controlador JS:

 'use strict'; angular.module('xxxxxxxxApp') .controller('xxxxController', function ($scope, xxxxServicePDF) { $scope.downloadPdf = function () { var fileName = "test.pdf"; var a = document.createElement("a"); document.body.appendChild(a); a.style = "display: none"; xxxxServicePDF.downloadPdf().then(function (result) { var file = new Blob([result.data], {type: 'application/pdf'}); var fileURL = window.URL.createObjectURL(file); a.href = fileURL; a.download = fileName; a.click(); }); }; }); 

Servicios de JS:

 angular.module('xxxxxxxxApp') .factory('xxxxServicePDF', function ($http) { return { downloadPdf: function () { return $http.get('api/downloadPDF', { responseType: 'arraybuffer' }).then(function (response) { return response; }); } }; }); 

Servicios web de Java REST – Spring MVC:

 @RequestMapping(value = "/downloadPDF", method = RequestMethod.GET, produces = "application/pdf") public ResponseEntity getPDF() { FileInputStream fileStream; try { fileStream = new FileInputStream(new File("C:\\xxxxx\\xxxxxx\\test.pdf")); byte[] contents = IOUtils.toByteArray(fileStream); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/pdf")); String filename = "test.pdf"; headers.setContentDispositionFormData(filename, filename); ResponseEntity response = new ResponseEntity(contents, headers, HttpStatus.OK); return response; } catch (FileNotFoundException e) { System.err.println(e); } catch (IOException e) { System.err.println(e); } return null; } 

Las sugerencias de michael funcionan como un encanto para mí 🙂 Si reemplaza $ http.post con $ http.get, recuerde que el método .get acepta 2 parámetros en lugar de 3 … aquí es donde se desperdicia mi tiempo …;)

controlador:

 $http.get('/getdoc/' + $stateParams.id, {responseType:'arraybuffer'}) .success(function (response) { var file = new Blob([(response)], {type: 'application/pdf'}); var fileURL = URL.createObjectURL(file); $scope.content = $sce.trustAsResourceUrl(fileURL); }); 

ver:

  

Tuve dificultades para usar “window.URL” con Opera Browser ya que resultaría “indefinido”. Además, con window.URL, el documento PDF nunca se abrió en Internet Explorer y Microsoft Edge (permanecería esperando por siempre). Se me ocurrió la siguiente solución que funciona en IE, Edge, Firefox, Chrome y Opera (no se ha probado con Safari):

 $http.post(postUrl, data, {responseType: 'arraybuffer'}) .success(success).error(failed); function success(data) { openPDF(data.data, "myPDFdoc.pdf"); }; function failed(error) {...}; function openPDF(resData, fileName) { var ieEDGE = navigator.userAgent.match(/Edge/g); var ie = navigator.userAgent.match(/.NET/g); // IE 11+ var oldIE = navigator.userAgent.match(/MSIE/g); var blob = new window.Blob([resData], { type: 'application/pdf' }); if (ie || oldIE || ieEDGE) { window.navigator.msSaveBlob(blob, fileName); } else { var reader = new window.FileReader(); reader.onloadend = function () { window.location.href = reader.result; }; reader.readAsDataURL(blob); } } 

¡Avíseme si ayudó! 🙂

Agregar responseType a la solicitud que se hace desde angular es de hecho la solución, pero para mí no funcionó hasta que configuré responseType para blob , no para arrayBuffer. El código es autoexplicativo:

  $http({ method : 'GET', url : 'api/paperAttachments/download/' + id, responseType: "blob" }).then(function successCallback(response) { console.log(response); var blob = new Blob([response.data]); FileSaver.saveAs(blob, getFileNameFromHttpResponse(response)); }, function errorCallback(response) { }); 

He luchado durante los últimos días tratando de descargar archivos PDF e imágenes, todo lo que pude descargar fueron simples archivos de texto.

La mayoría de las preguntas tienen los mismos componentes, pero tomó un tiempo encontrar el orden correcto para hacerlo funcionar.

Gracias @Nikolay Melnikov, su comentario / respuesta a esta pregunta fue lo que lo hizo funcionar.

En pocas palabras, aquí está mi servicio backend de AngularJS:

  getDownloadUrl(fileID){ // //Get the download url of the file let fullPath = this.paths.downloadServerURL + fileId; // // return the file as arraybuffer return this.$http.get(fullPath, { headers: { 'Authorization': 'Bearer ' + this.sessionService.getToken() }, responseType: 'arraybuffer' }); } 

Desde mi controlador:

 downloadFile(){ myService.getDownloadUrl(idOfTheFile).then( (response) => { //Create a new blob object let myBlobObject=new Blob([response.data],{ type:'application/pdf'}); //Ideally the mime type can change based on the file extension //let myBlobObject=new Blob([response.data],{ type: mimeType}); var url = window.URL || window.webkitURL var fileURL = url.createObjectURL(myBlobObject); var downloadLink = angular.element(''); downloadLink.attr('href',fileURL); downloadLink.attr('download',this.myFilesObj[documentId].name); downloadLink.attr('target','_self'); downloadLink[0].click();//call click function url.revokeObjectURL(fileURL);//revoke the object from URL }); }