Return generated pdf using spring MVC

148,789

You were on the right track with response.getOutputStream(), but you're not using its output anywhere in your code. Essentially what you need to do is to stream the PDF file's bytes directly to the output stream and flush the response. In Spring you can do it like this:

@RequestMapping(value="/getpdf", method=RequestMethod.POST)
public ResponseEntity<byte[]> getPDF(@RequestBody String json) {
    // convert JSON to Employee 
    Employee emp = convertSomehow(json);

    // generate the file
    PdfUtil.showHelp(emp);

    // retrieve contents of "C:/tmp/report.pdf" that were written in showHelp
    byte[] contents = (...);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_PDF);
    // Here you have to set the actual filename of your pdf
    String filename = "output.pdf";
    headers.setContentDispositionFormData(filename, filename);
    headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
    ResponseEntity<byte[]> response = new ResponseEntity<>(contents, headers, HttpStatus.OK);
    return response;
}

Notes:

  • use meaningful names for your methods: naming a method that writes a PDF document showHelp is not a good idea
  • reading a file into a byte[]: example here
  • I'd suggest adding a random string to the temporary PDF file name inside showHelp() to avoid overwriting the file if two users send a request at the same time
Share:
148,789

Related videos on Youtube

Maheshwaran K
Author by

Maheshwaran K

Updated on July 05, 2022

Comments

  • Maheshwaran K
    Maheshwaran K almost 2 years

    I am using Spring MVC .I have to write a service that would take input from the request body, add the data to the pdf and returns the pdf file to the browser. The pdf document is generated using itextpdf. How can I do this using Spring MVC. I have tried using this

    @RequestMapping(value="/getpdf", method=RequestMethod.POST)
    public Document getPDF(HttpServletRequest request , HttpServletResponse response, 
          @RequestBody String json) throws Exception {
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment:filename=report.pdf");
        OutputStream out = response.getOutputStream();
        Document doc = PdfUtil.showHelp(emp);
        return doc;
    }
    

    showhelp function that generates the pdf. I am just putting some random data in the pdf for time being.

    public static Document showHelp(Employee emp) throws Exception {
        Document document = new Document();
    
        PdfWriter.getInstance(document, new FileOutputStream("C:/tmp/report.pdf"));
        document.open();
        document.add(new Paragraph("table"));
        document.add(new Paragraph(new Date().toString()));
        PdfPTable table=new PdfPTable(2);
    
        PdfPCell cell = new PdfPCell (new Paragraph ("table"));
    
        cell.setColspan (2);
        cell.setHorizontalAlignment (Element.ALIGN_CENTER);
        cell.setPadding (10.0f);
        cell.setBackgroundColor (new BaseColor (140, 221, 8));                                  
    
        table.addCell(cell);                                    
        ArrayList<String[]> row=new ArrayList<String[]>();
        String[] data=new String[2];
        data[0]="1";
        data[1]="2";
        String[] data1=new String[2];
        data1[0]="3";
        data1[1]="4";
        row.add(data);
        row.add(data1);
    
        for(int i=0;i<row.size();i++) {
          String[] cols=row.get(i);
          for(int j=0;j<cols.length;j++){
            table.addCell(cols[j]);
          }
        }
    
        document.add(table);
        document.close();
    
        return document;   
    }
    

    I am sure this is wrong. I want that pdf to be generated and save/open dialog box to be opened through the browser, so that it can be stored in the client's file system. Please help me out.

  • Maheshwaran K
    Maheshwaran K about 11 years
    That helped me. Thanks a lot!!! I have one more. here I am storing the generated pdf to my file system and then reading it and converting it to bytes. What should I do if I have to convert the generated pdf on the go. Thanks in advance
  • kryger
    kryger about 11 years
    Instead of using FileOutputStream in your PdfWriter.getInstance() you could use a ByteArrayOutputStream.
  • Admin
    Admin over 10 years
    @kryger, do you know how to open the PDF file in a browser window? I used your method and I prompts the user to save the file immediately :)
  • cherouvim
    cherouvim almost 10 years
    Why store a file on the filesystem?
  • kryger
    kryger almost 10 years
    @cherouvim not sure what you mean (the file example comes from OP's question, in the comments I mentioned how to do it without FileOutputStream), but "thanks" for the downvote.
  • cherouvim
    cherouvim almost 10 years
    @kryger: My bad, you are right. Sorry for the downvote, cant undo it now (past 2 hours). I've upvoted you elsewhere to compensate.
  • Shivkumar Mallesappa
    Shivkumar Mallesappa about 6 years
    I am not understanding the root cause of the issue . I have a simple endpoint from where I want to render pdf. I am able to download the pdf but it is blank and if I use "application/octet-stream" I see that contents are there. So what might be the issue ? Thanks
  • Victor Ionescu
    Victor Ionescu almost 6 years
    Thank you, it worked fine. I've used GET instead of POST: @RequestMapping(value="/getpdf/{idpdf}", method=RequestMethod.GET)
  • Przemek Nowak
    Przemek Nowak over 5 years
    Since Spring 4.3 MediaType.APPLICATION_PDF is available as static variable.
  • Jean-Christophe Robertson
    Jean-Christophe Robertson about 5 years
    For me doing this in Chrome and attempting to save it results in a Failed - network error. Works fine on other browsers and can be worked around with print -> save as pdf. Why does this only happen in chrome and how can I correct it?
  • kryger
    kryger about 5 years
    @Parzzival dunno, ask a new question and include all the details - this is just a comment section so there's little chance to get help here