AngularJS 앱에서 Blob (.pdf)을 표시하는 방법


106

$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 뷰어 라이브러리에 옵션이 없다고 가정합시다.


안녕 D' lo DeProjuicer, 각도 고정을 통해 PDF를 생성하는 문제를 해결 했습니까?
Raymond Nakampe 2014 년

@michael D' lo DeProjuicer 각도 2에서 동일한 경우에 대해 어떻게해야합니까?
monica nov.

답변:


214

먼저을로 설정해야 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>

9
나를 위해 이것은 Chrome (35.0.1916.114m)에서 작동하지 않았습니다. <embed> 대신 <object>를 사용하여이 문제를 해결했습니다. <object data = "{{content}}"type = "application / pdf"> </ object>
HoffZ

2
나를 위해 (AngularJS 1.25)해야했습니다 : new Blob ([response.data]
Martin Connell

2
@HoffZ : 필드를 $http.get지정하는 바로 가기 방법 을 전체 방법 으로 대체했습니다 responseType. { url: "http://127.0.0.1:8080/resources/jobs/af471106-2e71-4fe6-946c-cd1809c659e5/result/?key="+$scope.key, method: "GET", headers: { 'Accept': 'application/pdf' }, responseType: 'arraybuffer' }그리고 작동합니다 :)
Nikolay Melnikov

1
나에게는 일을 할 수있는 유일한 방법은 함께 덩어리를 만드는 것이었다 response.data대신 response이 같은var file = new Blob([response.data], {type: 'application/pdf'});
Alekos Filini

1
URL 객체의 IE에 존재하지 않기 때문에 @ yosep - 김이 IE에서 작동하지 않습니다 : caniuse.com/#search=URL
카를로스에게

32

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

어떤 버전의 사파리? window.URL은 safari 9 이후에 적합합니다. caniuse.com/#search=createObjectURL
Stéphane GRILLON

MacBook pro 및 safari 9.0.2에서 테스트하고 유효성을 검사했습니다.
Stéphane GRILLON

맥북 엘 캡틴도 마찬가지입니다. window.URL.createObjectURL (파일); 나는 문제가 어디에 있는지 모르지만 코드가 작동하지 않습니다. 내가 뭔가 잘못했을 수 있습니다. 감사합니다. 나는 그것이 작동 및 사용 FileSaver.js없는 것을 확인하지 시간이
fdrv

신청서가 온라인 인 경우 URL을 게시 해주세요. 동일한 백엔드가 있습니까?
Stéphane GRILLON

다운로드 속성은 Safari에서 지원되지 않습니다. caniuse.com/#search=download
Biswanath

21

michael의 제안은 나를위한 매력처럼 작동합니다. :) $ http.post를 $ http.get으로 바꾸면 .get 메소드가 3 개 대신 2 개의 매개 변수를 허용한다는 점을 기억하세요 ... 이것은 내 시간을 낭비하는 곳입니다 ...;)

제어 장치:

$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>

responseType:'arraybuffer', 방금 수면 시간을 절약했습니다! +1
svarog

대신 저장을 트리거하여 html로 인쇄하는 방법은 무엇입니까?
fdrv

이것은 나에게 몇 시간을 저장, 감사합니다, 당신은 또한 대체 할 수 $scope.content = $sce.trustAsResourceUrl(fileURL);$window.open(fileURL, '_self', '');및 전체 화면에 파일을 엽니 다.
Tavitos

9

Opera Browser에서 "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);
    }
}

도움이되었는지 알려주세요! :)


이 방법은 IE의 브라우저 창에서 PDF 문서를 열지 않지만 사용자에게 다운로드하라는 메시지를 표시합니다. 이 문제를 해결할 수 있습니까?
sdd

1
위의 코드는 PDF 파일을 다운로드하고 기본 PDF 리더 앱이 파일을 열도록하는 것입니다. 모바일 장치에서도 잘 작동합니다. 이유는 일부 브라우저에서는 PDF를 열 수 있지만 다른 브라우저에서는 열 수 없기 때문입니다. 그래서 모든 브라우저 (모바일 브라우저 포함)에서 실행되는 솔루션을 가지고 PDF 파일을 다운로드하는 것이 최선이라고 생각했습니다.
Manuel Hernandez

다음 코드를 사용하여 새 탭에서 PDF를 볼 수 있습니다. window.open (reader.result, '_blank');
samneric 2016

6

angular에서 만들어진 요청에 responseType 을 추가 하는 것이 실제로 해결책이지만, 저에게는 responseType 을 arrayBuffer가 아닌 blob으로 설정 하기 전까지는 작동하지 않았습니다 . 코드는 자명합니다.

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

2
실제로,와 'blob'유형이 짧게 쓸 수 없습니다 : FileSaver.saveAs(response.data, getFileNameFromHttpResponse(response));만들 필요Blob
알레 Kastsiukavets

0

나는 지난 며칠 동안 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
    });
}

0

가장 최근 답변 (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" />

-1

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;" />

1
간략한 정보도 추가 해주세요.
Farhana 2018
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.