it-swarm.com.de

Blob (.pdf) in einer Winkel-App anzeigen

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

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

JS:

Nach diesem Dokument ging ich weiter und versuchte es ...

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

Nach meinem Verständnis erstellt fileURL eine temporäre URL, die das Blog als Referenz verwenden kann.

HTML:

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

Ich bin mir nicht sicher, wie man mit Angular umgehen soll. Die ideale Situation wäre, (1) einen Bereich zuzuweisen, (2) den Blob "vorbereiten/umbauen" in einem pdf 3) übergeben Sie es mit <embed> an das HTML, da ich es in der App anzeigen möchte.

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

96

Zunächst müssen Sie die Variable responseType auf arraybuffer setzen. Dies ist erforderlich, wenn Sie einen Blob Ihrer Daten erstellen möchten. Siehe Sending_and_Receiving_Binary_Data . Ihr Code wird also so aussehen:

$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, Sie müssen den Dienst $ sce verwenden, um die Vertrauenswürdigkeit Ihrer URL zu erreichen. Dies kann auf folgende Weise geschehen:

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

Vergessen Sie nicht, den Dienst $ sce zu injizieren.

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

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

Ich verwende 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 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;
    }
30
sgrillon

michaels Vorschläge funktionieren für mich wie ein Zauber:) Wenn Sie $ http.post durch $ http.get ersetzen, denken Sie daran, dass die .get-Methode 2 Parameter anstelle von 3 akzeptiert. .;)

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>
20
Jan Tchärmän

Ich hatte Schwierigkeiten, "window.URL" mit Opera Browser zu verwenden, da dies zu "undefined" führen würde. Mit window.URL wurde das PDF -Dokument nie in Internet Explorer und Microsoft Edge 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! :)

10

Das Hinzufügen von responseType zu der Anfrage, die von angle erfolgt, ist zwar die Lösung, aber für mich hat es nicht funktioniert, bis ich responseType auf blob gesetzt habe, nicht auf 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) {   
        });
6
ancab

Ich hatte in den letzten Tagen Probleme beim Herunterladen von PDFs und Bildern. Ich konnte nur einfache Textdateien herunterladen.

Die meisten Fragen haben die gleichen Komponenten, aber es hat eine Weile gedauert, bis die richtige Reihenfolge ermittelt wurde.

Vielen Dank @Nikolay Melnikov, Ihr Kommentar/Ihre Antwort auf diese Frage war, warum sie funktioniert hat.

Kurz gesagt, hier ist mein Backend-Aufruf für den AngularJS-Service:

  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
Javier Carbajal