Search code examples
javaservletsitextflying-saucer

iText/flying-saucer PdfStamper using an OutputStream


I'm almost there (I think) on being able to render a PDF with a servlet without saving it first. I've been able to successfully set it up, but I'm stuck at trying to make the PDF open in the client's browser with a Print Dialog initially.

I've been able to send my PDF to the client successfully with the following:

DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
Document doc = builder.parse(new StringBufferInputStream(buf.toString())); 

OutputStream os = resp.getOutputStream(); 

ITextRenderer renderer = new ITextRenderer(); 
renderer.setDocument(doc, null); 
renderer.layout(); 
renderer.createPDF(os); 

os.close();

But, I'm not sure how to put a print dialog on open of it. I've used this code for a physical PDF file, but I need to be able to read the contents of the OutputStream in as a byte array for input to the PdfReader (I think):

PdfReader reader = new PdfReader("a_physical_file.pdf"); 
PdfStamper stamper = new PdfStamper(reader, os); 
stamper.setPageAction(PdfWriter.PAGE_OPEN, new PdfAction(PdfAction.PRINTDIALOG), 1); 
stamper.close();

Not sure how to do this with an OutputStream rather than an actual file...

I've also created an iText chat room if you would like to post there: https://chat.stackoverflow.com/rooms/8945/itext


Solution

  • Warning : I use an old version of Itext, so my experience may not be applicable.

    PdfReader can use a byte array. so you could use a ByteArrayOutputStream as your first output stream, then use it to get the reader, instead of a filename.

    Regards

    Edit : Regarding your question :

    i'm doing it the others way around : i'm working on a ByteArrayOutputStream and then writing it in the response stream :

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    // creating / modifying the pdf
    ...
    byte[] pdfoutput = out.toByteArray();
    res.setContentLength(pdfoutput.length);
    res.getOutputStream().write(pdfoutput);
    

    Edit 2 : the final solution (from the chat room)

    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
    Document doc = builder.parse(new StringBufferInputStream(buf.toString())); 
    
    OutputStream os = new ByteArrayOutputStream(); 
    ITextRenderer renderer = new ITextRenderer(); 
    renderer.setDocument(doc, null); 
    renderer.layout(); 
    renderer.createPDF(os); 
    os.close(); 
    
    PdfReader reader = new PdfReader(((ByteArrayOutputStream)os).toByteArray()); 
    OutputStream out = new ByteArrayOutputStream(); 
    PdfStamper stamper = new PdfStamper(reader, out); 
    stamper.setPageAction(PdfWriter.PAGE_OPEN, new PdfAction(PdfAction.PRINTDIALOG), 1); 
    stamper.close(); 
    
    resp.getOutputStream().write(((ByteArrayOutputStream)out).toByteArray());