Skip to main content
Skip table of contents

How to add a background image to a cell?


I want to create a document which contains a table with cells with the same background image and text.


I have the following requirements:

  1. I want to create a document which contains one table. Inside that table, there are cells.

  2. I want to make each cell with specific height.

  3. each cell have the same background image.

  4. I want to put a text in front the image in the position I want inside the cell. For example: top left of the cell, bottom right of the cell.

Posted on StackOverflow on Jul 1, 2015 by lasheul

In other words: you want something like this: position_content_in_cell.pdf

Image in cell

Image in cell

There is more than one way to do this. Note that PdfPCell class does not exist in iText 7 anymore. You should use Cell instead. To add your own custom image and text you need to extend CellRenderer and override draw() method:

JAVA
private class ImageAndPositionRenderer extends CellRenderer {
    private Image img;
    private String content;
    private POSITION position;

    public ImageAndPositionRenderer(Cell modelElement, Image img, String content, POSITION position) {
        super(modelElement);
        this.img = img;
        this.content = content;
        this.position = position;
    }

    @Override
    public void draw(DrawContext drawContext) {
        super.draw(drawContext);
        img.scaleToFit(getOccupiedAreaBBox().getWidth(), getOccupiedAreaBBox().getHeight());

        img.getProperty(Property.HORIZONTAL_SCALING);

        drawContext.getCanvas().addXObject(img.getXObject(),
                getOccupiedAreaBBox().getX() +
                        (getOccupiedAreaBBox().getWidth()
                                - img.getImageWidth() * (float) img.getProperty(Property.HORIZONTAL_SCALING)) / 2,
                getOccupiedAreaBBox().getY() +
                        (getOccupiedAreaBBox().getHeight()
                                - img.getImageHeight() * (float) img.getProperty(Property.VERTICAL_SCALING)) / 2,
                img.getImageWidth() * (float) img.getProperty(Property.HORIZONTAL_SCALING));
        drawContext.getCanvas().stroke();

        Paragraph p = new Paragraph(content);
        Leading leading = p.getDefaultProperty(Property.LEADING);
        Float defaultFontSize = new DocumentRenderer(new Document(drawContext.getDocument())).getPropertyAsFloat(Property.FONT_SIZE);

        float x;
        float y;
        TextAlignment alignment;
        switch (position) {
            case TOP_LEFT:
                x = getOccupiedAreaBBox().getLeft() + 3;
                y = getOccupiedAreaBBox().getTop() - defaultFontSize * leading.getValue();
                alignment = TextAlignment.LEFT;
                break;
            case TOP_RIGHT:
                x = getOccupiedAreaBBox().getRight() - 3;
                y = getOccupiedAreaBBox().getTop() - defaultFontSize * leading.getValue();
                alignment = TextAlignment.RIGHT;
                break;
            case BOTTOM_LEFT:
                x = getOccupiedAreaBBox().getLeft() + 3;
                y = getOccupiedAreaBBox().getBottom() + 3;
                alignment = TextAlignment.LEFT;
                break;
            case BOTTOM_RIGHT:
                x = getOccupiedAreaBBox().getRight() - 3;
                y = getOccupiedAreaBBox().getBottom() + 3;
                alignment = TextAlignment.RIGHT;
                break;
            default:
                x = 0;
                y = 0;
                alignment = TextAlignment.CENTER;
        }
        new Canvas(drawContext.getCanvas(), drawContext.getDocument(), getOccupiedAreaBBox()).showTextAligned(p, x, y, alignment);
    }
}

So we’ve set the rules too add an image and draw some text inside the cell. We’ll use ImageAndPositionRenderer in setNextRenderer() method like this:

JAVA
cell1.setNextRenderer(new ImageAndPositionRenderer(cell1,
            new Image(ImageDataFactory.create(IMG)), "Top left", POSITION.TOP_LEFT));

Where cell1 is a Cell object. Don’t forget to set the specific height for each cell:

cell1.setHeight(50); Normally, I would write this code in a more efficient way, but I order the code lines in a way so that they reflect your requirements 1, 2, 3 and 4 literally.

OK, but how can I stretch the image?

Please check the PositionContentInCell example for the full code. As you see, we’ve used scaleToFit() method to stretch the image. Without this line, you’ll get the following result:

Scaled image in cell

Scaled image in cell

How can I position the image inside a cell using x and y coordinates

That required an extra example: PositionContentInCell2.

Instead of using the POSITION enumeration, you asked if it was possible to pass x and y values. You could do that, but you probably won't always know the width and the height of the cells, so why not define percentages such as wPct and hPct, along with an alignment:

JAVA
private class ImageAndPositionRenderer extends CellRenderer {
    private Image img;
    private String content;
    private TextAlignment alignment;
    private float wPct;
    private float hPct;

    public ImageAndPositionRenderer(Cell modelElement, float wPct, float hPct,
                                    Image img, String content, TextAlignment alignment) {
        super(modelElement);
        this.img = img;
        this.content = content;
        this.alignment = alignment;
        this.wPct = wPct;
        this.hPct = hPct;
    }

    @Override
    public void draw(DrawContext drawContext) {
        super.draw(drawContext);

        drawContext.getCanvas().addXObject(img.getXObject(), getOccupiedAreaBBox());
        drawContext.getCanvas().stroke();

        float x = getOccupiedAreaBBox().getX() + wPct * getOccupiedAreaBBox().getWidth();
        float y = getOccupiedAreaBBox().getY() + hPct * (getOccupiedAreaBBox().getHeight() - drawContext.getCanvas().getGraphicsState().getLeading());
        new Document(drawContext.getDocument()).showTextAligned(content, x, y, alignment);

    }
}

Now you can add these events like this:

JAVA
cell1.setNextRenderer(new ImageAndPositionRenderer(cell1, 0, 1,
            new Image(ImageDataFactory.create(IMG)), "Top left", TextAlignment.LEFT));

Click How to add a background image to a cell? if you want to see how to answer this question in iText 5.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.