In iText5, we can get the PdfPTable's height when we need "public float calculateHeights(boolean firsttime)".
But in iText7, how can we get current table height value (especially before adding the table to its parent element)?
I already tested "table.getHeight()" method, but it returns null. And I also found that in a table render object I can get this value, but the limitation is that the render need to be triggered when the table is adding into its parent element, so the time is not my need.
Cause sometimes we need this value for calculation to decide the "y-axis" value.
In iText5, elements and information about their position/size were a bit mixed together, which allowed you to call
calculateWidths
on aPdfPTable
element.In iText7, this functionality is separated, which allows different kind of flexibility for rendering/layouting elements.
Thus, model elements, which a
Table
instance is an example of, do not know anything about their position or size. And callingtable.getHeight
results innull
becausetable
did not haveHEIGHT
property previously set to it.To calculate table height, one would have to make use of the rendering functionality.
For a model element, you can get the subtree of renderers representing this model element and all its children, and
layout
it in any given area. To really know the height of a table, you would want to create an area which knowingly will be sufficient to place the whole contents of the element.The code above prints
22.982422O
for me, but the results may vary depending on the configuration and properties of elements.I would like to point out two important parts of the code:
We pass
1e4f
as the height of theLayoutArea
, considering that this will be sufficient to place the whole table. Note that if the table cannot be placed into that height, the result will never exceed this given height and thus it will not be correct for your usecase (know the total height of the table). So make sure to pass the height which will be sufficient for placement of the whole table..setParent(doc.getRenderer())
part is important here and is used for retrieving inheritant properties. Note that we did not set a lot of properties totable
element, even font, but this information is essential to know the area this element would occupy. So this information will be inherited from the parent chain duringlayout
. You can test this by changing the document's font:document.setFont(newFont);
, or font size:document.setFontSize(24);
and watching the resultant height changeWell, due to the way the renderer framework is written in iText7, there isn't a way (yet) to calculate the height of a layout object before it is added to a parent document, since the actual calculation of the height for the layout objects happens when they are added to the a
Document
object.You can however relayout a
Document
, allowing you to change the content of previously added elements. Using this, you can simulate the rendering of tables and get a hold of their heights when you add new elements. Thetable.getHeight()
still won't work, since it retrieves the height property, and that property is currently not set anywhere in the table rendering process.In the example below, I've written a convenience method that iterates over the renderer-tree and prints out the area each table occupies in the document, to show you how you can get the calculated heights.
The example itself adds some tables to the document, displays the occupied areas, adds some cells to each table, displays the occupied areas (they're the same since adding to an element that has been added before doesn't trigger a layout), and finally, manually triggers a relayout and displays the final occupied areas.