Java 如何使用onEndPage方法打印PDF标题中的动态字符串

Java 如何使用onEndPage方法打印PDF标题中的动态字符串,java,itext,pdf-generation,Java,Itext,Pdf Generation,我的pdf文档中有多个表,当以pdf格式打印其中一个表时,我需要在打印该表的所有页面的标题部分打印该表的名称。此外,需要根据表名更改标题值 我已经尝试为每个表的标题设置新表名,但是所有页面只打印最后一个表名 示例代码 PdfGenerator.class public static void main(String[] args) throws FileNotFoundException, DocumentException { try {

我的pdf文档中有多个表,当以pdf格式打印其中一个表时,我需要在打印该表的所有页面的标题部分打印该表的名称。此外,需要根据表名更改标题值

我已经尝试为每个表的标题设置新表名,但是所有页面只打印最后一个表名

示例代码

PdfGenerator.class



    public static void main(String[] args) throws FileNotFoundException, DocumentException {

        try {
            String pdfFilePath = "C:\\Users\\ychitela\\Desktop\\demo\\NewPdf.pdf";
            File file = new File(pdfFilePath);
            FileOutputStream fileout = new FileOutputStream(file);
            Document document = new Document(PageSize.A4.rotate(), 36, 36, 55, 25);
            PdfWriter writer = PdfWriter.getInstance(document, fileout);
            ReportHeader event = new ReportHeader();
            writer.setPageEvent(event);
            writer.setViewerPreferences(PdfWriter.PageModeUseOutlines);
            document.open();
            document.addAuthor("Me");
            document.addTitle("Table Report");

            Font font = FontFactory.getFont("TIMES_ROMAN", 12, BaseColor.BLACK);
            document.add(new Paragraph("Intro Page"));
            document.newPage();
            Chapter chapter = new Chapter(new Paragraph("Table \n\n"), 0);
            chapter.setNumberDepth(0);
            chapter.add(new Paragraph("   "));
            for (int i = 1; i < 5; i++) {

                float[] columnWidths = { 1f, 1f };
                // create PDF table with the given widths
                PdfPTable table = new PdfPTable(columnWidths);
                table.setHorizontalAlignment(Element.ALIGN_LEFT);
                table.setWidthPercentage(30.0f);
                Section subsection = chapter.addSection(new Paragraph("Table "+i+" \n\n"), 0);
                event.setTableName("Table header" + i);
                writer.setPageEvent(event);
                table.addCell(new PdfPCell(new Phrase("Column 1", font)));
                table.addCell(new PdfPCell(new Phrase("Column 2", font)));
                table.setHeaderRows(1);
                for (int j = 0; j < 25; j++) {
                    table.addCell(new PdfPCell(new Phrase("Hello" + j, font)));
                    table.addCell(new PdfPCell(new Phrase("World" + j, font)));
                }
                subsection.add(table);
                subsection.newPage();

            }
            document.add(chapter);
            document.close();
            System.out.println("Done");
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }


正如您自己发现的,问题的原因是

我在实际代码和循环中使用了章节和小节,在循环结束时,我将章节添加到文档中。因此,这导致只打印最后一个表名

要使动态标题按原样工作,您必须提前添加内容;特别是,每次添加新表时,即每次页眉更改时,都必须将章节的当前内容添加到文档中

您可以利用
Chapter
实现
LargeElement
,即可以多次向文档中添加
Chapter
实例,每次仅将自上次以来章节中的所有新内容写入文档。为此,您必须在开始时将其
Complete
属性设置为
false
,只有在最后一次添加之前才能将其设置为
true
。因此,

Chapter chapter = new Chapter(new Paragraph("Table \n\n"), 0);
// prepare chapter to be set piecewise
chapter.setComplete(false);
chapter.setNumberDepth(0);
chapter.add(new Paragraph("   "));
for (int i = 1; i < 5; i++) {

    float[] columnWidths = { 1f, 1f };
    // create PDF table with the given widths
    PdfPTable table = new PdfPTable(columnWidths);
    table.setHorizontalAlignment(Element.ALIGN_LEFT);
    table.setWidthPercentage(30.0f);
    // add recent chapter additions
    document.add(chapter);
    Section subsection = chapter.addSection(new Paragraph("Table "+i+" \n\n"), 0);
    event.setTableName("Table header" + i);
    writer.setPageEvent(event);
    table.addCell(new PdfPCell(new Phrase("Column 1", font)));
    table.addCell(new PdfPCell(new Phrase("Column 2", font)));
    table.setHeaderRows(1);
    for (int j = 0; j < 25; j++) {
        table.addCell(new PdfPCell(new Phrase("Hello" + j, font)));
        table.addCell(new PdfPCell(new Phrase("World" + j, font)));
    }
    subsection.add(table);
    subsection.newPage();

}
// prepare chapter to be completed
chapter.setComplete(true);
// final adding of chapter
document.add(chapter);
Chapter Chapter=新章节(新段落(“表”),0;
//准备要分段设置的章节
第章.设置完成(错误);
第章设置编号第pth(0)条;
第章.添加(新的段落(“”);
对于(int i=1;i<5;i++){
float[]列宽={1f,1f};
//创建具有给定宽度的PDF表格
PdfPTable table=新PdfPTable(列宽);
表.setHorizontalAlignment(元素.ALIGN_左);
表3.设置宽度百分比(30.0f);
//添加最近的章节增补
文件.增补(第章);
章节小节=章节添加章节(新段落(“表”+i+“\n\n”),0);
事件.setTableName(“表头”+i);
writer.setPageEvent(事件);
表2.addCell(新的PdfPCell(新短语(“第1栏”,字体));
表2.addCell(新的PdfPCell(新短语(“第2栏”,字体));
表2.setHeaderRows(1);
对于(int j=0;j<25;j++){
表.addCell(新的PdfPCell(新短语(“Hello”+j,font)));
表.addCell(新的PdfPCell(新短语(“世界”+j,字体));
}
增加(表)小节;
第.newPage()小节;
}
//准备要完成的章节
第章设置完成(正确);
//最后增加一章
文件.增补(第章);

(test
testlikeyuvarajchitelaemodified

“因为只有在关闭整个文档后才调用onEndPage方法。”-不,不是。但是您的代码在
document.left()、document.bottom()
处绘制表格,即在页面底部,就在可见区域之外。所以,您在输出中看到的标题并不是由该代码生成的……您好,您能展示一下您试图实现的目标吗?文本描述似乎并不能描述所有的问题details@AlexeySubach这是示例文档。我的pdf打印了多个表格,在每一页的页脚或页眉处都应打印该页中表格的名称。我仍然无法重现最后一个表格的名称将打印在所有页面上的情况-如果许多页面上有许多表格,这实际上是不可能的,在将最后一个表的名称设置为页面事件实例之前,第一个表很早就被写入到输出中,因此名称不能出现在这些第一个页面上。但是您的代码中有一个问题,
PdfWriter.setPageEvent
“setter”实际上不是一个“setter”,而是一个“adder”:它不会覆盖上一个页面事件侦听器,而是添加到它。要替换它,请首先
setPageEvent(null)
,它将清除集合。@mkl感谢您的评论,它们非常有用。终于找到了问题所在。我在实际代码和循环中使用了章节和小节,在循环结束时,我将章节添加到文档中。因此,这导致只打印最后一个表名。我正在用实际代码更新代码以显示问题。
Chapter chapter = new Chapter(new Paragraph("Table \n\n"), 0);
// prepare chapter to be set piecewise
chapter.setComplete(false);
chapter.setNumberDepth(0);
chapter.add(new Paragraph("   "));
for (int i = 1; i < 5; i++) {

    float[] columnWidths = { 1f, 1f };
    // create PDF table with the given widths
    PdfPTable table = new PdfPTable(columnWidths);
    table.setHorizontalAlignment(Element.ALIGN_LEFT);
    table.setWidthPercentage(30.0f);
    // add recent chapter additions
    document.add(chapter);
    Section subsection = chapter.addSection(new Paragraph("Table "+i+" \n\n"), 0);
    event.setTableName("Table header" + i);
    writer.setPageEvent(event);
    table.addCell(new PdfPCell(new Phrase("Column 1", font)));
    table.addCell(new PdfPCell(new Phrase("Column 2", font)));
    table.setHeaderRows(1);
    for (int j = 0; j < 25; j++) {
        table.addCell(new PdfPCell(new Phrase("Hello" + j, font)));
        table.addCell(new PdfPCell(new Phrase("World" + j, font)));
    }
    subsection.add(table);
    subsection.newPage();

}
// prepare chapter to be completed
chapter.setComplete(true);
// final adding of chapter
document.add(chapter);