Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper alignment on iText7

Tags:

c#

itext7

I have been struggling with creating a layout using iText7. I read a lot and tried a lot of variations, but I'm still unable to get it the way I need. If anyone could help... This is what I have:

enter image description here

In this picture there are some things I still can't fix.

  1. The text is not vertically centered, although the image is
  2. When the image is on the left, the text is too close to the image

I tried and read a lot of things as I mentioned, one of them, but definitely not limited to, was:

https://developers.itextpdf.com/examples/tables/clone-alignment-indentation-leading-and-spacing-cells

This is the code generating that PDF:

private static Cell GetCell(int position, ...)
{
    var cell = new Cell();
    var isEven = (position + 1) % 2 == 0;

    if (image != null && record != null)
    {
        var paragraph = new Paragraph(
            $"t1\n"
        );

        if (!string.IsNullOrEmpty(t2))
            paragraph.Add($"t2\n");

        // ...

        image.SetProperty(Property.FLOAT, isEven ? FloatPropertyValue.LEFT : FloatPropertyValue.RIGHT);
        cell.Add(image)
            .Add(paragraph.SetPaddingLeft(5))
            .SetVerticalAlignment(VerticalAlignment.MIDDLE);
    }

    cell.SetBorder(Border.NO_BORDER);
    cell.SetBackgroundColor(isEven ? WebColors.GetRGBColor("#DEDEDE") : WebColors.GetRGBColor("#FFFFFF"));

    return cell;
}

var table = new Table(1);

table.SetWidth(TableWidth).SetHeight(TableHeight);
table.SetFontSize(7);
table.SetBorder(new SolidBorder(WebColors.GetRGBColor("#333333"), 2));
// add cells to table

Any ideas on what am I doing wrong here? I'm kinda out of hair to pull out atm... appreciate any help.

Thanks

like image 724
eestein Avatar asked Nov 29 '25 14:11

eestein


1 Answers

Floating elements functionality in iText is based on the CSS concepts and the behaviour is quite similar. Let me explain some of the details here.

I'll first answer the second question. To get some spacing between image and the content that wraps around it, you should use margin properties for floated image. E.g. in your case it's image.setMarginRight(5). Floating elements make content wrap around them, however block boxes positioning is not affected, blocks are positioned as if there were no floats at all. Thus when you specify padding for the paragraph, it's still there but it's "under" the image.

Have a look at this HTML snippet that demonstrates the same behaviour that applies in iText layouting: https://jsfiddle.net/cah7uzed/2/ Pay attention at padding that works below the image.


The first of your questions is more tricky. The thing is that vertical alignment is applied for the whole content of the cell at once, treating all it's children elements as a single chunk. Therefore text is moved along with the top edge of the floating image while aligning this single big chunk.

Currently there is no out of the box simple solution for your use case. I think what you need is some kind of analog of CSS flex property, which allows to center-align all the blocks positioned in a row, but iText currently doesn't support it.

I can think of a workaround though. You can wrap paragraph with Div element with fixed height equal to the floating element height and additionally specify vertical alignment for this Div. If you want heights to be dynamic depending on the content, you can precalculate container's height like it's shown in this answer: https://stackoverflow.com/a/41788843/4495409. Technic shown there applies to all model elements including Paragraph.

In general case you would want to precalculate both floating element and paragraph heights and choose the bigger one. To simplify a bit, based off your specific case and assuming that you know that image height is going to be always bigger than text height, you can simply specify image height for the Div. In this case your code would look like this:

private static Cell GetCell(int position, ...)
{
    var cell = new Cell();
    var isEven = (position + 1) % 2 == 0;

    if (image != null && record != null)
    {
        var paragraph = new Paragraph(
                $"t1\n"
        );

        if (!string.IsNullOrEmpty(t2))
            paragraph.Add($"t2\n");

        // ...

        // This gives the original image height,
        // it doesn't take into account any set properties.
        float imageHeight = image.GetImageHeight();

        var div = new Div()
                .Add(paragraph)
                .SetHeight(imageHeight)
                .SetVerticalAlignment(VerticalAlignment.MIDDLE);


        if (isEven) {
            image.SetMarginRight(5);
        } else {
            image.SetMarginLeft(5);
        }

        image.SetProperty(Property.FLOAT, isEven ? FloatPropertyValue.LEFT : FloatPropertyValue.RIGHT);
        cell.Add(image)
                .Add(div)
                .SetVerticalAlignment(VerticalAlignment.MIDDLE);
    }

    cell.SetBorder(Border.NO_BORDER);
    cell.SetBackgroundColor(isEven ? WebColors.GetRGBColor("#DEDEDE") : WebColors.GetRGBColor("#FFFFFF"));

    return cell;
}
like image 95
Yulian Gaponenko Avatar answered Dec 02 '25 03:12

Yulian Gaponenko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!