How to precisely position an image on top of a Table?
I need to precisely position an image over a table, for example:
Observe that the image overlays a specific set of rows and columns: it overlays row 5 and row 13 partially, and rows 8-12 completely; it also overlays columns C and D partially.
In other words, I want to say that the top-left of the image should be in the cell C5, and 4pt below and 6pt to the right of the top-left of C5.
How do I do this? I thought I'll add the text to the table, add the table to the Document, and then query the table to get the absolute positions of the rows and columns, and then add the image to the Document
at that position, perhaps in direct content mode.
But the table may split across pages, because it may have hundreds of rows. In that case, I need to add the image to the right page, and at the right position.
Posted on StackOverflow on Feb 28, 2014 by Kartick Vaddadi
I've written some sample code that uses a table event. In the AddOverlappingImage class, we create a table and declare a table event to show how it can be used and how position of image can be calculated. And here I adapted this example to use also cell renderer to determine in which cell I would like to put the top-left corner of my image. This table renderer looks like this:
private class OverlappingImageTableRenderer extends TableRenderer {
private ImageData image;
public OverlappingImageTableRenderer(Table modelElement, Table.RowRange rowRange, ImageData img) {
super(modelElement, rowRange);
this.image = img;
}
public OverlappingImageTableRenderer(Table modelElement, ImageData img) {
super(modelElement);
this.image = img;
}
@Override
public void drawChildren(DrawContext drawContext) {
super.drawChildren(drawContext);
float x = Math.max(this.getOccupiedAreaBBox().getX() +
this.getOccupiedAreaBBox().getWidth() / 3 - image.getWidth(), 0);
float y = Math.max(this.getOccupiedAreaBBox().getY() +
this.getOccupiedAreaBBox().getHeight() / 3 - image.getHeight(), 0);
drawContext.getCanvas().addImage(image, x, y, false);
}
@Override
public IRenderer getNextRenderer() {
return new OverlappingImageTableRenderer((Table) modelElement, image);
}
}
}
I pass a DrawContext
to the drawChildren()
method, and calculate necessary x and y coordinates for drawing an image. I add the image to the 2nd row and the 3rd column (the index starts counting at 0), so I use the eighth cell with text "B3"
.
I hard-coded the cell position. Obviously, you should use some parameters, for instance a List
of images and coordinates.
Click this link if you want to see how to answer this question in iText 5.