PDFBOX - header in all pages using easytable

对着背影说爱祢 提交于 2020-06-16 05:08:26

问题


I am using pdfbox and easytable https://github.com/vandeseer/easytable for creating dynamic pages which works great. But I do want header to be added in alL pages. I faced/tried below things.

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

Any idea/help would be appreciated.

Need output similar to this project - https://github.com/eduardohl/Paginated-PDFBox-Table-Sample . only problem here being the content is not dynamic like easytable.


回答1:


easytable does not support repeating table headers or footers. Not yet I should say because this feature actually is easy to implement.

It is difficult, though, to implement on top of easytable because that library (like many others) suffers from excessive data hiding: many interesting member variables and methods are private, so extending the classes is not a viable option.

But what you can do is handle the header rows as a separate table which you draw again and again! The downside is a bit of duplicity of settings.

In case of the test code TwoPagesTableTest you referred to, it can be changed like this:

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 test createTwoPageTableRepeatingHeader)

As you see, the code first creates a separate Table tableHeader containing only the header row. This table then is added first on each page and a part of the body rows table is added thereafter.

The result: table headers on each page...

A word of warning: This is a proof of concept, I have only tested with the table generation code from TwoPagesTableTest. For production code you should apply further tests.




回答2:


As an addition to @mkl's answer and its comments: In current versions of the library there is a class of its own for this very requirement.

So your code basically boils down to something like:

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


来源:https://stackoverflow.com/questions/54233886/pdfbox-header-in-all-pages-using-easytable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!