PDFBOX-使用easytable的所有页面标题

时间:2019-01-17 10:29:41

标签: java pdfbox

我正在使用pdfbox和easytable https://github.com/vandeseer/easytable创建动态页面,效果很好。但我确实希望在AlL页面中添加标头。我在下面遇到/尝试过。

  

1)Tablebuilder是在写行之前创建的,因此由于行是动态的,因此我们可以创建一个完美的tablebuilder。

     

2)尝试在创建tablebuilder时在中间插入标头,但这又不是完美的,因为TableDrawer使行根据行高就足够了

任何想法/帮助将不胜感激。

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

2 个答案:

答案 0 :(得分:2)

easytable不支持重复表格的页眉或页脚。 还不是我应该说,因为此功能实际上易于实现。

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

但是您可以做的是将标题行作为单独的表格处理,并一次又一次绘制!缺点是设置有些重复。

对于您所引用的测试代码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,仅包含标题行。然后,首先在每个页面上添加此表,然后再添加主体行表的一部分。

结果:每个页面上的表标题...

screen shot

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

答案 1 :(得分:2)

作为@mkl答案及其注释的补充:在当前版本的库中,针对此要求有自己的一类。

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

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