在 iText7 上正确对齐

Proper alignment on iText7

我一直在努力使用 iText7 创建布局。我读了很多书并尝试了很多变体,但我仍然无法按照我需要的方式获得它。如果有人能帮忙...这就是我所拥有的:

在这张照片中,有些地方我仍然无法解决。

  1. 尽管图像是垂直居中的,但文本未垂直居中
  2. 当图片在左边时,文字离图片太近

我尝试并阅读了很多我提到的东西,其中之一,但绝对不限于:

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

这是生成 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

关于我在这里做错了什么有什么想法吗?我有点没力气提取自动取款机...感谢您的帮助。

谢谢

iText 中的浮动元素功能基于 CSS 概念,并且行为非常相似。让我在这里解释一些细节。

我先回答第二个问题。要在图像和围绕它的内容之间获得一些间距,您应该为浮动图像使用边距属性。例如。在你的例子中是 image.setMarginRight(5)。 浮动元素使内容环绕在它们周围,但是块框的定位不受影响,块的定位就好像根本没有浮动一样。因此,当您为段落指定填充时,它仍然存在,但它是 "under" 图像。

看看这个 HTML 片段,它演示了适用于 iText 布局的相同行为: https://jsfiddle.net/cah7uzed/2/ 注意图片下方的填充。


你的第一个问题比较棘手。问题是垂直对齐一次应用于单元格的全部内容,将其所有子元素视为一个块。因此,在对齐这个大块时,文本会随着浮动图像的上边缘移动。

目前没有适合您的用例的开箱即用的简单解决方案。我认为您需要的是 CSS flex 属性 的某种模拟,它允许居中对齐位于一行中的所有块,但 iText 目前不支持它。

不过我可以想到一个解决方法。您可以用固定高度等于浮动元素高度的 Div 元素包裹段落,并另外为此 Div 指定垂直对齐方式。 如果您希望高度根据内容动态变化,您可以预先计算容器的高度,如此答案所示:。此处显示的技术适用于所有模型元素,包括 Paragraph.

一般情况下,您需要预先计算浮动元素和段落的高度,然后选择较大的一个。为了简化一点,根据您的具体情况并假设您知道图像高度将始终大于文本高度,您可以简单地为 Div 指定图像高度。在这种情况下,您的代码将如下所示:

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;
}