Positioning different text snippets on a page

Tags: ColumnTextrectanglecoordinate systemiText 5
Files: 
/*
 * This example was written by Bruno Lowagie in answer to the following question:
 * http://stackoverflow.com/questions/27989754/itext-failure-with-adding-elements-with-5-5-4
 */
package sandbox.objects;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import sandbox.WrapToTest;
 
@WrapToTest
public class ColumnTextPhrase {
 
    public static final String SRC = "resources/pdfs/hello.pdf";
    public static final String DEST = "results/objects/column_text_phrase.pdf";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new ColumnTextPhrase().manipulatePdf(SRC, DEST);
    }
 
    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        PdfContentByte cb = stamper.getOverContent(1);
        ColumnText ct = new ColumnText(cb);
        ct.setSimpleColumn(120f, 48f, 200f, 600f);
        Font f = new Font();
        Paragraph pz = new Paragraph(new Phrase(20, "Hello World!", f));
        ct.addElement(pz);
        ct.go();
        BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA_BOLD, "Cp1252", BaseFont.EMBEDDED);
        f = new Font(bf, 13);
        ct = new ColumnText(cb);
        ct.setSimpleColumn(120f, 48f, 200f, 700f);
        pz = new Paragraph ("Hello World!", f);
        ct.addElement(pz);
        ct.go();
        stamper.close();
        reader.close();
    }
}
/**
 * Example written by Bruno Lowagie in answer to:
 * http://stackoverflow.com/questions/20909450/correct-text-position-center-in-rectangle-itext
 * 
 * Doing some font math to vertically fit a piece of text inside a rectangle.
 */
package sandbox.objects;
 
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
 
import sandbox.WrapToTest;
 
@WrapToTest
public class FitTextInRectangle {
 
    public static final String DEST = "results/objects/chunk_in_rectangle.pdf";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new FitTextInRectangle().createPdf(DEST);
    }
 
    public void createPdf(String dest) throws IOException, DocumentException {
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
        document.open();
 
        // the direct content
        PdfContentByte cb = writer.getDirectContent();
        // the rectangle and the text we want to fit in the rectangle
        Rectangle rect = new Rectangle(100, 150, 220, 200);
        String text = "test";
        // try to get max font size that fit in rectangle
        BaseFont bf = BaseFont.createFont();
        int textHeightInGlyphSpace = bf.getAscent(text) - bf.getDescent(text);
        float fontSize = 1000f * rect.getHeight() / textHeightInGlyphSpace;
        Phrase phrase = new Phrase("test", new Font(bf, fontSize));
        ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, phrase,
                // center horizontally
                (rect.getLeft() + rect.getRight()) / 2,
                // shift baseline based on descent
                rect.getBottom() - bf.getDescentPoint(text, fontSize),
                0);
 
        // draw the rect
        cb.saveState();
        cb.setColorStroke(BaseColor.BLUE);
        cb.rectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight());
        cb.stroke();
        cb.restoreState();
 
        document.close();
    }
}
/*
 * This example was written by Bruno Lowagie in answer to the following question:
 * http://stackoverflow.com/questions/29037981/how-to-draw-a-rectangle-around-multiline-text
 */
package sandbox.objects;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import sandbox.WrapToTest;
 
@WrapToTest
public class DrawRectangleAroundText {
 
    public static final String SRC = "resources/pdfs/hello.pdf";
    public static final String DEST = "results/objects/column_text_rectangle.pdf";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new DrawRectangleAroundText().manipulatePdf(SRC, DEST);
    }
 
    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        PdfContentByte cb = stamper.getOverContent(1);
        // full column
        ColumnText ct = new ColumnText(cb);
        ct.setSimpleColumn(120f, 500f, 250f, 780f);
        Paragraph p = new Paragraph("This is a long paragraph that doesn't"
                + "fit the width we defined for the simple column of the"
                + "ColumnText object, so it will be distributed over several"
                + "lines (and we don't know in advance how many).");
        ct.addElement(p);
        ct.go();
        cb.rectangle(120, 500, 130, 280);
        cb.stroke();
        // used column
        ct = new ColumnText(cb);
        ct.setSimpleColumn(300f, 500f, 430f, 780f);
        ct.addElement(p);
        ct.go();
        float endPos = ct.getYLine() - 5;
        cb.rectangle(300, endPos, 130, 780 - endPos);
        cb.stroke();
        stamper.close();
        reader.close();
    }
}
/*
 * This example was written by Bruno Lowagie in answer to the following question:
 * http://stackoverflow.com/questions/26752663/adding-maps-at-itext-java
 */
package sandbox.objects;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import sandbox.WrapToTest;
 
@WrapToTest
public class CenterVertically {
 
    public static final String DEST = "results/objects/center_vertically.pdf";
 
    private int status = ColumnText.START_COLUMN;
    private float y_position = 0;
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new CenterVertically().createPdf(DEST);
    }
 
    public void createPdf(String dest) throws IOException, DocumentException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
        // step 3
        document.open();
        // step 4
        PdfContentByte pagecanvas = writer.getDirectContent();
        PdfPTable table;
        PdfPCell cell = new PdfPCell();
        for (int i = 1; i <= 5; i++)
            cell.addElement(new Paragraph("Line " + i));
        table = new PdfPTable(1);
        table.addCell(cell);
        table.addCell(cell);
        table.addCell(cell);
        addTable(document, pagecanvas, table);
        document.newPage();
        table = new PdfPTable(1);
        table.addCell(cell);
        table.addCell(cell);
        table.addCell(cell);
        table.addCell(cell);
        table.addCell(cell);
        table.addCell(cell);
        table.addCell(cell);
        table.addCell(cell);
        table.addCell(cell);
        table.addCell(cell);
        addTable(document, pagecanvas, table);
        // step 5
        document.close();
    }
 
    public void addTable(Document document, PdfContentByte canvas, PdfPTable table) throws DocumentException {
        Rectangle pagedimension = new Rectangle(36, 36, 559, 806);
        drawColumnText(document, canvas, pagedimension, table, true);
        Rectangle rect;
        if (ColumnText.hasMoreText(status)) {
            rect = pagedimension;
        }
        else {
            rect = new Rectangle(36, 36, 559, 806 - ((y_position - 36) / 2));
        }
        drawColumnText(document, canvas, rect, table, false);
    }
 
    public void drawColumnText(Document document, PdfContentByte canvas, Rectangle rect, PdfPTable table, boolean simulate) throws DocumentException {
        ColumnText ct = new ColumnText(canvas);
        ct.setSimpleColumn(rect);
        ct.addElement(table);
        status = ct.go(simulate);
        y_position = ct.getYLine();
        while (!simulate && ColumnText.hasMoreText(status)) {
            document.newPage();
            ct.setSimpleColumn(rect);
            status = ct.go(simulate);
        }
    }
}
package sandbox.objects;
 
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
 
import sandbox.WrapToTest;
 
@WrapToTest
public class CenterColumnVertically {
 
    public static final String DEST = "results/objects/center_column_vertically.pdf";
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new CenterColumnVertically().createPdf(DEST);
    }
 
    public void createPdf(String dest) throws IOException, DocumentException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
        // step 3
        document.open();
        // step 4
        // show the area for the column as a rectangle with red borders
        float llx = 50;  float lly = 650;
        float urx = 400; float ury = 800;
        Rectangle rect = new Rectangle(llx, lly, urx, ury);
        rect.setBorder(Rectangle.BOX);
        rect.setBorderWidth(0.5f);
        rect.setBorderColor(BaseColor.RED);
        PdfContentByte cb = writer.getDirectContent();
        cb.rectangle(rect);
        // this is the paragraph we want to center vertically:
        Paragraph p = new Paragraph("This text is centered vertically. It is rendered in the middle of the red rectangle.");
        p.setLeading(12f);
        // We add the column in simulation mode:
        float y = drawColumnText(cb, rect, p, true);
        // We calculate a new rectangle and add the column for real
        rect = new Rectangle(llx, lly, urx, ury - ((y - lly) / 2));
        drawColumnText(cb, rect, p, false);
        // step 5
        document.close();
    }
 
    /**
     * Draws a Paragraph inside a given column and returns the Y value at the end of the text.
     * @param  canvas    the canvas to which we'll add the Paragraph
     * @param  rect      the dimensions of the column
     * @param  p         the Paragraph we want to add
     * @param  simulate  do we add the paragraph for real?
     * @return the Y coordinate of the end of the text
     * @throws com.itextpdf.text.DocumentException
     */
    public float drawColumnText(PdfContentByte canvas, Rectangle rect, Paragraph p, boolean simulate) throws DocumentException {
        ColumnText ct = new ColumnText(canvas);
        ct.setSimpleColumn(rect);
        ct.addElement(p);
        ct.go(simulate);
        return ct.getYLine();
    }
}
/**
 * Example written by Bruno Lowagie in answer to:
 * http://stackoverflow.com/questions/28502315/divide-page-in-2-parts-so-we-can-fill-each-with-different-source
 */
package sandbox.events;
 
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
 
import sandbox.WrapToTest;
 
@WrapToTest
public class ThreeParts {
    public static final String DEST = "results/events/three_parts.pdf";
 
    public static final String[] LANGUAGES = { "la", "en", "fr" };
    public static final Rectangle[] RECTANGLES = {
        new Rectangle(36, 581, 559, 806),
        new Rectangle(36, 308.5f, 559, 533.5f),
        new Rectangle(36, 36, 559, 261) };
 
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new ThreeParts().createPdf(DEST);
    }
 
    public class RedBorder extends PdfPageEventHelper {
        protected Rectangle[] rectangles;
 
        public RedBorder() {
            rectangles = new Rectangle[3];
            for (int i = 0; i < 3; i++) {
                rectangles[i] = new Rectangle(RECTANGLES[i]);
                rectangles[i].setBorder(Rectangle.BOX);
                rectangles[i].setBorderWidth(1);
                rectangles[i].setBorderColor(BaseColor.RED);
            }
        }
 
        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            PdfContentByte canvas = writer.getDirectContent();
            for (Rectangle rectangle : rectangles) {
                canvas.rectangle(rectangle);
            }
        }
    }
 
    public void createPdf(String filename) throws IOException, DocumentException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        RedBorder event = new RedBorder();
        writer.setPageEvent(event);
        // step 3
        document.open();
        // step 4
        PdfContentByte cb = writer.getDirectContent();
        ColumnText[] columns = new ColumnText[3];
        for (int section = 1; section <= 3; section++) {
            for (int la = 0; la < 3; la++) {
                columns[la] = createColumn(cb, section, LANGUAGES[la], RECTANGLES[la]);
            }
            while (addColumns(columns)) {
                document.newPage();
                for (int la = 0; la < 3; la++) {
                    columns[la].setSimpleColumn(RECTANGLES[la]);
                }
            }
            document.newPage();
        }
        // step 5
        document.close();
    }
 
    public ColumnText createColumn(PdfContentByte cb, int i, String la, Rectangle rect) throws IOException {
        ColumnText ct = new ColumnText(cb);
        ct.setSimpleColumn(rect);
        Phrase p = createPhrase(String.format("resources/text/liber1_%s_%s.txt", i, la));
        ct.addText(p);
        return ct;
    }
 
    public Phrase createPhrase(String path) throws IOException {
        Phrase p = new Phrase();
        BufferedReader in = new BufferedReader(
            new InputStreamReader(new FileInputStream(path), "UTF8"));
        String str;
        while ((str = in.readLine()) != null) {
            p.add(str);
        }
        in.close();
        return p;
    }
 
    public boolean addColumns(ColumnText[] columns) throws DocumentException {
        int status = ColumnText.NO_MORE_TEXT;
        for (ColumnText column : columns) {
            if (ColumnText.hasMoreText(column.go()))
                status = ColumnText.NO_MORE_COLUMN;
        }
        return ColumnText.hasMoreText(status);
    }
}
/**
 * Example written by Bruno Lowagie in answer to the following question:
 * http://stackoverflow.com/questions/25808367/rotate-multiline-text-with-columntext-itextsharp
 */
package sandbox.stamper;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfTemplate;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import sandbox.WrapToTest;
 
@WrapToTest
public class AddRotatedTemplate {
 
    public static final String SRC = "resources/pdfs/hello.pdf";
    public static final String DEST = "results/stamper/hello_template.pdf";
    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new AddRotatedTemplate().manipulatePdf(SRC, DEST);
    }
 
    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        PdfContentByte cb = stamper.getOverContent(1);
        PdfTemplate xobject = cb.createTemplate(80, 120);
        ColumnText column = new ColumnText(xobject);
        column.setSimpleColumn(new Rectangle(80, 120));
        column.addElement(new Paragraph("Some long text that needs to be distributed over several lines."));
        column.go();
        cb.addTemplate(xobject, 36, 600);
        double angle = Math.PI / 4;
        cb.addTemplate(xobject,
                (float)Math.cos(angle), -(float)Math.sin(angle),
                (float)Math.cos(angle), (float)Math.sin(angle),
                150, 600);
        stamper.close();
        reader.close();
    }
 
}
Resources: 
File nameRaw URLUpdated
hello.pdfhello.pdf2015-10-11 3:52 pm
liber1_1_fr.txtliber1_1_fr.txt2015-11-01 7:14 pm
liber1_1_la.txtliber1_1_la.txt2015-10-24 1:26 am
liber1_1_en.txtliber1_1_en.txt2015-11-01 7:14 pm
liber1_2_fr.txtliber1_2_fr.txt2015-11-01 7:14 pm
liber1_2_la.txtliber1_2_la.txt2015-11-01 7:14 pm
liber1_2_en.txtliber1_2_en.txt2015-11-01 7:14 pm
liber1_3_fr.txtliber1_3_fr.txt2015-11-01 7:14 pm
liber1_3_la.txtliber1_3_la.txt2015-11-01 7:14 pm
liber1_3_en.txtliber1_3_en.txt2015-11-01 7:14 pm