简体   繁体   中英

PDF Generation using iText7 with Java

I am trying to add content to an existing PDF using iText7. I have been able to create new PDFs and add content to them using Paragraphs and Tables. However, once I go to reopen a PDF that I have created and attempt to write more content to it, the new content starts overwriting the old content. I want the new content to be appended to the Document after the old content. How can I achieve this?

Edit

This is the Class which sets up some common methods that will be executed with each change done to a PDF document.

public class PDFParent {

private static Document document;

private static PdfWriter writer;

private static PdfReader reader;

private static PageSize ps;

private static PdfDocument pdfDoc;

public static Document getDocument() {
    return document;
}

public static void setDocument(Document document) {
    PDFParent.document = document;
}

public static void setupPdf(byte[] inParamInPDFBinary){
    writer = new PdfWriter(new ByteArrayOutputStream());

    try {
        reader = new PdfReader(new ByteArrayInputStream(inParamInPDFBinary));           
    } catch (IOException e) {
        e.printStackTrace();
    }

    pdfDoc = new PdfDocument(reader, writer);

    ps = PageSize.A4;
    document = new Document(pdfDoc, ps);
}

public static byte[] writePdf(){        
    ByteArrayOutputStream stream = (ByteArrayOutputStream) writer.getOutputStream();    
    return stream.toByteArray();
}

public static void closePdf(){
    pdfDoc.close();
}

And this is how I am adding the content to the pdf

public class ActAddParagraphToPDF extends PDFParent{

// output parameters
public static byte[] outParamOutPDFBinary;

public static ActAddParagraphToPDF mosAddParagraphToPDF(byte[] inParamInPDFBinary, String inParamParagraph) throws IOException {
    ActAddParagraphToPDF result = new ActAddParagraphToPDF();

    setupPdf(inParamInPDFBinary);

    //---------------------begin content-------------------//

    getDocument().add((Paragraph) new Paragraph(inParamParagraph));

    //---------------------end content-------------------//

    closePdf();

    outParamOutPDFBinary = writePdf();

    return result;
}

When I go to execute this second class, it appears to be treating the original document as if it is blank. Then writes the new Paragraph on top of the original content. I know that I am missing something, just not sure what that is.

Is reopening the document every time a requirement? If you keep the document open, you can append as much content as you want and you won't have to deal with content overlapping problems.

If it is a requirement, then you will have to track the last free content position yourself and reset it to new DocumentRenderer .

A Rectangle would be enough to store the free area that is left on the last page. Right before closing the document, save the free area in some Rectangle in the following way:

Rectangle savedBbox = document.getRenderer().getCurrentArea().getBBox();

After that, when you have to reopen the document, first jump to the last page:

document.add(new AreaBreak(AreaBreakType.LAST_PAGE));

And then reset the free occupied area left from the previous time you dealt with the document:

document.getRenderer().getCurrentArea().setBBox(savedBbox);

After that you are free to add new content to the document and it will appear at the saved position:

document.add(new Paragraph("Hello again"));

Please note that this approach works if you know which documents you are dealing with (ie you can associate last "free" position with the document's ID) and this document is not changed outside of your environment. If this is not the case, I recommend that you look into content extraction and in particular PdfDocumentContentParser . It can help you to extract the content you have on the page and determine which positions it occupies. Then you can calculate the free area on a page and use document.getRenderer().getCurrentArea().setBBox approach I described above to point DocumentRenderer to the correct place to write content to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM