So zeigen Sie Blob (.pdf) in einer AngularJS-App an


106

Ich habe versucht, eine PDF-Datei anzuzeigen, die ich als Blob aus einer $http.postAntwort erhalte . Das PDF muss in der App mit angezeigt werden<embed src> .

Ich bin auf ein paar Stapelpfosten gestoßen, aber irgendwie scheint mein Beispiel nicht zu funktionieren.

JS:

Laut diesem Dokument habe ich weiter versucht ...

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

Soweit ich weiß, fileURL wird nun eine temporäre URL erstellt, die das Blog als Referenz verwenden kann.

HTML:

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

Ich bin mir nicht sicher, wie ich damit in Angular umgehen soll. Die ideale Situation wäre, (1) es einem Bereich zuzuweisen, (2) den Blob in ein PDF 'vorzubereiten / neu zu erstellen', (3) ihn an den HTML-Code zu übergeben, <embed>weil ich möchte es in der App anzeigen.

Ich habe seit mehr als einem Tag recherchiert, aber irgendwie kann ich nicht verstehen, wie das in Angular funktioniert ... Und nehmen wir einfach an, dass die PDF-Viewer-Bibliotheken da draußen keine Option waren.


Hallo D'lo DeProjuicer, haben Sie es geschafft, Ihr Problem beim Generieren der PDF-Datei über einen Winkel zu beheben?
Raymond Nakampe

@michael D'lo DeProjuicer Was ist für den gleichen Fall in Winkel 2 zu tun?
Monica

Antworten:


214

Zunächst einmal müssen Sie die festlegen responseTypezu arraybuffer. Dies ist erforderlich, wenn Sie einen Blob Ihrer Daten erstellen möchten. Siehe Sending_and_Receiving_Binary_Data . Ihr Code sieht also folgendermaßen aus:

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

Der nächste Teil ist, dass Sie den $ sce- Dienst verwenden müssen, damit Angular Ihrer URL vertraut. Dies kann folgendermaßen geschehen:

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

Vergessen Sie nicht, den $ sce- Service einzuschleusen .

Wenn dies alles erledigt ist, können Sie jetzt Ihr PDF einbetten:

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

9
Bei mir hat das in Chrome (35.0.1916.114 m) nicht funktioniert. Dies wurde behoben, indem <object> anstelle von <embed> verwendet wurde: <object data = "{{content}}" type = "application / pdf"> </ object>
HoffZ

2
Für mich (AngularJS 1.25) musste ich tun: neuer Blob ([response.data]
Martin Connell

2
@HoffZ: Ich habe die Verknüpfungsmethode $http.getdurch eine vollständige ersetzt und das responseTypeFeld angegeben: { 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' }Und es funktioniert :)
Nikolay Melnikov

1
Für mich war die einzige Möglichkeit, es zum response.dataresponsevar file = new Blob([response.data], {type: 'application/pdf'});
Laufen

1
@ yosep-kim dies funktioniert nicht im IE, da das URL-Objekt im IE nicht vorhanden ist: caniuse.com/#search=URL
Carlos

32

Ich benutze 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-Dienste:

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

Java REST-Webdienste - 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;
    }

Welche Version der Safari? window.URL ist gut in Safari 9 und danach: caniuse.com/#search=createObjectURL
Stéphane GRILLON

Ich habe mein MacBook Pro und Safari 9.0.2 getestet und validiert.
Stéphane GRILLON

Gleich, MacBook El Captain. window.URL.createObjectURL (Datei); Ich weiß nicht, wo das Problem ist, aber Code funktioniert nicht. Vielleicht mache ich etwas falsch. Irgendwelche danke. Ich habe keine Zeit zu überprüfen, was es nicht funktioniert und FileSaver.js
fdrv

Wenn Ihre Bewerbung online ist, geben Sie bitte Ihre URL an. Hast du das gleiche Backend?
Stéphane GRILLON

Das Download-Attribut wird in Safari nicht unterstützt. caniuse.com/#search=download
Biswanath

21

Michaels Vorschläge wirken wie ein Zauber für mich :) Wenn Sie $ http.post durch $ http.get ersetzen, denken Sie daran, dass die .get-Methode 2 Parameter anstelle von 3 akzeptiert ... hier wird meine Zeit verschwendet ...;)

Regler:

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

Aussicht:

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

responseType:'arraybuffer', habe mir nur ein paar Schlafstunden erspart! +1
svarog

Wie kann man das Speichern auslösen, um es in HTML zu drucken?
Fdrv

danke, das mir ein paar Stunden gespeichert haben , können Sie auch ersetzen $scope.content = $sce.trustAsResourceUrl(fileURL);mit $window.open(fileURL, '_self', '');und die Datei auf Vollbild öffnen.
Tavitos

9

Ich hatte Probleme bei der Verwendung von "window.URL" mit Opera Browser, da dies zu "undefiniert" führen würde. Außerdem wurde mit window.URL das PDF-Dokument in Internet Explorer und Microsoft Edge nie geöffnet (es würde für immer warten). Ich habe die folgende Lösung gefunden, die in IE, Edge, Firefox, Chrome und Opera funktioniert (nicht mit Safari getestet):

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

Lass es mich wissen, wenn es geholfen hat! :) :)


Dieser Ansatz öffnet das PDF-Dokument nicht im Browserfenster im IE, sondern fordert den Benutzer auf, es herunterzuladen. Gibt es eine Lösung dafür?
SDD

1
Mit dem obigen Code können Sie die PDF-Datei herunterladen und Ihre Standard-PDF-Reader-App zum Öffnen übernehmen. Es funktioniert sogar gut auf mobilen Geräten. Der Grund dafür ist, dass ich das PDF zwar in einigen Browsern öffnen konnte, in anderen jedoch nicht. Daher hielt ich es für das Beste, eine Lösung zu haben, die auf allen Browsern (einschließlich mobiler Browser) ausgeführt werden kann, um die PDF-Datei herunterzuladen.
Manuel Hernandez

Sie können den folgenden Code verwenden, um die PDF-Datei in einer neuen Registerkarte anzuzeigen: window.open (reader.result, '_blank');
Samneric

6

Hinzufügen response auf die Anforderung , die von Winkel hergestellt wird , ist in der Tat die Lösung, aber für mich ist es nicht funktioniert hat, bis ich festgelegt haben response zu Klecks , nicht zu Arraybuffer. Der Code ist selbsterklärend:

    $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
Tatsächlich

0

Ich hatte in den letzten Tagen Probleme, PDFs und Bilder herunterzuladen. Alles, was ich herunterladen konnte, waren einfache Textdateien.

Die meisten Fragen haben die gleichen Komponenten, aber es hat eine Weile gedauert, bis die richtige Reihenfolge gefunden war, damit es funktioniert.

Vielen Dank an Nikolay Melnikov. Ihr Kommentar / Ihre Antwort auf diese Frage hat dazu beigetragen, dass es funktioniert hat.

Kurz gesagt, hier ist mein AngularJS Service-Backend-Aufruf:

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

Von meinem 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

Letzte Antwort (für 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

Ein Vorschlag für Code, den ich gerade in meinem Projekt mit AngularJS v1.7.2 verwendet habe

$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
Bitte fügen Sie auch einige kurze hinzu.
Farhana
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.