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:
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
Click this link if you want to see how to answer this question in iText 7.