AngularJS uygulamasında blob (.pdf) nasıl görüntülenir


106

Bir $http.postyanıttan blob olarak aldığım pdf dosyasını görüntülemeye çalışıyorum . <embed src>Örneğin pdf, uygulama içinde görüntülenmelidir .

Birkaç yığın gönderi ile karşılaştım ama bir şekilde örneğim işe yaramıyor.

JS:

Bu belgeye göre , devam ettim ve denedim ...

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

Şimdi anladığım kadarıyla, fileURLblogun referans olarak kullanabileceği geçici bir URL oluşturuyor.

HTML:

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

Bunu Angular'da nasıl ele alacağımdan emin değilim, ideal durum (1) onu bir kapsama atamak, (2) blob'u bir pdf'ye 'hazırlamak / yeniden oluşturmak' (3) kullanarak HTML'ye geçirmek olacaktır <embed>çünkü ben uygulama içinde görüntülemek istiyorum.

Bir günden fazla bir süredir araştırma yapıyorum ama bir şekilde bunun Angular'da nasıl çalıştığını anlayamıyorum ... Ve sadece oradaki pdf görüntüleyici kitaplıklarının bir seçenek olmadığını varsayalım.


Merhaba D'lo DeProjuicer, PDF'yi açısal düzeltmeyle oluşturma sorununuzu çözdünüz mü?
Raymond Nakampe

@michael D'lo DeProjuicer Açısal 2'de aynı durum için ne yapılmalı?
monica

Yanıtlar:


214

Her şeyden önce ayarlamak gerekir responseTypeiçin arraybuffer. Verilerinizden bir damla oluşturmak istiyorsanız bu gereklidir. Bkz. Sending_and_Receiving_Binary_Data . Yani kodunuz şöyle görünecek:

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

Sonraki kısım, url'nize açısal güven sağlamak için $ sce hizmetini kullanmanız gerektiğidir . Bu şu şekilde yapılabilir:

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

$ Sce hizmetini enjekte etmeyi unutmayın .

Bunların hepsi bittiyse, şimdi pdf'nizi yerleştirebilirsiniz:

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

9
Benim için bu Chrome'da işe yaramadı (35.0.1916.114 m). Bunu <embed> yerine <object> kullanarak
çözdüm

2
Benim için (AngularJS 1.25) Yapmam gereken: yeni Blob ([response.data]
Martin Connell

2
@HoffZ: Kısayol yöntemini alanı $http.getbelirterek tam bir yöntemle değiştirdim 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' }Ve çalışıyor :)
Nikolay Melnikov

1
Benim için bunu çalıştırmanın tek yolu response.databunun yerine blob oluşturmaktı response:var file = new Blob([response.data], {type: 'application/pdf'});
Alekos Filini

1
@ yosep-kim IE'de URL nesnesi olmadığı için bu IE'de çalışmaz: caniuse.com/#search=URL
Carlos

32

AngularJS v1.3.4 kullanıyorum

HTML:

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

JS denetleyicisi:

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

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 Hizmetleri - 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;
    }

safarinin hangi versiyonu? window.URL, safari 9'da ve sonrasında iyidir: caniuse.com/#search=createObjectURL
Stéphane GRILLON

MacBook pro ve safari 9.0.2'de test ettim ve doğruladım.
Stéphane GRILLON

Aynı, macBook el kaptanı. window.URL.createObjectURL (dosya); Sorun nerede bilmiyorum ama kod çalışmıyor. Yanlış bir şey yapıyor olabilirim. Herhangi bir teşekkür ederim. Neyin çalışmadığını kontrol edecek ve FileSaver.js'yi kullanacak
vaktim yok

Başvurunuz çevrimiçiyse, lütfen URL'nizi gönderin. aynı Back-End'e mi sahipsiniz?
Stéphane GRILLON

indirme özelliği safaride desteklenmez. caniuse.com/#search=download
Biswanath

21

michael'ın önerileri benim için bir cazibe gibi çalışıyor :) $ http.post'u $ http.get ile değiştirirseniz, .get yönteminin 3 yerine 2 parametreyi kabul ettiğini unutmayın ... burası benim zamanımı boşa harcıyor ...;)

denetleyici:

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

görünüm:

<object ng-show="content" data="{{content}}" type="application/pdf" style="width: 100%; height: 400px;"></object>

responseType:'arraybuffer', beni birkaç uyku saatinden kurtardı! +1
svarog

html olarak yazdırmak yerine kaydetme nasıl tetiklenir?
fdrv

Bu bana birkaç saat kurtardı, teşekkür ederim, ayrıca yerini alabilir $scope.content = $sce.trustAsResourceUrl(fileURL);ile $window.open(fileURL, '_self', '');ve tam ekran ve dosyayı açın.
Tavitos

9

Opera Tarayıcısı ile "window.URL" yi kullanırken "undefined" ile sonuçlanacağı için zorluklarla karşılaştım. Ayrıca, window.URL ile, PDF belgesi hiçbir zaman Internet Explorer ve Microsoft Edge'de açılmaz (sonsuza kadar beklemeye devam eder). IE, Edge, Firefox, Chrome ve Opera'da çalışan aşağıdaki çözümü buldum (Safari ile test etmedim):

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

Yardımı olup olmadığını bana bildirin! :)


Bu yaklaşım, PDF belgesini IE'de tarayıcı penceresinde açmaz, ancak kullanıcıdan onu indirmesini ister. Bunun etrafında herhangi bir çalışma var mı?
sdd

1
Yukarıdaki kod, PDF dosyasını indirmek ve varsayılan PDF Reader uygulamanızın onu açmasına izin vermektir. Mobil cihazlarda bile iyi çalışıyor. Nedeni şu ki, PDF'yi bazı tarayıcılarda açabilsem de diğer tarayıcılarda açamadım. Bu yüzden, PDF dosyasını indirmek için tüm tarayıcılarda (mobil tarayıcılar dahil) çalışacak bir çözüme sahip olmanın en iyisi olduğunu düşündüm.
Manuel Hernandez

PDF'yi yeni bir sekmede görüntülemek için aşağıdaki kodu kullanabilirsiniz: window.open (reader.result, '_blank');
samneric

6

Ekleme responseType açısal yapılır isteğine gerçekten çözüm, ancak set ettik kadar benim için işi yoktu responseType için damla değil, arrayBuffer için. Kod kendinden açıklamalıdır:

    $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
aslında 'blob'FileSaver.saveAs(response.data, getFileNameFromHttpResponse(response));Blob
yazımla

0

Son birkaç gündür pdf'leri ve resimleri indirmeye çalışırken mücadele ettim, indirebildiğim tek şey basit metin dosyalarıydı.

Soruların çoğu aynı bileşenlere sahiptir, ancak doğru sırayı bulmak biraz zaman aldı.

Teşekkürler @Nikolay Melnikov, yorumunuz / bu soruya cevabınız, onu işe yarayan şeydi.

Özetle, işte AngularJS Hizmeti arka uç çağrım:

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

Denetleyicimden:

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

En son cevap (Angular 8+ için):

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'yi kullanarak projemde az önce kullandığım bir kod önerisi

$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
lütfen biraz da özet ekleyin.
Farhana
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.