Отображение BLOB-объектов (.pdf) в угловом приложении

Я пытался отобразить pdf-файл, который я получаю как blob от $http.post ответ. 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) 'подготовка / восстановление' blob в pdf (3) передайте его в HTML с помощью <embed> потому что я хочу, чтобы отобразить его в приложении.

Я исследовал больше дня, но почему-то я не могу понять, как это работает в Угловатый... И давайте просто предположим, что библиотеки просмотра pdf не были вариантом.

6 ответов


прежде всего вам нужно установить responseType to arraybuffer. Это необходимо, если вы хотите создать объект ваших данных. См.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>

Я использую 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-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;
    }

предложения Майкла работает как шарм для меня :) Если вы замените $http.сообщение с $http.вам, помните, что .метод get принимает 2 параметра вместо 3... здесь я зря трачу время... ;)

:
$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>

я столкнулся с трудностями, используя " окно.URL "с браузером Opera, поскольку это приведет к"неопределенному". Также, с окном.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);
    }
}

Дайте мне знать, если это помогло! :)


добавлять responseType на запрос, который сделан из углового, действительно решение, но для меня это не сработало, пока я не установил responseType to blob, Не для 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) {   
        });

я боролся за последние пару дней, пытаясь загрузить 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
    });
}