How to draw a line every 25 words?

Is there a way of adding lines during the PDF creation process?

24th October 2015
admin-marketing

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


Share this article

Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now