Search code examples
javapdfjerseyitexthtml-to-pdf

File is getting downloaded twice in Java Jersey API


I am using following code to download PDF from html contain my working fine but file is getting downloaded twice I tried to modify renderer behavior but still haven't got anything.

public Response downloadResumePdf(@PathParam("userId") String userId) throws IOException, DocumentException {
     String homePath = System.getProperty("user.home");
        String filePath = homePath + "/Downloads/Resume" + LocalDateTime.now().toLocalDate() + ".pdf";
        org.xhtmlrenderer.pdf.ITextRenderer renderer = new ITextRenderer();
        String yourXhtmlContentAsString = "<h1>hi </h1>";
        renderer.setDocumentFromString(yourXhtmlContentAsString);
        renderer.layout();
        java.io.FileOutputStream fos = new java.io.FileOutputStream(filePath);
        renderer.createPDF(fos);
        fos.close();
        File file = new File(filePath);
        return Response
          .ok((Object) file)
          .header("Content-Disposition", "attachment; filename=\"Resume" + LocalDateTime.now().toLocalDate() + ".pdf\"")
          .build();

Solution

  • The reason for the duplication, as mentioned in Mark's answer, is because you are creating a "temporary" file when you create and write to the FileOutputStream.

    The solution: you do not need to create a temporary file to handle the Download. Instead of creating a FileOutputStream, just use StreamingOutput and pass the StreamingOutput's OutputStream to the ITextRenderer#createPDF(OutputStream) method.

    @GET
    @Produces("application/pdf")
    public Response getResumePdf(@PathParam("userId") String userId) {
    
        StreamingOutput entity = new StreamingOutput() {
            @Override
            public void write(OutputStream output) {
                try {
                    ITextRenderer renderer = new ITextRenderer();
                    String yourXhtmlContentAsString = "<h1>hi </h1>";
                    renderer.setDocumentFromString(yourXhtmlContentAsString);
                    renderer.layout();
                    renderer.createPDF(output);
                    output.flush();
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
    
        return Response.ok(entity)
             .header(...)
             .build();
    }