Як відобразити крапку (.pdf) у програмі AngularJS


106

Я намагався відобразити pdf-файл, який я отримую як $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>

Я не впевнений, як впоратися з цим у Angular, ідеальною ситуацією було б (1) призначити його області, (2) "підготувати / відновити" крапку в pdf (3) передати його в HTML, використовуючи, <embed>тому що я хочу відобразити його в додатку.

Я займаюся дослідженнями вже більше доби, але я якось не можу зрозуміти, як це працює в Angular ... І давайте просто припустимо, що бібліотеки для перегляду PDF не існують.


Привіт D'lo DeProjuicer, чи вдалося вам вирішити проблему створення PDF через кутовий фіксований?
Реймонд Накампе

@michael D'lo DeProjuicer Що робити для того ж випадку в кутку 2?
моніка

Відповіді:


214

Перш за все , вам потрібно встановити responseTypeна arraybuffer. Це потрібно, якщо ви хочете створити крапку своїх даних. Див. Відправлення_і_Приймання_Бінарні_Дані . Отже ваш код буде виглядати приблизно так:

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

9
Для мене це не спрацювало в Chrome (35.0.1916.114 м). Вирішили це за допомогою <object> замість <embed>: <object data = "{{content}}" type = "application / pdf"> </object>
HoffZ

2
Для мене (AngularJS 1,25) мені довелося зробити: новий Blob ([відповідь.дані]
Мартін Коннелл

2
@HoffZ: Я замінив метод ярлика $http.getна повний, вказавши responseTypeполе: { 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' }І він працює :)
Микола Мельников

1
Для мене єдиний спосіб змусити його працювати було створити блоб з response.dataзамість response, як це:var file = new Blob([response.data], {type: 'application/pdf'});
Alekos Filini

1
@ yosep-kim це не працює на IE, оскільки об’єкт URL не існує в IE: caniuse.com/#search=URL
Carlos

32

Я використовую 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;
    }

яка версія сафарі? window.URL хороший в сафарі 9 і після: caniuse.com/#search=createObjectURL
Stéphane GRILLON

Я тестував і перевіряв свої версії на своїх MacBook Pro та safari 9.0.2.
Стефан ГРІЛЛОН

Це ж, капітан macBook el. window.URL.createObjectURL (файл); Я не знаю, де проблема, але код не працює. Можливо, я роблю щось не так. Будь-яке спасибі Я не встиг перевірити, що це не працює, і використовувати FileSaver.js
fdrv

якщо ваша заявка в Інтернеті, опублікуйте, будь ласка, свою URL-адресу? у вас такий самий бек-енд?
Стефан ГРІЛОН

атрибут завантаження не підтримується в сафарі. caniuse.com/#search=download
Biswanath

21

Пропозиції michael для мене спрацьовують як шарм :) Якщо ви заміните $ http.post на $ http.get, пам’ятайте, що метод .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>

responseType:'arraybuffer', щойно врятував мені пару годин сну! +1
сварог

як запустити збереження замість того, щоб надрукувати його в html?
fdrv

спасибі, це врятувало мені пару годин, ви можете також замінити $scope.content = $sce.trustAsResourceUrl(fileURL);з $window.open(fileURL, '_self', '');і відкрити файл на весь екран.
Тавітос

9

Я зіткнувся з труднощами використання "window.URL" з браузером Opera, оскільки це призведе до "невизначеності". Крім того, з window.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);
    }
}

Дайте мені знати, чи допомогло це! :)


Цей підхід не відкриває документ PDF у вікні браузера в IE, але спонукає користувача завантажити його. Чи є якась робота навколо цього?
sdd

1
Вищенаведений код - завантажити файл PDF та дозволити його відкрити програмі PDF Reader за замовчуванням, щоб відкрити її. Він навіть добре працює на мобільних пристроях. Причина полягає в тому, що, коли мені вдалося відкрити PDF у деяких браузерах, я не зміг його відкрити в інших. Тому я подумав, що найкраще мати рішення, яке буде працювати на всіх браузерах (включаючи мобільні браузери), щоб завантажити файл PDF.
Мануель Ернандес

Ви можете використовувати наступний код для перегляду PDF-файлу на новій вкладці: window.open (reader.result, '_blank');
самнерік

6

Додавання responseType на запит , який зроблений з кутового дійсно рішення, але для мене це не робота , поки я безліч responseType для згустку , а чи не до 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) {   
        });

2
власне, з 'blob'типом можна писати коротше: FileSaver.saveAs(response.data, getFileNameFromHttpResponse(response));Не потрібно створюватиBlob
Alena Kastsiukavets

0

Протягом останніх кількох днів я намагався завантажити файли pdfs та зображення, все, що мені вдалося завантажити, - це прості текстові файли.

Більшість запитань мають однакові компоненти, але потрібен певний час, щоб з’ясувати правильний порядок роботи.

Дякую @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
    });
}

0

Остання відповідь (для кутових 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

Пропозиція коду, яку я щойно використав у своєму проекті, використовуючи AngularJS v1.7.2

$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
будь-ласка, додайте також короткий текст.
Farhana
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.