title: How to download a pdf file in angular which is generated on my server(springboot)?
body: <p>"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?"</p>
  
  <p>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 : </p>
  
  <p>. ERROR Error: The request body isn't either a blob or an array buffer</p>
  
  <p>I have visited the following questions on StackOverflow, to find some solution:
  1. <a href="https://stackoverflow.com/questions/37046133/pdf-blob-is-not-showing-content-angular-2">PDF Blob is not showing content, Angular 2</a>
  2. <a href="https://stackoverflow.com/questions/36087145/how-can-i-get-access-to-the-angular-2-http-response-body-without-converting-it-t">How can I get access to the Angular 2 http response body without converting it to string or json?</a>
  3. <a href="https://stackoverflow.com/questions/51633734/converting-byte-stream-in-httpresponse-body-into-a-pdf-file">converting byte stream in HTTPResponse body into a pdf file</a>
  4. <a href="https://stackoverflow.com/questions/51417520/send-file-with-springboot-to-angular2">Send File with SpringBoot to Angular2</a></p>
  
  <p><strong>In Angular app:</strong>
  <em>component:</em>
     <pre> </p>
  
  <pre><code>getPDF(){
        this.apiService.getPDF(this.invoiceId)
        .subscribe(
          (data) =&gt; {
            //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) =&gt; {
            console.log('getPDF error: ',error);
          }
        );
      }
  </code></pre>
  
  <p></pre>
  <em>Service:</em></p>
  
  <pre>
  
      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());
                       }
                   ));
           }
  
  </pre>
  
  <p><strong>In Spring boot:</strong></p>
  
  <p><em>Controller:</em></p>
  
  <pre>
  
      @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);
      }
  
  </pre>
  
  <p><em>ServiceImplementation:</em></p>
  
  <pre>
  
      @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;
          }
  
  </pre>
  
  <p>I expect to download a .pdf file in the browser and open it and see its contents, but instead i get the error:</p>
  
  <blockquote>
    <p>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)></p>
  </blockquote>