创建一个矩形,在其中添加段落并使用 iText 根据文本调整矩形的高度

Create a rectangle, add paragraph inside that and adjust the height of the rectangle according to the text using iText

我可以创建一个矩形并在其中添加段落和图像。矩形的宽度也可以,但我只想根据段落中的文本设置矩形的高度。此外,我想以特定方式在矩形内添加数据,这就是我在其中创建 table 的原因。那么如何让table填满整个矩形。有人可以帮我解决这个问题吗?

        PdfContentByte cb = writer.getDirectContent();

        Rectangle rect = new Rectangle(kBorderInset, document.getPageSize().getHeight()-kPageDisclaimerY,
                document.getPageSize().getWidth()-2 * kBorderInset,700f);
        cb.rectangle(rect);
        cb.stroke();

        rect.setBorder(Rectangle.BOX);
        rect.setBorderWidth(1);
        rect.setBorderColor(BaseColor.BLACK);
        cb.rectangle(rect);

        ColumnText ct = new ColumnText(cb);
        ct.setSimpleColumn(rect);
        ct.addElement(createTable1(auditBundle, context));
        ct.go();

创建table代码

       private static PdfPTable createTable1(AuditBundle auditBundle, Context context) throws 
       DocumentException {
           PdfPTable table = new PdfPTable(3);
           table.setWidthPercentage(100);
           table.getDefaultCell().setUseAscender(true);
           table.getDefaultCell().setUseDescender(true);
           table.getDefaultCell().setFixedHeight(112f);
           table.setWidths(new int[]{1, 2, 1});

    float fntSize, lineSpacing;
    fntSize = 20f;
    lineSpacing = 12f;
    Paragraph paragraph = new Paragraph();
    paragraph.add(new Phrase(lineSpacing,auditBundle.getAudit().auditName,
            FontFactory.getFont(FontFactory.HELVETICA, fntSize)));
    paragraph.setAlignment(Element.ALIGN_LEFT | Element.ALIGN_CENTER);
    paragraph.setPaddingTop(30);
    PdfPCell cell = new PdfPCell();
    cell.addElement(paragraph);
    cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
    table.addCell("");
    table.addCell(cell);

    Drawable d = context.getDrawable(R.drawable.ic_action_device_access_camera); // the drawable (Captain Obvious, to the rescue!!!)
    assert d != null;
    Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] bitmapdata = stream.toByteArray();

    PdfPCell cellImg = new PdfPCell();
    try {
        Image image = Image.getInstance(bitmapdata);
        image.setAlignment(Element.ALIGN_CENTER);
        cellImg.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cellImg.addElement(image);
        cellImg.setBackgroundColor(BaseColor.WHITE);
    } catch (IOException e) {
        e.printStackTrace();
    }
    table.addCell(cellImg);
    return table;
}

目前看起来是这样的:

如果您的内容位于 table 中,并且您想在其周围绘制一个矩形,最直接的方法是使用 table 边框。这消除了绘制额外矩形的需要。

如果需要单独绘制矩形,您可以简单地添加内容并获得最终的垂直位置(writer.getVerticalPosition(false))。然后根据添加内容前后的垂直位置绘制矩形。

不过,确定呈现一段内容所需区域的一般问题仍然是一个有趣的问题。因此,我将在问题中定义的 table 的上下文中进行回复,尽管这可能不是最有用的方法。它可以应用于其他类型的内容和用例。

首先,在 PDF 中,坐标从左到右增加,从底部到顶部增加。您正在使用的 Rectangle 构造函数是 Rectangle(final float lowerleftx, final float lowerlefty, final float upperrightx, final float upperrighty)。所以 lowerlefty 应该比 upperrighty 小。 您也可以忽略它,定义 Rectangle "upside down" 并调用 Rectangle.normalize().

要确定呈现内容所需的垂直 space,您可以在模拟模式下 运行 ColumnText。它将执行所有呈现逻辑,而无需实际将内容写入 PDF 文档。然后,您可以使用该模拟中的信息 运行 在第二阶段调整实际渲染。

PdfContentByte cb = writer.getDirectContent();

// the initial rectangle defines the max size of the content
Rectangle rect = new Rectangle(10, document.getPageSize().getBottom() + 50,
        document.getPageSize().getWidth() - 2 * 10, document.getPageSize().getTop() - 50);

// flip the rectangle if top and bottom were switched
rect.normalize();

ColumnText ct = new ColumnText(cb);
ct.setSimpleColumn(rect);
ct.addElement(createTable1(auditBundle, context));

// do a simulation run
int result = ct.go(true);

// assume the content fits in the initial rectangle
if (result == ColumnText.NO_MORE_TEXT) {

    // the bottom of the simulated content
    float verticalpos = ct.getYLine();

    // redefine the rectangle based on the simulation
    rect = new Rectangle(10, verticalpos, document.getPageSize().getWidth() - 2 * 10,
            document.getPageSize().getTop() - 50);
    ct.setSimpleColumn(rect);

    // the original content was consumed in the simulation, so add it again
    ct.addElement(createTable1(auditBundle, context));

    // render again
    ct.go(false);

    // draw the rectangle
    rect.setBorder(Rectangle.BOX);
    rect.setBorderWidth(1);
    rect.setBorderColor(BaseColor.RED);
    cb.rectangle(rect);

}

对原始代码的进一步修改:

  • 去掉了table单元格的固定高度,可以更清楚地展示矩形的增长和缩小:去掉了table.getDefaultCell().setFixedHeight(112f)
  • 删除了 table 边框并将矩形颜色更改为红色以更清楚地显示矩形。

短文本结果:

长文本结果: