"I want to download a .pdf file sent from spring-based restful web service to my angular app. How to download it, am I missing some code on my angular app or spring boot?"
I am sending an HTTP GET request from an angular 6 app to my spring-boot server, which generates a .pdf file and then sends me this .pdf file as a blob, but when I try to create a blob on my angular side and open the pdf, it shows the following error :
. ERROR Error: The request body isn't either a blob or an array buffer
I have visited the following questions on StackOverflow, to find some solution: 1. PDF Blob is not showing content, Angular 2 2. How can I get access to the Angular 2 http response body without converting it to string or json? 3. converting byte stream in HTTPResponse body into a pdf file 4. Send File with SpringBoot to Angular2
In Angular app: component:
Service:getPDF(){ this.apiService.getPDF(this.invoiceId) .subscribe( (data) => { //data.blob() doesnt work properly var file = new Blob([data.blob()], { type: 'application/pdf' }) var fileURL = URL.createObjectURL(file); window.open(fileURL); // if you want to open it in new tab var a = document.createElement('a'); a.href = fileURL; a.target = '_blank'; a.download = 'bill.pdf'; document.body.appendChild(a); a.click(); }, (error) => { console.log('getPDF error: ',error); } ); }
getPDF(invoiceId : number)
{
this.url = this.main_url + '/invoices/generatepdf/'+invoiceId;
const headers = new Headers({ 'Content-Type': 'application/json',
"Authorization": authorization, responseType : 'blob'});
return this.http.get(this.url, { headers : headers})
.pipe(map(
(response) => {
return response;
},
(error) => {
console.log(error.json());
}
));
}
In Spring boot:
Controller:
@RestController
@RequestMapping("/invoices")
public class InvoiceController {
@Autowired
InvoiceService invoiceService;
@GetMapping(path = "/generatepdf/{invoiceId}")
public void generateInvoicePdf(@PathVariable Integer invoiceId,
HttpServletRequest request,HttpServletResponse response) {
invoiceService.generateInvoicePdf(invoiceId, request, response);
}
ServiceImplementation:
@Override
public String generateInvoicePdf(Integer invoiceId, HttpServletRequest request, HttpServletResponse response) {
//createPDF() will create a .pdf file
createPDF(pdfFilename, dto, dtoForSupplier);
if (pdfFilename != null) {
try {
File file = new File(pdfFilename);
FileInputStream is = new FileInputStream(file);
response.setContentType("application/blob");
// Response header
response.setHeader("Pragma", "public");
response.setHeader("responseType", "blob");
response.setHeader("Content-Disposition", "attachment; filename=\"" + pdfFilename + "\"");
// Read from the file and write into the response
OutputStream os = response.getOutputStream();
System.out.println(os);
byte[] buffer = new byte[(int) file.length()];
int len;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println(os);
os.flush();
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return pdfFilename;
}
I expect to download a .pdf file in the browser and open it and see its contents, but instead i get the error:
core.js:15724 ERROR Error: The request body isn't either a blob or an array buffer at Response.push../node_modules/@angular/http/fesm5/http.js.Body.blob (http.js:782) at SafeSubscriber._next (invoice-details.component.ts:212) at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:196) at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (Subscriber.js:134) at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next (Subscriber.js:77) at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54) at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:41) at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54) at XMLHttpRequest.onLoad (http.js:1070) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)>
ServiceImplementationchangeresponse.setContentType("application/pdf")or tell what is response do you get in angular? - Alireza Khajavi