0

Using iTextSharp, I create a pdf writing some text into it. What I need is to draw a line to delimiter the text every 25 words, like the following image:

enter image description here

Basically, I need to do that: draw a line every 25 words, just like the image.

I'm aware there's a way of finding the position of a word on a page, but considering I'm writing the text to the pdf file, I guess there could be a way of calculating this without really having to find the text position, right?

Community
  • 1
  • 1
Matias Bello
  • 50
  • 2
  • 10
  • Please post some of what you have tried already and what is not working. Stack Overflow is meant to help you whenever you run into a problem implementing rather than being a code writing service. – zero298 Feb 25 '15 at 01:41
  • I totally understand that. I'm not intending you guys to give me *all* the code, but I really don't know where to start.. Don't really need the complete code (I mean, openining a writer, print text to it, flushing it, closing it), but I do need a hint -at least- of how could I achieve what I'm looking for, that is drawing a line every N words. Basically, what I don't know, is how to get the position of a word. If I get that, I guess drawing the line from a fixed position to the word position wouldn' be that hard. – Matias Bello Feb 25 '15 at 23:21
  • To ellaborate a little bit further.. The methods I've seen to find the position of a certain text does not work either, because, let's say that word N° 25 is "house", I might have another occurence of the word "house" somewhere else in my text, but I only care for the one which is the 25th word in my text. So I guess I could be writing word by word, and carrying the count.. so when I'm writing the 25th word, then get -somehow- the position of that particular word, and draw the line there. But **how** to do that is what I don't know. – Matias Bello Feb 25 '15 at 23:41

1 Answers1

0

Please take a look at the Every25Words examples. 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:

enter image description here

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Thanks a million, Bruno!! Not only for helping me, but for giving such a detailed explanation even with example. Really, thank you so much!! – Matias Bello Feb 26 '15 at 01:45
  • Now that I've revisited the code, I came to the conclusion that the key was to use the OnGenericTag event from PdfPageHandler. Only if I knew there was such event... Anyway, thanks again, Bruno! PS: I'd totally vote up, but I lack of enough reputation :( – Matias Bello Feb 26 '15 at 11:06
  • No problem. I'm on vacation, but when I saw that your question already received one down vote and one close vote, I decided to give it an up-vote and an answer, because it is an original requirement and a good question. It was fun writing the example (but now I return to vacation mode). – Bruno Lowagie Feb 26 '15 at 16:57
  • Thanks again, and enjoy your vacations! :=) – Matias Bello Feb 27 '15 at 19:50