如何仅在 itext 7 表的每一页(最终)的第一行重复列值?

How to repeat column value only on first row in each page (eventual) in itext 7 tables?

我需要实现一个看起来像图片中的 table,每个页面的 table 的第一行仅重复 1 或 2 列值,最终呈现。

我尝试使用 Footer HandleEvent 如果 page > 1.

我在特定位置添加 canvas

这个解决方案存在一个问题:如果 table 仅在第一页呈现(在 table 之后有 3 行文本),在第二页我找到了我的文本第 1 e 2 列(ID 和姓名)。

有什么方法建议吗?

我想弄清楚 table 事件处理是否仍然存在于 itext7 中(setTableEvent` setter 不再适用于 Table itext7)?

// ...
Footer footerHandler = new Footer();
pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, footerHandler);
// ...
public virtual void HandleEvent(Event @event) {
    PdfDocumentEvent docEvent = (PdfDocumentEvent)@event;
    PdfDocument pdf = docEvent.GetDocument();
    PdfPage page = docEvent.GetPage();
    int pageNumber = pdf.GetPageNumber(page);
    // ...

    if (pageNumber !=1) {
          // get size of rectangle from file...

          Rectangle rect = new Rectangle(float.Parse(m.X_LABELNOME), float.Parse(m.Y_LABELNOME), float.Parse(m.WIDTH_LABELNOME), float.Parse(m.HEIGHT_LABELNOME));
          pdfCanvas = new PdfCanvas(page);
          Canvas mycanvas = new Canvas(pdfCanvas, rect);
          mycanvas.SetFontSize(9f);
          Paragraph mytext = new Paragraph(ID_Variable or Name Variable).SetTextAlignment(TextAlignment.CENTER);
          mycanvas.Add(mytext);
          mycanvas.Close();

          // ...

您可以自定义 TableRenderer 并覆盖其布局逻辑,以将单元格从 table 的前一部分复制到下一部分。

这是一个如何操作的示例(请注意,此代码依赖于一些 TableRenderer 本机实现细节,因此无法保证此代码适用于 iText 7 的所有未来更新) :

private static class CustomTableRenderer extends TableRenderer {
    public CustomTableRenderer(Table modelElement) {
        super(modelElement);
    }

    @Override
    public LayoutResult layout(LayoutContext layoutContext) {
        LayoutResult result = super.layout(layoutContext);
        if (result.getStatus() == LayoutResult.PARTIAL) {
            CustomTableRenderer overflowRenderer = (CustomTableRenderer) result.getOverflowRenderer();
            // Modify first two columns
            for (int i = 0; i < 2; i++) {
                CellRenderer previousTablePartCell = overflowRenderer.rows.get(0)[i];
                overflowRenderer.rows.get(0)[i] = (CellRenderer) ((Cell) previousTablePartCell.getModelElement()).createRendererSubTree().setParent(this);
            }
        }
        return result;
    }

    @Override
    public IRenderer getNextRenderer() {
        return new CustomTableRenderer((Table) getModelElement());
    }
}

现在我们需要做的就是将这个自定义渲染器设置为我们的 table。完整代码:

Document document = new Document(pdfDocument);

Table table = new Table(3).useAllAvailableWidth();
for (int i = 0; i < 10; i++) {
    table.addCell(new Paragraph("Hello " + i));

    table.addCell(String.valueOf(i));

    StringBuilder sb = new StringBuilder();
    for (int j = 0; j < 20; j++) {
        sb.append(UUID.randomUUID()).append("\n");
    }
    table.addCell(sb.toString());
}
table.setNextRenderer(new CustomTableRenderer(table));
document.add(table);

视觉效果: