developer tip

각도 앱에 Blob (.pdf) 표시

copycodes 2020. 8. 14. 07:55
반응형

각도 앱에 Blob (.pdf) 표시


$http.post응답 에서 blob으로 받고있는 pdf 파일을 표시하려고했습니다 . <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바에 따르면 블로그가 참조로 사용할 수있는 임시 URL을 만듭니다.

HTML :

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

Angular에서 이것을 처리하는 방법을 잘 모르겠습니다. 이상적인 상황은 (1) 범위에 할당하고, (2) blob을 pdf로 '준비 / 재 작성' (3) 사용하여 HTML에 전달하는 <embed>것입니다. 앱 내에 표시하고 싶습니다.

저는 하루 이상 연구를 해왔지만 어떻게 든 이것이 Angular에서 어떻게 작동하는지 이해할 수없는 것 같습니다 ... 그리고 거기에있는 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 서비스를 사용하여 URL을 각도 신뢰하도록 만들어야합니다. 다음과 같은 방법으로 수행 할 수 있습니다.

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

자바 REST 웹 서비스-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;
    }

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>

I faced difficulties using "window.URL" with Opera Browser as it would result to "undefined". Also, with window.URL, the PDF document never opened in Internet Explorer and Microsoft Edge (it would remain waiting forever). I came up with the following solution that works in IE, Edge, Firefox, Chrome and Opera (have not tested with 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);
    }
}

Let me know if it helped! :)


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

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

A suggestion of code that I just used in my project using AngularJS v1.7.2

$http.get('LabelsPDF?ids=' + ids, { responseType: 'arraybuffer' })
            .then(function (response) {
                var file = new Blob([response.data], { type: 'application/pdf' });
                var fileURL = URL.createObjectURL(file);
                $scope.ContentPDF = $sce.trustAsResourceUrl(fileURL);
            });

<embed ng-src="{{ContentPDF}}" type="application/pdf" class="col-xs-12" style="height:100px; text-align:center;" />

참고URL : https://stackoverflow.com/questions/21628378/display-blob-pdf-in-an-angular-app

반응형