0

I am trying to download a runtime generated PDF file (PDF generated using iTextPDF) in Springboot Service and want to open that file in new tab via angular 6.0. I tried to follow this How to download a pdf file in angular which is generated on my server(springboot)? but getting error as 'Failed to load PDF document'. What is wrong in code?

Angular Compomnent:

this.service.PrintPDF(this.quotations).subscribe((data: Blob) => {
      var file = new Blob([data], { type: 'application/pdf' })
      var fileURL = URL.createObjectURL(file);

// if you want to open PDF in new tab
      window.open(fileURL); 
      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);
    }
  );

Angular Service:

PrintPDF(quotations: Quotation[]) {

        let url = this.PDF_URL;
        var authorization = 'Bearer ' + sessionStorage.getItem("key");

        const headers = new HttpHeaders({
            'Content-Type': 'application/json',
            responseType: 'blob',
            "Authorization": authorization
        });

        return this.http.post<Blob>(url, quotations, {
            headers: headers, responseType:'blob' as 'json'}).pipe(map(
            (response) => {
                return response;
            },
            (error) => {console.log(error.json());}
        ));

Springboot Controller:

@PostMapping(value = "/generatepdf")
    public void downloadFile(@RequestBody List<QuotationDTO> quotationDTOs, HttpServletRequest request, HttpServletResponse response) {

        try {
            quotationService.GeneratePDF(quotationDTOs, request, response);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

Springboot Service:

public String  GeneratePDF(java.util.List<QuotationDTO> quotationDTOs, HttpServletRequest request,
                           HttpServletResponse response) throws DocumentException, IOException {

        response.setContentType("application/blob");

        // Response header
        response.setHeader("Pragma", "public");
        response.setHeader("responseType", "blob");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + "Quotation" + "\"");
//        OutputStream os = response.getOutputStream();

        Document document = new Document(PageSize.A4, 50, 50, 5 , 5);
        String current = sdf.format(new Timestamp(System.currentTimeMillis())).toString();
        String reportName = "report"+current;

        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(<Path>));
        document.open();
        // Write Content
        document.close();
        PdfWriter.getInstance(document, response.getOutputStream());

        return reportName+".pdf";
    }
Harshal
  • 77
  • 2
  • 12

1 Answers1

0

I found solution to my problem. I was trying to send PDF from in memory. Now creating pdf on a location and sending reading it from that location. Not sure if iTextPDF supports in memory pdf creation.

Springboot service:

public Resource GeneratePDF(java.util.List<QuotationDTO> quotationDTOs, HttpServletRequest request)
        throws DocumentException, IOException {
    Document document = new Document(PageSize.A4, 50, 50, 5 , 5);
    String current = sdf.format(new Timestamp(System.currentTimeMillis())).toString();
    String reportName = "report"+current;
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("PATH"));
    document.open();
    //Write PDF
    document.close();
    try {
        Path filePath = this.fileStorageLocation.resolve(reportName+".pdf").normalize();
        Resource resource = new UrlResource(filePath.toUri());
        if (resource.exists()) {
            return resource;
        } else {
            throw new MyFileNotFoundException("File not found " + reportName+".pdf");
        }
    } catch (MalformedURLException ex) {
        throw new MyFileNotFoundException("File not found " + reportName+".pdf", ex);
    }
}

Springboot Controller:

@PostMapping(value = "/generatepdf")
public ResponseEntity<Resource> downloadFile(@RequestBody List<QuotationDTO> quotationDTOs, HttpServletRequest request) {

    try {
        Resource resource = quotationService.GeneratePDF(quotationDTOs, request);
        String contentType = null;
        try {
            contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
        } catch (IOException ex) {
        }
        // Fallback to the default content type if type could not be determined
        if(contentType == null) {
            contentType = "application/octet-stream";
        }
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                .body(resource);

    } catch (DocumentException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

Angular Service:

PrintPDF(quotations: Quotation[]) {
    let url = this.PDF_URL;
    var authorization = 'Bearer ' + sessionStorage.getItem("key");
    let headerOptions = new HttpHeaders({
        'Content-Type': 'application/json',
        'Accept': 'application/pdf',
        "Authorization": authorization
        //   'Accept': 'application/octet-stream', // for excel file
    });
    let requestOptions = { headers: headerOptions, responseType: 'blob' as 'blob' };
    this.http.post(url, quotations, requestOptions).pipe(map((data: any) => {
        let blob = new Blob([data], {
            type: 'application/pdf' // must match the Accept type
            // type: 'application/octet-stream' // for excel 
        });
        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        // link.download = 'samplePDFFile.pdf';
        link.target = '_blank';
        link.click();
        window.URL.revokeObjectURL(link.href);

    })).subscribe((result: any) => {
    });
}

Angular Component is just calling Angular Service

Harshal
  • 77
  • 2
  • 12