Affichage de la goutte (.pdf) dans une application angulaire

j'ai essayé d'afficher le fichier pdf que je reçois comme un blob à partir d'une réponse $http.post . Le pdf doit être affiché dans l'application en utilisant <embed src> par exemple.

je suis tombé sur un couple de poteaux de pile mais d'une certaine façon mon exemple ne semble pas fonctionner.

JS:

selon CE doc , j'ai continué et essayé...

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

D'après ce que j'ai compris, fileURL crée une URL temporaire que le blog peut utiliser comme référence.

HTML:

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

Je ne sais pas comment gérer cela en angle, la situation idéale serait (1) assignez-le à une portée, (2) 'préparer/reconstruire le blob en pdf (3) passer au HTML en utilisant <embed> parce que Je veux l'afficher dans l'application.

j'ai fait des recherches depuis plus d'un jour maintenant mais d'une certaine façon je ne peux pas comprendre comment cela fonctionne en angle... Et supposons que les bibliothèques de visualisation de pdf là-bas n'étaient pas une option.

92
demandé sur picciano 2014-02-07 16:56:17

6 réponses

tout d'Abord, vous devez définir le responseType à arraybuffer . Cela est nécessaire si vous souhaitez créer un blob de vos données. Voir Sending_and_Receiving_Binary_Data . Votre code ressemblera donc à ceci:

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

la partie suivante est, vous devez utiliser le service $sce pour faire confiance angular à votre url. Cela peut être fait de cette manière:

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

N'oubliez pas d'injecter de l' $ sce service.

Si cela est fait, vous pouvez maintenant intégrer votre pdf:

<embed ng-src="{{content}}" style="width:200px;height:200px;"></embed>
186
répondu michael 2014-02-12 15:22:53

J'utilise AngularJS v1.3.4

HTML:

<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>

JS contrôleur:

'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 services:

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;
    }
29
répondu sgrillon 2015-08-26 07:03:14

les suggestions de michael me vont à ravir :) Si vous remplacez $http.post avec $ http., souvenez-vous que l' .la méthode get accepte 2 paramètres au lieu de 3... c'est là perdu mon temps... ;)

contrôleur:

$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>
19
répondu Jan Tchärmän 2016-09-07 08:22:39

j'ai fait face à des difficultés à l'aide de la fenêtre".URL" avec Navigateur Opera qu'elle conduirait à "undefined". Aussi, avec fenêtre.URL, le document PDF jamais ouvert dans Internet Explorer et Microsoft Edge (il resterait en attente pour toujours). J'ai trouvé la solution suivante qui fonctionne dans IE, Edge, Firefox, Chrome et Opera (n'ont pas testé avec 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);
    }
}

dites-moi si ça a aidé! :)

10
répondu Manuel Hernandez 2016-01-08 21:41:18

ajouter responsabiletype à la demande qui est faite à partir d'angular est en effet la solution, mais pour moi , il n'a pas fonctionné jusqu'à ce que j'ai mis responsabiletype à blob , pas à arrayBuffer. Le code est explicite:

    $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
répondu ancab 2017-03-27 08:20:45

j'ai lutté ces derniers jours pour télécharger des fichiers PDF et des images,tout ce que j'ai pu télécharger était des fichiers textes simples.

la plupart des questions ont les mêmes composantes, mais il a fallu un certain temps pour trouver le bon ordre pour le faire fonctionner.

Merci @Nikolay Melnikov, votre commentaire / réponse à cette question était ce qui l'a fait fonctionner.

en un mot, voici mon service AngularJS 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'
    });
  }

de mon contrôleur:

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
répondu Javier Carbajal 2017-01-25 06:05:03