我正在使用pdfbox和easytable https://github.com/vandeseer/easytable创建动态页面,效果很好。但我确实希望在AlL页面中添加标头。我在下面遇到/尝试过。
1)Tablebuilder是在写行之前创建的,因此由于行是动态的,因此我们可以创建一个完美的tablebuilder。
2)尝试在创建tablebuilder时在中间插入标头,但这又不是完美的,因为TableDrawer使行根据行高就足够了
任何想法/帮助将不胜感激。
需要类似于该项目的输出-https://github.com/eduardohl/Paginated-PDFBox-Table-Sample。唯一的问题是内容不是像easytable一样动态的。
答案 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
,仅包含标题行。然后,首先在每个页面上添加此表,然后再添加主体行表的一部分。
结果:每个页面上的表标题...
警告:这是一个概念证明,我仅使用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");
}