Cómo mostrar blob (.pdf) en una aplicación AngularJS

Resuelto Simo Mafuxwana asked hace 10 años • 8 respuestas

He estado intentando mostrar un archivo pdf que obtengo como un blob de una $http.postrespuesta. El pdf debe mostrarse dentro de la aplicación usando, <embed src>por ejemplo.

Me encontré con un par de publicaciones de pila pero de alguna manera mi ejemplo no parece funcionar.

JS:

Según este documento , seguí y probé...

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

Ahora, según tengo entendido, fileURLcrea una URL temporal que el blog puede usar como referencia.

HTML:

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

No estoy seguro de cómo manejar esto en Angular, la situación ideal sería (1) asignarlo a un alcance, (2) 'preparar/reconstruir' el blob en un pdf (3) pasarlo al HTML usando <embed>porque desea mostrarlo dentro de la aplicación.

He estado investigando durante más de un día, pero de alguna manera parece que no puedo entender cómo funciona esto en Angular... Y supongamos que las bibliotecas del visor de PDF disponibles no eran una opción.

Simo Mafuxwana avatar Feb 07 '14 19:02 Simo Mafuxwana
Aceptado

En primer lugar, debe configurar el responseTypearchivo en arraybuffer. Esto es necesario si desea crear un blob de sus datos. Consulte Envío_y_recepción_datos_binarios . Entonces tu código se verá así:

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

La siguiente parte es que necesitas usar el servicio $sce para hacer que angular confíe en tu URL. Esto se puede hacer de esta manera:

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

No olvides inyectar el servicio $sce .

Si todo esto está hecho, ahora puede incrustar su pdf:

<embed ng-src="{{content}}" style="width:200px;height:200px;"></embed>
michael avatar Feb 12 '2014 15:02 michael

Yo uso AngularJS v1.3.4

HTML:

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

Controlador 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();
            });
        };
});

Servicios JS:

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

Servicios web Java 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;
    }
Stéphane GRILLON avatar May 22 '2015 19:05 Stéphane GRILLON

Las sugerencias de Michael funcionan de maravilla para mí :) Si reemplazas $http.post con $http.get, recuerda que el método .get acepta 2 parámetros en lugar de 3... aquí es donde pierdo el tiempo... ;)

controlador:

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

vista:

<object ng-show="content" data="{{content}}" type="application/pdf" style="width: 100%; height: 400px;"></object>
Jan Tchärmän avatar Jun 11 '2015 14:06 Jan Tchärmän