【问题标题】:iText: Set height of table cell with imageiText:用图像设置表格单元格的高度
【发布时间】:2021-11-09 19:22:49
【问题描述】:

我用 iText 5.5.13.2(最新的 iText5 版本)创建了一个表格,并用从同一台 PC 上的特定文件夹读取的文本和图像填充它:

Paragraph p = new Paragraph();
p.add(new Phrase("This is a new paragraph!"));

PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100);

for(int i=0;i<imageArr.size();i++) { //imageArr.size()%2==0!
    PdfPCell cell = new PdfPCell();
    String name = imageArr.get(i);
    String path = imgFolder + File.separator + name;
    File f = new File(path);

    if(f.isFile()) {
        Image img = Image.getInstance(path);
        //cell.setCalculatedHeight(50);
        cell.addElement(img);
    } else {
        cell.addElement(new Phrase(name));
    }

    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
    cell.setHorizontalAlignment(Element.ALIGN_MIDDLE);
    //cell.setCalculatedHeight(50);
    table.addCell(cell);
}

p.add(table);
doc.add(p);

表格中的两列都使用相同的宽度(这很棒),并且大图像会自动调整大小以适应宽度(这也很棒),唯一不起作用的是:

所有单元格都应具有一定的高度,并且大图像应相应调整大小(同时仍保持适当的高度/宽度比)。在我将图像添加到单元格之前或之后使用setCalculatedHeight 似乎并不重要(只做一个或另一个,参见上面的代码),单元格总是根据图像的高度设置它的高度,所以行仅包含横向格式的文本或图像的行总是小于包含纵向格式的图像的行。

即使在使用img.setScaleToFitLineWhenOverflow(false)img.setScaleToFitHeight(false) 时,小图像也会调整大小(拉伸),但即使这样,高度也没有正确设置。

我已经尝试使用Chunk (cell.addElement(new Chunk(img, 0, 0))),但是图像很小,我的高度设置仍然被忽略。

如何设置单元格的高度并相应地调整图像大小?

【问题讨论】:

    标签: java itext


    【解决方案1】:

    我设法找到了解决方案。涉及大量测试,即使是现在我也不能 100% 确定它为什么会像大多数时间那样表现。

    首先:不要使用addElement 添加元素,因为一旦使用PdfPCell 调用它,iText 就会从“文本模式”(似乎也影响图像)切换到“复合模式”,然后从那时起忽略所有对齐,...该单元格的设置,包括文本的水平对齐 - 您可以找到原始 iText 开发人员here 的更详细解释(示例here)。而是先用Image 做任何你想做的事情,然后才用那个图像创建PdfPCell。之后可以编辑单元格 - 使用 table.getDefaultCell() 将不起作用,对其所做的更改不会对使用以下代码创建的单元格产生任何影响。

    我的工作代码:

    float docWidth = doc.getPageSize().getWidth() - doc.leftMargin() - doc.rightMargin();
    float docHeight = doc.getPageSize().getHeight() - doc.topMargin() - doc.bottomMargin();
    float docWidthDiv2 = docWidth/2 - 10;
    float docHeightDiv2 = docHeight/2 - 10;
    PdfPCell cell = null;
    
    if(f.isFile()) {
        Image img = Image.getInstance(path);
        //img.scaleAbsolute(100, 50);
    
        if(img.getWidth() < docWidthDiv2 && img.getHeight < docHeightDiv2) {
            cell = new PdfPCell(img, false);
        } else {
            cell = new PdfPCell(img, true);
        }
    } else {
        cell = new PdfPCell(new Phrase(name));
    }
    
    cell.setFixedHeight(50); //"setCalculatedHeight" doesn't work
    

    为什么我将图像的宽度与docWidthDiv2 进行比较,将图像的高度与docHeightDiv2 进行比较?

    有很多组合可以设置单元格的高度,但没有一个显示出我预期的 100% 的行为:应该缩小真正大的图像以适应列的宽度(对于横向模式下的图像更重要),但也尊重单元格的固定高度(对于纵向模式的图像更重要),同时仍保持其纵横比。已经很适合单元格的小图像根本不应该缩放。

    new PDfPCell(Image image, boolean fit) 的文档描述了 fit 参数:

    true 使图像适合单元格

    在我的情况下,true 调整图像的大小(同时仍然尊重其纵横比和单元格的高度),直到它接触到单元格的两个相对侧,因此:大图像的尺寸被缩小,小图像被拉伸。

    使用false,图像的纵横比和单元格的高度仍然受到尊重,但小图像保持其大小,横向模式下的大图像“渗入”相邻单元格(setScaleToFitLineWhenOverflow 无济于事)纵向模式下的大图像甚至可能根本不显示(当它们对于单元格来说太高时)。

    要不拉伸小图像而是减小大图像的大小,需要将两者结合起来。我只添加了-10,所以潜在的默认填充不会弄乱它。如果你想在表格之前或之后添加文字,那么你也必须从docHeightDiv2中减去它的高度。

    如前所述,我还测试了其他组合,我从中提取的最重要信息:

    如果在添加图片之前设置了单元格的高度,那么无论它比单元格小(单元格高度缩小)还是大(单元格高度增加),图像都会覆盖高度。

    在参数、设置图像大小和设置单元格高度之间可以使用几种组合,但其中大多数图像要么保持其原始大小(例如 2000x1000 在页)或它们的大小增加,直到它们接触到单元格的两个相对侧(这也增加了单元格的高度)。最后只剩下一个组合仍然有用(在我看来) - 一个例子:

    img.scaleAbsolute(100, 50);
    cell = new PdfPCell(img, false);
    cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //"center" doesn't work here
    cell.setHorizontalAlignment(Element.ALIGN_CENTER); //"middle" doesn't work here
    cell.setFixedHeight(150);
    

    这将在一个 150 单位高的单元格中心创建一个大小为 100x50(忽略原始纵横比)的图像(= 图像上方和下方 50 个单位的填充)。

    关于 iText 表格的附加信息:

    列平均共享表格的可用宽度,无需更改它,即使第一个单元格包含一个非常小的图像而第二个单元格包含一个非常大的图像。在这方面,您唯一需要注意的是添加的单元格数量 - 行始终必须完全填充,因此具有 3 列的表格每行必须包含 3 个单元格,否则该行获胜' 不会打印到 pdf 文件中(同样也不会打印空的新页面)。可以创建空的额外单元格来填充行的其余部分:

    PdfPCell extra = new PdfPCell();
    extra.setFixedHeight(50);
    table.addCell(extra);
    

    【讨论】:

      猜你喜欢
      • 2012-01-06
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-15
      • 1970-01-01
      相关资源
      最近更新 更多