AngularJS:在角度应用程序中显示blob(.pdf)

我一直在试图显示PDF文件,我得到一个$http.post响应blob。 例如,必须使用<embed src>在应用程序中显示pdf。

我遇到了几个帖子帖子,但一些如何我的例子似乎没有工作。

JS:

根据这个文件 ,我继续尝试…

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

现在从我的理解, fileURL创建一个临时的网址,博客可以用作参考。

HTML:

 <embed src="{{content}}" width="200" height="200"></embed> 

我不知道如何处理这个角度,理想的情况是(1)将它分配给一个范围, (2) “准备/重建”blob到一个pdf (3)传递给HTML使用<embed>因为我想在应用程序中显示它。

我一直在研究一天以上,但一些我似乎无法理解这是如何工作的角度..让我们假设PDF查看器库没有一个选项。

首先你需要将responseType设置为arraybuffer 。 如果你想创建一个数据blob,这是必需的。 请参阅Sending_and_Receiving_Binary_Data 。 所以你的代码如下所示:

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

接下来的部分是,你需要使用$ sce服务使角度信任你的网址。 这可以通过这种方式完成:

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

不要忘记注入$ sce服务。

如果这一切都已经完成,现在可以嵌入您的PDF:

 <embed ng-src="{{content}}" style="width:200px;height:200px;"></embed> 

我使用AngularJS v1.3.4

HTML:

 <button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button> 

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

JS服务:

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

Java REST Web服务 – Spring MVC:

 @RequestMapping(value = "/downloadPDF", method = RequestMethod.GET, produces = "application/pdf") public ResponseEntity<byte[]> 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<byte[]> response = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK); return response; } catch (FileNotFoundException e) { System.err.println(e); } catch (IOException e) { System.err.println(e); } return null; } 

迈克尔的建议像我的魅力:)如果你用$ http.get替换$ http.post,请记住.get方法接受2参数,而不是3 …这是浪费我的时间…;)

控制器:

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

视图:

 <object ng-show="content" data="{{content}}" type="application/pdf" style="width: 100%; height: 400px;"></object> 

Opera浏览器使用“window.URL”会遇到困难,因为它会导致“未定义”。 另外,在window.URL中,PDF文档从未在Internet Explorer和Microsoft Edge中打开过(它将永远保持等待)。 我想出了在IE,Edge,Firefox,Chrome和Opera(没有用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); } } 

让我知道,如果它帮助! 🙂

responseType添加到由angular创建的请求中的确是解决方案,但是对于我来说,只有在将responseType设置为blob而不是arrayBuffer之后,才能正常工作。 代码是自我解释的:

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

过去几天我一直在努力尝试下载PDF和图像,所有我能够下载的都是简单的文本文件。

大多数问题都有相同的组件,但花了一段时间才能找出正确的顺序来使其工作。

谢谢你@Nikolay Melnikov,你对这个问题的评论/回复是它的工作原理。

简而言之,这里是我的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' }); } 

从我的控制器:

 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('<a></a>'); 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 }); } 
Interesting Posts