1

my goal is to move text in a PDF around, which is within a certain rectangular area. There is an existing Item on stackoverflow, which already got me close to achiving this: iText or iTextSharp rudimentary text edit

However, I would be back at manipulating the PDF on a very basic level. Is there a chance to use higher level facilities of itext to alter the position of the text? I'm afraid there is no simple solution, but I'd be happy to get some suggestions.

PS: Also keep in mind that I want to move around only text within a rectangular area, i.e. text(chunks) matching the area in the original PDF should be shifted some in their x and y coordinates. I have no influence on how the PDF are created and I can accept a solution that only vaguely works.

Community
  • 1
  • 1
tom_imk
  • 165
  • 2
  • 11
  • Just to be clear: you want to move around text within a rectangular area. Does this mean you know the **coordinates** of that rectangle and that you want to have an effect that looks as if that rectangle was cut out and placed at another location? – Bruno Lowagie Feb 06 '15 at 15:02
  • no, not a graphical effect. It can be much messier. I have the coordinates and whichever text chunk I find "within" shall be shifted by a given amount of points in x and y axes.I swear I read your book up and down, but still can't wrap my head around the workflow of this task :) – tom_imk Feb 06 '15 at 19:10
  • 1
    You say *no* but what is the difference? – mkl Feb 06 '15 at 20:00

2 Answers2

2

I thought I understood your question, but your response to my counter-question is confusing, so let me give you an example that answers your question as I interpret it.

Suppose that you have a text like this: enter image description here

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

enter image description here

That is fairly easy to achieve. Take a look at the CutAndPaste example:

public void manipulatePdf(String src, String dest)
    throws IOException, DocumentException {
    // Creating a reader
    PdfReader reader = new PdfReader(src);
    // step 1
    Rectangle pageSize = reader.getPageSize(1);
    Rectangle toMove = new Rectangle(100, 500, 200, 600);
    Document document = new Document(pageSize);
    // step 2
    PdfWriter writer
        = PdfWriter.getInstance(document, new FileOutputStream(dest));
    // step 3
    document.open();
    // step 4
    PdfImportedPage page = writer.getImportedPage(reader, 1);
    PdfContentByte cb = writer.getDirectContent();
    PdfTemplate template1 = cb.createTemplate(pageSize.getWidth(), pageSize.getHeight());
    template1.rectangle(0, 0, pageSize.getWidth(), pageSize.getHeight());
    template1.rectangle(toMove.getLeft(), toMove.getBottom(),
            toMove.getWidth(), toMove.getHeight());
    template1.eoClip();
    template1.newPath();
    template1.addTemplate(page, 0, 0);
    PdfTemplate template2 = cb.createTemplate(pageSize.getWidth(), pageSize.getHeight());
    template2.rectangle(toMove.getLeft(), toMove.getBottom(),
            toMove.getWidth(), toMove.getHeight());
    template2.clip();
    template2.newPath();
    template2.addTemplate(page, 0, 0);
    cb.addTemplate(template1, 0, 0);
    cb.addTemplate(template2, -20, -2);
    // step 4
    document.close();
    reader.close();
}

If this is not what you want. If you want to detect actual words and move those words, then you have a problem. In that case, we are talking about a project that could easily cost a couple of months of work to do it correctly, and your short question would be largely insufficient to know what to do in the many edge cases that can be imagined.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • 1
    Geesh, it is indeed the solution I needed. My response was based on the assumption that an actual "cutout" effect was indeed more difficult to achieve. But it suits my task just as well. Thank you very much for the solution and the example.I just went back to the book and just maybe I could've come up with the solution myself, but I couldn't piece it together. – tom_imk Feb 07 '15 at 16:07
0

The same code above, but in C#, with namespaces:

        // Creating a reader
        iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(src);

        // step 1
        Rectangle pageSize = reader.GetPageSize(1);
        Rectangle toMove = new Rectangle(100, 500, 200, 600);
        Document document = new Document(pageSize);

        // step 2
        iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, new FileStream(dest, FileMode.Create));

        // step 3
        document.Open();

        // step 4
        iTextSharp.text.pdf.PdfImportedPage page = writer.GetImportedPage(reader, 1);
        iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
        iTextSharp.text.pdf.PdfTemplate template1 = cb.CreateTemplate(pageSize.Width, pageSize.Height);

        template1.Rectangle(0, 0, pageSize.Width, pageSize.Height);
        template1.Rectangle(toMove.Left, toMove.Bottom, toMove.Width, toMove.Height);
        template1.EoClip();
        template1.NewPath();
        template1.AddTemplate(page, 0, 0);

        iTextSharp.text.pdf.PdfTemplate template2 = cb.CreateTemplate(pageSize.Width, pageSize.Height);

        template2.Rectangle(toMove.Left, toMove.Bottom, toMove.Width, toMove.Height);
        template2.Clip();
        template2.NewPath();
        template2.AddTemplate(page, 0, 0);
        cb.AddTemplate(template1, 0, 0);
        cb.AddTemplate(template2, -20, -2);

        // step 5
        document.Close();
        reader.Close();