javapdfcopyitextstamp

iText - Persistence of pagestamp in PdfCopy


I'm using iText 4.2.1 to generate my pdf reports. So basically I have a PDF template which contains a cover page, end page and a content page (that just contains an image header).

I'm using PdfCopy & PdfImportedPage to copy my template and PageStamp to add my content dynamically.

Need: I need to use the content page many times: as much as content pages in my report.

Problem: If I use pdfCopy.createPageStamp(importedPage) and ColumnText.showTextAligned to add some text the stamp persists over the next content pages. Thus my content page n°2 contains the text of the 1st one (added by PageStamp) and its own text (added by another PageStamp).

Here is an example of code:


    // Init
    Document doc = new Document();
    PdfCopy pdfCopy = new PdfCopy( doc, new FileOutputStream( new File("Result.pdf") ) );
    doc.open();
    PdfReader pdfReader = new PdfReader( "pdf-template.pdf" );

    // Page 1
    PdfImportedPage importedPage1= pdfCopy.getImportedPage(pdfReader, 2);
    String text1= "Text of the first page - 1";
    PageStamp stamp1 = pdfCopy.createPageStamp( importedPage1 );
    ColumnText.showTextAligned( stamp.getOverContent(), Element.ALIGN_CENTER,
                                new Phrase(text1), 400, 500, 0 );
    stamp.alterContents();
    pdfCopy.addPage(importedPage1);

    // Page 2
    PdfImportedPage importedPage2= pdfCopy.getImportedPage(pdfReader, 2);
    String text2 = "Text of the second page - 2";
    PageStamp stamp2 = pdfCopy.createPageStamp( importedPage2 );
    ColumnText.showTextAligned( stamp2.getOverContent(), Element.ALIGN_CENTER, 
                                new Phrase(text2), 200, 700, 0 );
    stamp2.alterContents();
    pdfCopy.addPage(importedPage2);

    // Closing
    doc.close();

--> In the 2nd page I will see my text1 and my text2

I tried using the same PdfImportedPage: same result.

I tried using the same PageStamp: same result.

I tried using a different PdfReader: it works but is this really the solution??

Thanks for your help.


Solution

  • @Bruno and @Amedee already commented on using a version 4.2.1, so I do not need to talk about that. The question you ask still is valid for the current iText version, though. Thus:

    Problem: If I use pdfCopy.createPageStamp(importedPage) and ColumnText.showTextAligned to add some text the stamp persists over the next content pages. Thus my content page n°2 contains the text of the 1st one (added by PageStamp) and its own text (added by another PageStamp).

    This is to be expected as it is the documented behavior. Have a look at the PdfCopy.createPageStamp JavaDocs:

    /**
     * Create a page stamp. New content and annotations, including new fields, are allowed.
     * The fields added cannot have parents in another pages. This method modifies the PdfReader instance.<p>
     * The general usage to stamp something in a page is:
     * <p>
     * <pre>
     * PdfImportedPage page = copy.getImportedPage(reader, 1);
     * PdfCopy.PageStamp ps = copy.createPageStamp(page);
     * ps.addAnnotation(PdfAnnotation.createText(copy, new Rectangle(50, 180, 70, 200), "Hello", "No Thanks", true, "Comment"));
     * PdfContentByte under = ps.getUnderContent();
     * under.addImage(img);
     * PdfContentByte over = ps.getOverContent();
     * over.beginText();
     * over.setFontAndSize(bf, 18);
     * over.setTextMatrix(30, 30);
     * over.showText("total page " + totalPage);
     * over.endText();
     * ps.alterContents();
     * copy.addPage(page);
     * </pre>
     * @param iPage an imported page
     * @return the <CODE>PageStamp</CODE>
     */
    public PageStamp createPageStamp(PdfImportedPage iPage)
    

    (PdfCopy.java)

    As it says in the second line: This method modifies the PdfReader instance.

    Thus,

    I tried using a different PdfReader: it works but is this really the solution??

    This is one solution but depending on the source PDF quite a resource-intensive one. Another one is to use PdfCopy without PageStamps and apply your changes in a separate PdfStamper. Depending on your use case there are other ones...

    PageStamps represent a very lightweight way to stamp while copying because they simply manipulate the PdfReader and do not have to build their own intermediary structures. In case of incompatible use cases,