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:

In this picture there are some things I still can't fix.
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
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With