PDFBOX - header 在所有使用 easytable 的页面中

PDFBOX - header in all pages using easytable

我正在使用 pdfbox 和 easytable https://github.com/vandeseer/easytable 创建动态页面,效果很好。但我确实希望在所有页面中添加 header。我faced/tried下面的东西。

1) Tablebuilder is created before writing rows so we can create a perfect tablebuilder since rows are dynamic.

2) Tried to insert header in middle while creating tablebuilder which again is not perfect since TableDrawer makes the rows to suffice according to row height

任何 idea/help 将不胜感激。

需要类似于此项目的输出 - https://github.com/eduardohl/Paginated-PDFBox-Table-Sample。唯一的问题是内容不像 easytable 那样动态。

这个答案是在更早的时候写的,当时 easytable 还不支持重复 table headers。同时,请参阅 the answer by philonous,简单 table 作者。

easytable 不支持重复 table header 或页脚。 还没有我应该说因为这个功能实际上很容易实现。

但是,很难在 之上实现 easytable,因为该库(与许多其他库一样)存在过度数据隐藏的问题:许多有趣的成员变量和方法是 private,因此扩展 类 不是一个可行的选择。

但是您可以将 header 行作为一个单独的 table 行来处理,您可以一次又一次地绘制!缺点是设置有点口是心非。

如果是你提到的测试代码TwoPagesTableTest,可以这样改:

final Table.TableBuilder tableHeaderBuilder = Table.builder()
        .addColumnOfWidth(200)
        .addColumnOfWidth(200);

CellText dummyHeaderCell = CellText.builder()
        .text("Header dummy")
        .backgroundColor(Color.BLUE)
        .textColor(Color.WHITE)
        .borderWidth(1F)
        .build();

tableHeaderBuilder.addRow(
        Row.builder()
                .add(dummyHeaderCell)
                .add(dummyHeaderCell)
                .build());

Table tableHeader = tableHeaderBuilder.build();

final Table.TableBuilder tableBuilder = Table.builder()
        .addColumnOfWidth(200)
        .addColumnOfWidth(200);

CellText dummyCell = CellText.builder()
        .text("dummy")
        .borderWidth(1F)
        .build();

for (int i = 0; i < 50; i++) {
    tableBuilder.addRow(
            Row.builder()
                    .add(dummyCell)
                    .add(dummyCell)
                    .build());
}

TableDrawer drawer = TableDrawer.builder()
        .table(tableBuilder.build())
        .startX(50)
        .endY(50F) // note: if not set, table is drawn over the end of the page
        .build();

final PDDocument document = new PDDocument();

float startY = 100F;

do {
    TableDrawer headerDrawer = TableDrawer.builder()
            .table(tableHeader)
            .startX(50)
            .build();

    PDPage page = new PDPage(PDRectangle.A4);
    document.addPage(page);
    try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
        headerDrawer.startY(startY);
        headerDrawer.contentStream(contentStream).draw();
        drawer.startY(startY - tableHeader.getHeight());
        drawer.contentStream(contentStream).draw();
    }

    startY = page.getMediaBox().getHeight() - 50;
} while (!drawer.isFinished());

document.save("twoPageTable-repeatingHeader.pdf");
document.close();

(RepeatingTableHeaders 测试 createTwoPageTableRepeatingHeader)

如您所见,代码首先创建一个单独的 Table tableHeader,仅包含 header 行。这个 table 然后首先添加到每个页面上,然后添加 body 行的一部分 table。

结果:每页 table headers...

一句警告:这是一个概念证明,我只用 TwoPagesTableTest 的 table 生成代码进行了测试。对于生产代码,您应该应用进一步的测试。

作为对@mkl 的回答及其评论的补充:在当前版本的库中,有一个 class 来满足这个要求。

所以您的代码基本上可以归结为:

try (final PDDocument document = new PDDocument()) {

    RepeatedHeaderTableDrawer.builder()
            .table(createTable())
            .startX(50)
            .startY(100F)
            .endY(50F) // note: if not set, table is drawn over the end of the page
            .build()
            .draw(() -> document, () -> new PDPage(PDRectangle.A4), 50f);

    document.save("your-awesome-document.pdf");
}