Skip to main content
Skip table of contents

How to draw a line every 25 words?

I create a PDF using iText. The content consists of text and I need to draw a line to delimit this text every 25 words as shown in the following image:

Desired result

I'm aware there's a way of that I can extract text and text positions once I have a finished PDF, but considering I'm writing the text to the PDF file, I guess there could be a way of adding these lines during the creation process without really having to find the text position, right?

Posted on StackOverflow on Feb 25, 2015 by Matias Bello

Please take a look at the Every25Words example. In that example, I read a text file into a String with the readFile() method. I then split the text into words based on the occurrence of spaces, and I add each word one by one:

public void createPdf(String dest) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter writer =
        PdfWriter.getInstance(document, new FileOutputStream(dest));
    writer.setPageEvent(new WordCounter());
    writer.setInitialLeading(16);
    document.open();
    String[] words = readFile().split("\\s+");
    Chunk chunk = null;
    for (String word : words) {
        if (chunk != null) {
            document.add(new Chunk(" "));
        }
        chunk = new Chunk(word);
        chunk.setGenericTag("");
        document.add(chunk);
    }
    document.close();
}

The magic happens in this line:

writer.setPageEvent(new WordCounter());
...
chunk.setGenericTag("");

First we declare an instance of the WordCounter event. You may choose a better name for that class, as not only does it count words, it also draws a dashed line:

public class WordCounter extends PdfPageEventHelper {
    public int count = 0;

    @Override
    public void onGenericTag(
        PdfWriter writer, Document document, Rectangle rect, String text) {
        count++;
        if (count % 25 == 0) {
            PdfContentByte canvas = writer.getDirectContent();
            canvas.saveState();
            canvas.setLineDash(5, 5);
            canvas.moveTo(document.left(), rect.getBottom());
            canvas.lineTo(rect.getRight(), rect.getBottom());
            canvas.lineTo(rect.getRight(), rect.getTop());
            canvas.lineTo(document.right(), rect.getTop());
            canvas.stroke();
            canvas.restoreState();
        }
    }
}

Do you see what we do between the saveState() and restoreState() method? We define a dash pattern, we move to the left of the page, we construct a path to the right of the word, then we draw a short upwards line, to finish the path with a line to the right. Once the path is constructed, we stroke the line.

This onGenericTag() method will be triggered every time a Chunk is added on which we used the setGenericTag method.

This is what the result looks like every25words.pdf:

Screen shot of result

Screen shot of result

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

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.