16

I was following the below links for displaying pdf page in new tab in my angular 5 application. But unable to achieve the result.

I am consuming the bytes array from spring controller api.

PDF Blob is not showing content, Angular 2

PDF Blob - Pop up window not showing content

Angular2 Displaying PDF

I tried the below options but none of them is working.

Trial 1

Consumed the response as json

component.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

Consumed the response as json

component.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

Consumed the response as bytes

component.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);

}

By all the combination I am only getting two results. Empty pdf document or Failed to load PDF document.

enter image description here

enter image description here

For understanding posting java spring controller code.

controller.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;
}
Leandro Bardelli
  • 10,561
  • 15
  • 79
  • 116
MPPNBD
  • 1,566
  • 4
  • 20
  • 36

5 Answers5

32

At last, I was able to render pdf. There were two small mistakes from my side.

1 st Problem was, I gave 'responseType' inside HttpHeaders which was wrong. It should be outside as below.

2 nd Problem was, even though if you mention as responseType : 'arraybuffer', it was unable to take it. For that you need to mention as responseType : 'arraybuffer' as 'json'.(Reference)

The corrected and working code below.

Trial 3

component.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);

}

Referred from the below link

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

MPPNBD
  • 1,566
  • 4
  • 20
  • 36
4

I had the same problem with angular and pdf display. I will describe my solution - use base64 encoded string. All modern browsers support base64.

  1. Use import java.util.Base64 to decode your byte array

    byte[] bytes = baos.toByteArray();
    
    String string = Base64.getEncoder().encodeToString(bytes);
    
    test.setByteString(string);
    
  2. On the frontend side use standard mime type for pdf and indicate that you are using base64 data:application/pdf;base64,.

    Ref. to mime types: https://en.wikipedia.org/wiki/Media_type

    If you need to open document in a new window:

    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. If you need to open in a new tab, you may simply provide to your html href:

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

    bypassSecurityTrustUrl will sanitize your url. As I remember there was some problem with angular security, that prevented me from seeing the content.

PS. before checking how it works with angular I would like to recommend you to store the pdf file on a drive and try to open it. I mean, that you should be certainly sure that you file is valid and you may open it with simple reader.

Update. The simpliest solution is to use pdf.js library https://github.com/mozilla/pdf.js

piet.t
  • 11,718
  • 21
  • 43
  • 52
Dmitrii Cheremisin
  • 1,498
  • 10
  • 11
  • This only works because you're using an IFrame. Chrome removed top-level support for data URI's [over a year ago](https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/GbVcuwg_QjM/GsIAQlemBQAJ). – Roddy of the Frozen Peas May 09 '18 at 20:01
  • https://stackoverflow.com/questions/63187758/issue-while-printing-pdf-files-from-blob-agnular can you solve this – Sunil Garg Aug 01 '20 at 07:22
0

Have you looked for an angular component to wrap pdf.js?

Sample usage:

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

pdfSrc can be a url string or a UInt8Array

Chris White
  • 29,949
  • 4
  • 71
  • 93
0

When you make AJAX call to get PDF/file stream

var req = this.getYourPDFRequest(fd);
    this.postData(environment.previewPDFRFR, req).then(res => {
      res.blob().then(blob => {
         const fileURL = URL.createObjectURL(blob);
        window.open(fileURL, '', 'height=650,width=840');
      })
    });
0

If ur byte array comes from a .net backend u have to return

return File(doc.BinaryData, "application/pdf"); // page visible in typescript

, and not this :

return Ok(doc.BinaryData); // page blank in typescript

SSchmid
  • 431
  • 4
  • 3