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:
protected void manipulatePdf(String dest) throws Exception {
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(DEST));
Document doc = new Document(pdfDoc);
String[] words = readFile().split("\\s+");
Paragraph paragraph = new Paragraph();
Text text = null;
int i = 0;
for (String word : words) {
if (text != null) {
paragraph.add(" ");
}
text = new Text(word);
text.setNextRenderer(new Word25TextRenderer(text, ++i));
paragraph.add(text);
}
doc.add(paragraph);
doc.close();
}
As you see we define a Word25TextRenderer
to catch every 25th word and draw a dashed line. It happens through extending a TextRenderer
class:
private class Word25TextRenderer extends TextRenderer {
private int count = 0;
public Word25TextRenderer(Text textElement, int count) {
super(textElement);
this.count = count;
}
@Override
public void draw(DrawContext drawContext) {
super.draw(drawContext);
if (0 == count % 25) {
Rectangle rect = getOccupiedAreaBBox();
int pageNumber = getOccupiedArea().getPageNumber();
PdfCanvas canvas = drawContext.getCanvas();
canvas.saveState()
.setLineDash(5, 5)
.moveTo(drawContext.getDocument().getPage(pageNumber).getPageSize().getLeft(), rect.getBottom())
.lineTo(rect.getRight(), rect.getBottom())
.lineTo(rect.getRight(), rect.getTop())
.lineTo(drawContext.getDocument().getDefaultPageSize().getRight(), rect.getTop())
.stroke()
.restoreState();
}
}
}
Do you see what we do between the saveState()
and restoreState()
methods? 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. To get the area occupied by the current word we use getOccupiedAreaBBox()
method and store the result to the Rectangle
variable.
This draw()
method will be triggered every time a Text
is added on which we used the setNextRenderer()
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 5.