How to move the content inside a rectangle inside an existing PDF?

Tags: clippingiText 7

My goal is to move text in a PDF around, which is within a certain rectangular area. All content matching the area in the original PDF should be shifted somewhat in the x and y direction. I have no influence on how the PDFs are created and I can accept a solution that only vaguely works.

Posted on StackOverflow on Feb 6, 2015 by tom_ink

Suppose that you have a PDF document like this:

Original PDF
Original PDF

I also have the coordinates of a rectangle: new Rectangle(100, 500, 100, 100); and an offset: move everything in that rectangle 10 points to the left and 2 points to the bottom, like this:

Manipulated PDF
Manipulated PDF

That is fairly easy to achieve. Take a look at the CutAndPaste example adapted for iText 7:

public void manipulatePdf(String src, String dest) throws IOException {

    Rectangle toMove = new Rectangle(100, 500, 100, 100);

    PdfDocument srcDoc = new PdfDocument(new PdfReader(src));
    Rectangle pageSize = srcDoc.getFirstPage().getPageSize();

    PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
    pdfDoc.setDefaultPageSize(new PageSize(pageSize));
    pdfDoc.addNewPage();

    PdfFormXObject t_canvas1 = new PdfFormXObject(pageSize);
    PdfCanvas canvas1 = new PdfCanvas(t_canvas1, pdfDoc);

    PdfFormXObject pageXObject = srcDoc.getFirstPage().copyAsFormXObject(pdfDoc);

    canvas1.rectangle(0, 0, pageSize.getWidth(), pageSize.getHeight());
    canvas1.rectangle(toMove.getLeft(), toMove.getBottom(),
            toMove.getWidth(), toMove.getHeight());
    canvas1.eoClip();
    canvas1.newPath();
    canvas1.addXObject(pageXObject, 0, 0);

    PdfFormXObject t_canvas2 = new PdfFormXObject(pageSize);
    PdfCanvas canvas2 = new PdfCanvas(t_canvas2, pdfDoc);
    canvas2.rectangle(toMove.getLeft(), toMove.getBottom(),
            toMove.getWidth(), toMove.getHeight());
    canvas2.clip();
    canvas2.newPath();
    canvas2.addXObject(pageXObject, 0, 0);

    PdfCanvas canvas = new PdfCanvas(pdfDoc.getFirstPage());
    canvas.addXObject(t_canvas1, 0, 0);
    canvas.addXObject(t_canvas2, -20, -2);

    srcDoc.close();
    pdfDoc.close();
}

Take into account that PdfImportedPage, PdfContentByte and PdfTemplate classes don’t exist in iText 7. We use PdfFormXObject and PdfCanvas now. As you see in the code above, t_canvas1 contains the whole first page, but with the clipped rectangle area; t_canvas2 is that clipped area and we add it to the main canvas with an offset -20, -2 to make the resulting PDF more demonstrative.

Click this link if you want to see how to answer this question in iText 5.