Open pdf from bytes array in angular 5
Solution 1
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
Solution 2
I had the same problem with angular and pdf display. I will describe my solution - use base64 encoded string. All modern browsers support base64.
-
Use
import java.util.Base64
to decode your byte arraybyte[] bytes = baos.toByteArray(); String string = Base64.getEncoder().encodeToString(bytes); test.setByteString(string);
-
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);
-
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
MPPNBD
I am Developer working on the technologies like java,j2ee,angular5,HTML,CSS
Updated on May 27, 2021Comments
-
MPPNBD almost 3 years
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
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.
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; }
-
Roddy of the Frozen Peas almost 6 yearsThis only works because you're using an IFrame. Chrome removed top-level support for data URI's over a year ago.
-
Sunil Garg over 3 yearsstackoverflow.com/questions/63187758/… can you solve this
-
Sunil Garg over 3 yearscan you help on this stackoverflow.com/questions/63187758/…
-
Lakshman Pilaka over 2 yearsworked like charm. in the first attempt :)
-
Robin over 2 yearsAwesome, in .NET, with an IActionResult, I needed: return File(bytes, "application/pdf"); instead of returning Ok(bytes);