Blob de exibição (.pdf) em um aplicativo angular

Eu tenho tentado exibir o arquivo pdf que estou recebendo como um blob de uma resposta $http.post . O pdf deve ser exibido dentro do aplicativo usando por exemplo.

Eu me deparei com alguns posts, mas de alguma forma o meu exemplo parece não funcionar.

JS:

De acordo com esse documento , eu continuei e tentei …

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

Agora, pelo que entendi, fileURL cria uma URL temporária que o blog pode usar como referência.

HTML:

  

Não tenho certeza de como lidar com isso em Angular, a situação ideal seria (1) atribuí-lo a um escopo, (2) ‘preparar / reconstruir’ o blob para um pdf (3) passá-lo para o HTML usando porque eu quero exibi-lo dentro do aplicativo.

Eu venho pesquisando há mais de um dia, mas de alguma forma eu não consigo entender como isso funciona em Angular … E vamos supor que as bibliotecas de visualizadores de PDF não eram uma opção.

   

Primeiro de tudo você precisa definir o responseType para arraybuffer . Isso é necessário se você quiser criar um blob dos seus dados. Veja Sending_and_Receiving_Binary_Data . Então seu código ficará assim:

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

A próxima parte é, você precisa usar o serviço $ sce para fazer angular confiar em seu URL. Isso pode ser feito desta maneira:

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

Não esqueça de injetar o serviço do $ sce .

Se tudo isso for feito, você pode agora incorporar o seu pdf:

  

Eu uso o 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(); }); }; }); 

Serviços JS:

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

Serviços Web 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; } 

As sugestões de Michael funcionam como um encanto para mim 🙂 Se você replace $ http.post por $ http.get, lembre-se de que o método .get aceita 2 parâmetros em vez de 3 … isto é onde é desperdiçado meu tempo …;)

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

Visão:

  

Eu enfrentei dificuldades usando “window.URL” com o Opera Browser, pois resultaria em “indefinido”. Além disso, com window.URL, o documento PDF nunca foi aberto no Internet Explorer e no Microsoft Edge (ele permaneceria aguardando para sempre). Eu criei a seguinte solução que funciona no IE, Edge, Firefox, Chrome e Opera (não testei com o 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); } } 

Deixe-me saber se ajudou! 🙂

Adicionar responseType à solicitação que é feita a partir de angular é, de fato, a solução, mas, para mim, não funcionou até eu definir responseType para blob , não para arrayBuffer. O código é auto-explicativo:

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

Eu tenho lutado nos últimos dias tentando baixar pdfs e imagens, tudo que eu consegui fazer foi baixar arquivos de texto simples.

A maioria das perguntas tem os mesmos componentes, mas demorou um pouco para descobrir a ordem certa para que funcionasse.

Obrigado @Nikolay Melnikov, o seu comentário / resposta a esta pergunta foi o que fez o trabalho.

Em poucas palavras, aqui está minha chamada de back-end do AngularJS Service:

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

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