How to Display blob (.pdf) in an AngularJS app

后端 未结 8 1293
逝去的感伤
逝去的感伤 2020-11-22 11:01

I have been trying to display pdf file which I am getting as a blob from a $http.post response. The pdf must be displayed within the app using

相关标签:
8条回答
  • 2020-11-22 11:40

    I have struggled for the past couple of days trying to download pdfs and images,all I was able to download was simple text files.

    Most of the questions have the same components, but it took a while to figure out the right order to make it work.

    Thank you @Nikolay Melnikov, your comment/reply to this question was what made it work.

    In a nutshell, here is my AngularJS Service backend call:

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

    From my controller:

    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
        });
    }
    
    0 讨论(0)
  • 2020-11-22 11:43

    michael's suggestions works like a charm for me :) If you replace $http.post with $http.get, remember that the .get method accepts 2 parameters instead of 3... this is where is wasted my time... ;)

    controller:

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

    view:

    <object ng-show="content" data="{{content}}" type="application/pdf" style="width: 100%; height: 400px;"></object>
    
    0 讨论(0)
  • 2020-11-22 11:44

    I use AngularJS v1.3.4

    HTML:

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

    JS controller:

    '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 services:

    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 Services - 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;
        }
    
    0 讨论(0)
  • 2020-11-22 11:44

    Most recent answer (for Angular 8+):

    this.http.post("your-url",params,{responseType:'arraybuffer' as 'json'}).subscribe(
      (res) => {
        this.showpdf(res);
      }
    )};
    
    public Content:SafeResourceUrl;
    showpdf(response:ArrayBuffer) {
      var file = new Blob([response], {type: 'application/pdf'});
      var fileURL = URL.createObjectURL(file);
      this.Content = this.sanitizer.bypassSecurityTrustResourceUrl(fileURL);
    }
    
      HTML :
    
      <embed [src]="Content" style="width:200px;height:200px;" type="application/pdf" />
    
    0 讨论(0)
  • 2020-11-22 11:48

    First of all you need to set the responseType to arraybuffer. This is required if you want to create a blob of your data. See Sending_and_Receiving_Binary_Data. So your code will look like this:

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

    The next part is, you need to use the $sce service to make angular trust your url. This can be done in this way:

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

    Do not forget to inject the $sce service.

    If this is all done you can now embed your pdf:

    <embed ng-src="{{content}}" style="width:200px;height:200px;"></embed>
    
    0 讨论(0)
  • 2020-11-22 11:50

    Adding responseType to the request that is made from angular is indeed the solution, but for me it didn't work until I've set responseType to blob, not to arrayBuffer. The code is self explanatory:

        $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) {   
            });
    
    0 讨论(0)
提交回复
热议问题