2

I am trying to implement logic of download pdf from db on angular 5. I am facing issue in download file. File gets downloaded but throws error on opening -"Failed to load".

I have looked at so many blogs and question/answers but not able to find the mistake in my code.

In Database -> pdf file content saved as BLOB

Rest web service -> In below code pdfData is the data from BLOB type column, which is byte[] in java code here

@GetMapping("downloadReport/{reportId}")
public StreamingResponseBody downloadDocument(byte[] pdfData) {
        return outputStream -> {
        //This way working for sample
            /*try (InputStream inputStream = new ByteArrayInputStream(
                    Files.readAllBytes(Paths.get("D:/pdfWithoutPassword.pdf")))) {
                IOUtils.copy(inputStream, outputStream);
            }*/
        //This way not working when data fetched from Database
            try (InputStream inputStream = new ByteArrayInputStream(pdfData)) {
                IOUtils.copy(inputStream, outputStream);
            }
            outputStream.close();
        };

Angular 5 code

downloadReport(reportType: string, reportId: string) {
        let fileDownloadUrl = environment.apiUrl + "/downloadReport" + "/" + reportId;

        return this.httpClient
            .get(fileDownloadUrl, { observe: 'response', responseType: "blob"})
            .subscribe(response => this.saveFileToSystem(response.body)),
            error => console.log("Error downloading the file."),
            () => console.info("OK");
    }

       saveFileToSystem(input: any) {
        const blob = new Blob([input], { type: 'application/octet-stream' });
        saveAs(blob, "testingpdf1.pdf");
    }

Looking for help in solving this. Thanks in advance!

4
  • can you share stackblitz so that we can edit ? Commented Nov 29, 2018 at 7:20
  • or response you are getting from server side Commented Nov 29, 2018 at 7:21
  • Have a look at this Commented Nov 29, 2018 at 7:24
  • Thank you for all your comments. Check everything and will reply. Also will edit the que as per comments Commented Dec 3, 2018 at 6:13

2 Answers 2

1

Here another way I did it you you can change :

@RequestMapping(value = "/generateReport", method = RequestMethod.POST)
  public ResponseEntity<byte[]> generateReport(){

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.parseMediaType("application/pdf"));
    StringBuilder filename = new StringBuilder("MyPdfName").append(".pdf");

    byte[] bytes = pdfGeneratorService.generatePDF();
    headers.add("content-disposition", "inline;filename=" + filename.toString());

    headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
    ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
    return response;
}
Sign up to request clarification or add additional context in comments.

Comments

0

Try this :

From your html page

 <a href="javascript:void(0);" (click)="generatePdf()"> YourPdf.pdf </a>

From your js file

generatePdf() {

this.yourService.generatePdf()
     .subscribe(pdf => {
     let mediaType = 'application/pdf';
     let blob = new 
     Blob([this.converterService.base64ToArrayBuffer(pdf.pdfByteArray)], { type: mediaType });
    saveAs(blob, fileName);
  }, err => {
    console.log('Pdf generated err: ', JSON.stringify(err));
  });

}

Your converter service:

import { Injectable } from "@angular/core";

@Injectable()
export class ConverterService {

base64ToArrayBuffer(base64) {
    var binaryString = window.atob(base64);
    var binaryLen = binaryString.length;
    var bytes = new Uint8Array(binaryLen);
    for (var i = 0; i < binaryLen; i++) {
        var ascii = binaryString.charCodeAt(i);
        bytes[i] = ascii;
    }
      return bytes;
   }
  }

2 Comments

Thank you @Irshaad it worked along with your server side code. But with a small change in UI code. I have not used converter service on UI side. Here is my UI side code :
downloadt(reportId: string) { let fileDownloadUrl = environment.apiUrl + "orderHistory/test"; return this.httpClient .get(fileDownloadUrl, { observe: 'response', responseType: "blob" }) .subscribe(response => {this.saveFile(response.body)}, err => { console.log('err: ', JSON.stringify(err)); }); } saveFile(input: any) { const blob = new Blob([input], { type: 'octet/stream' }); saveAs(blob, "a.pdf"); }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.