AngularJSアプリでblob(.pdf)を表示する方法


106

$http.post応答からBLOBとして取得しているPDFファイルを表示しようとしています。pdfは<embed src>、たとえばアプリを使用して表示する必要があります。

いくつかのスタックポストに出くわしましたが、どういうわけか私の例は機能していないようです。

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>

私は理想的な状況がになり、必ず角度でこれを処理する方法はないです(1) 、スコープに割り当てます(2)「再構築準備/」PDFへのブロブ(3)が使用してHTMLに渡す<embed>ので、私はアプリ内で表示したい。

私は1日以上研究してきましたが、どういうわけかAngularでこれがどのように機能するのか理解できないようです...そして、PDFビューアライブラリが選択肢がないと仮定しましょう。


こんにちはD'lo DeProjuicer、角度固定を介してPDFを生成するという問題を解決できましたか?
Raymond Nakampe 2014

@michael D'lo DeProjuicer角度2で同じケースに対して何をすべきですか?
モニカ2016年

回答:


214

あなたが設定する必要がまず第一responseTypearraybuffer。これは、データの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.114 m)では機能しませんでした。<embed>の代わりに<object>を使用してこれを解決しました:<object data = "{{content}}" type = "application / pdf"> </ object>
HoffZ

2
私(AngularJS 1.25)の場合:新しいBlob([response.data]
Martin Connell 2014年

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 '25年

1
私にとってそれは作品を作るための唯一の方法は、とのブロブを作成することでしたresponse.data代わりにresponse:このように、var file = new Blob([response.data], {type: 'application/pdf'});
Alekos Filini

1
@ yosep-キムはこれが原因URLオブジェクトのIEでの作業は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;
            });
        }
    };
});

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

サファリのどのバージョン?window.URLはSafari 9以降で良好です。caniuse.com
createObjectURL –StéphaneGRILLON

MacBook proとsafari 9.0.2でテストして検証しました。
ステファン・グリオン

同じ、macBook el captain。window.URL.createObjectURL(file); 問題はどこにあるのかわかりませんが、コードが機能しません。私は何か間違ったことをするかもしれません。ありがとうございます。私は何それが動作していないと使用FileSaver.jsをチェックする時間はない持っている
即ち、fdrv

アプリケーションがオンラインの場合は、URLを投稿してください。あなたは同じバックエンドを持っていますか?
ステファン・グリオン

Safariではダウンロード属性はサポートされていません。caniuse.com/#search=download
Biswanath

21

マイケルの提案は私にとって魅力のように機能します:) $ 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 2016年

ありがとう、これで数時間節約できました。ファイルをフルスクリーンで置き換え$scope.content = $sce.trustAsResourceUrl(fileURL);$window.open(fileURL, '_self', '');開くこともできます。
Tavitos

9

Operaブラウザで「window.URL」を使用すると、「undefined」になるため、困難に直面しました。また、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を開くことができなかったためです。したがって、PDFファイルをダウンロードするには、すべてのブラウザー(モバイルブラウザーを含む)で実行できるソリューションを用意するのが最善だと思いました。
Manuel Hernandez

次のコードを使用して、PDFを新しいタブで表示できます。window.open(reader.result、 '_blank');
samneric 2016年

6

追加responseTypeを角度から作られているの要求には、確かなソリューションですが、私が設定したまで私のためにそれは仕事をしませんでしたresponseTypeブロブ、ない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) {   
        });

2
実際には、'blob'タイプを使用すると、短く書くことができFileSaver.saveAs(response.data, getFileNameFromHttpResponse(response));ます。作成する必要はありませんBlob
Alena Kastsiukavets '19 / 07/19

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、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.