Search code examples
itext7

How to get the number of lines written in IText 7


I'm upgrating from IText 5 to IText 7. The code below is from version 5 which has a method to get the actual number of lines written. How can I accomplish the same using IText 7?

Paragraph p = new Paragraph(veryLongText, font);  
ColumnText column1 = new ColumnText(writer.DirectContent);
column1.SetSimpleColumn(bottomX, bottomY, topX, 100);
column1.AddElement(p);
column1.Go(true);

noOfLines = column1.LinesWritten; <---- No of Lines 

Solution

  • Layout mechanism in iText 7 is much more complex and feature-rich than mechanism in iText 5, and notion of written lines might be very much opinion-based in many complex layout cases. That's why the number of written lines is not maintained by the layout engine and is not available for query. However, it's very easy to extend your elements/renderers to support calculating the number of written lines. Here is how to do it. First, you need to override a Paragraph to aggregate the number of lines and ParagraphRenderer to provide the info of the lines written back to Paragraph:

    private static class LineCountingParagraph extends Paragraph {
        private int linesWritten = 0;
    
        public LineCountingParagraph(String text) {
            super(text);
        }
    
        public void addWrittenLines(int toAdd) {
            linesWritten += toAdd;
        }
    
        public int getNumberOfWrittenLines() {
            return linesWritten;
        }
    
        @Override
        protected IRenderer makeNewRenderer() {
            return new LineCountingParagraphRenderer(this);
        }
    }
    
    private static class LineCountingParagraphRenderer extends ParagraphRenderer {
        public LineCountingParagraphRenderer(LineCountingParagraph modelElement) {
            super(modelElement);
        }
    
        @Override
        public void drawChildren(DrawContext drawContext) {
            ((LineCountingParagraph)modelElement).addWrittenLines(lines.size());
            super.drawChildren(drawContext);
        }
    
        @Override
        public IRenderer getNextRenderer() {
            return new LineCountingParagraphRenderer((LineCountingParagraph) modelElement);
        }
    }
    

    Now, just use the customized classes instead of the standard ones and query the information after an element was added to a Document or Canvas:

    LineCountingParagraph p = new LineCountingParagraph("text");
    document.add(p);
    System.out.println(p.getNumberOfWrittenLines());
    

    Note that this mechanism also allows you to calculate the number of lines written that satisfy some condition. You can analyze elements in lines list.