web-dev-qa-db-fra.com

Ouvrir le fichier pdf du tableau d'octets en mode angulaire 5

Je suivais les liens ci-dessous pour afficher la page pdf dans un nouvel onglet de mon application angular 5. Mais incapable d'obtenir le résultat.

Je consomme le tableau d'octets de l'API Spring Controller.

PDF Blob n'affiche pas le contenu, angulaire 2

PDF Blob - Une fenêtre contextuelle ne contenant pas de contenu

Angular2 Afficher PDF

J'ai essayé les options ci-dessous mais aucune d'entre elles ne fonctionne.

Trial 1

Consumé la réponse comme json

composant.ts

clickEvent(){
this.service.getPDF().subscribe((response)=>{

  let file = new Blob([response.byteString], { type: 'application/pdf' });            
  var fileURL = URL.createObjectURL(file);
  window.open(fileURL);
})

}

service.ts

getPDF(){
const url = `${this.serviceUrl}/pdf`;

const httpOptions = {
  headers: new HttpHeaders(
    {
      'Accept': 'application/json',
      'responseType':'blob'
    }
  )
};

return this.http.get<any>(url, httpOptions);

}

Trial 2

Consumé la réponse comme json

composant.ts

clickEvent(){
this.service.getPDF().subscribe((response)=>{

  let file = new Blob([response.byteArray], { type: 'application/pdf' });            
  var fileURL = URL.createObjectURL(file);
  window.open(fileURL);
})

}

service.ts

getPDF(){
const url = `${this.serviceUrl}/pdf`;

const httpOptions = {
  headers: new HttpHeaders(
    {
      'Accept': 'application/json',
      'responseType':'arraybuffer'
    }
  )
};

return this.http.get<any>(url, httpOptions);

}

Trial 3

Consumé la réponse en octets

composant.ts

clickEvent(){
this.service.getPDF().subscribe((response)=>{

  let file = new Blob([response], { type: 'application/pdf' });            
  var fileURL = URL.createObjectURL(file);
  window.open(fileURL);
})

}

service.ts

getPDF(){
const url = `${this.serviceUrl}/pdf`;

const httpOptions = {
  headers: new HttpHeaders(
    {
      'responseType':'blob'                 //both combination
      //'responseType'  : 'arraybuffer'
    }
  )
};

return this.http.get<any>(url, httpOptions);

}

La combinaison obtenue ne donne que deux résultats . Document pdf vide ou Échec de chargement du document PDF. 

 enter image description here

 enter image description here

Pour comprendre l’affichage du code du contrôleur de ressort Java.

contrôleur.Java

@GetMapping(value = "/pdf")
public ResTest generatePDF(HttpServletResponse response) throws IOException {
    ResTest test = new ResTest();
    ByteArrayOutputStream baos = docTypeService.createPdf();
    test.setByteArray(baos.toByteArray());
    test.setByteString(new String(baos.toByteArray()));
    return test;
}
4
MPPNBD

Enfin, j'ai pu rendre le pdf. Il y avait deux petites erreurs de mon côté.

Le 1 er problème était que j'ai donné 'responseType' à l'intérieur de HttpHeaders, ce qui était faux ... Il devrait être à l'extérieur comme ci-dessous.

Le 2 ème problème était, même si vous mentionnez comme responseType: 'arraybuffer', il était incapable de le prendre. Pour cela, vous devez mentionner en tant que responseType: 'arraybuffer' en tant que 'json'. ( Reference )

Le code corrigé et fonctionnel ci-dessous.

Trial 3

composant.ts (nochanges)

clickEvent(){
  this.service.getPDF().subscribe((response)=>{

  let file = new Blob([response], { type: 'application/pdf' });            
  var fileURL = URL.createObjectURL(file);
  window.open(fileURL);
})

service.ts

getPDF(){
const url = `${this.serviceUrl}/pdf`;

const httpOptions = {
  'responseType'  : 'arraybuffer' as 'json'
   //'responseType'  : 'blob' as 'json'        //This also worked
};

return this.http.get<any>(url, httpOptions);

}

Référé du lien ci-dessous

https://github.com/angular/angular/issues/18586

3
MPPNBD

J'ai eu le même problème avec l'affichage angulaire et pdf. Je vais décrire ma solution - utiliser une chaîne encodée en base64. Tous les navigateurs modernes supportent base64.

  1. Utilisez import Java.util.Base64 pour décoder votre tableau d'octets

    byte[] bytes = baos.toByteArray();
    
    String string = Base64.getEncoder().encodeToString(bytes);
    
    test.setByteString(string);
    
  2. Sur le côté frontal, utilisez le type mime standard pour pdf et indiquez que vous utilisez base64 data:application/pdf;base64,

    Réf. mime les types: https://en.wikipedia.org/wiki/Media_type

    Si vous devez ouvrir le document dans une nouvelle fenêtre:

    let newPdfWindow = window.open("","Print");
    
    let content = encodeURIComponent(response.byteString);
    
    let iframeStart = "<\iframe width='100%' height='100%' src='data:application/pdf;base64, ";
    
    let iframeEnd = "'><\/iframe>";
    
    newPdfWindow.document.write(iframeStart + content + iframeEnd);
    
  3. Si vous avez besoin d'ouvrir un nouvel onglet, vous pouvez simplement fournir à votre href HTML:

    let pdfHref = this.sanitizer.bypassSecurityTrustUrl('data:application/octet-stream;base64,' + content);
    

    bypassSecurityTrustUrl va désinfecter votre URL. Si je me souviens bien, il y avait un problème de sécurité angulaire qui m'a empêché de voir le contenu.

PS. Avant de vérifier son fonctionnement avec Angular, je vous recommande de stocker le fichier pdf sur un lecteur et d’essayer de l’ouvrir. Je veux dire, que vous devez être certain que votre fichier est valide et que vous pouvez l’ouvrir avec un simple lecteur.

Mettre à jour. La solution la plus simple consiste à utiliser la bibliothèque pdf.js https://github.com/mozilla/pdf.js

2

Avez-vous cherché un composant angulaire pour envelopper pdf.js?

Exemple d'utilisation:

<pdf-viewer [src]="pdfSrc" 
    [render-text]="true"
    style="display: block;">
</pdf-viewer>

pdfSrc peut être une URL string ou un UInt8Array

0
Chris White