You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用iText PDF 7无法居中页脚?样式被覆盖问题求助

问题描述

我正在开发一款PDF生成器,需根据生成的文件类型添加两种不同页脚:一种是仅显示“This PDF is a sample”文本的页脚,另一种是包含短描述和两个Logo的三列表格页脚。但调用事件处理器后,文本和表格的样式均被覆盖,无法将页脚居中;表格还出现宽度被压缩、Logo与文本无间距的问题,且页脚位置会随页数变化。我已尝试为所有对象设置水平对齐,相关代码如下:

单元格代码

Image trustedImage = new Image(ImageDataFactory.create(pathLogo3));
trustedImage.scaleToFit(100, 100);

Cell trustedIdentity = new Cell().setBorder(new SolidBorder(whiteColor, 1f));
trustedIdentity.add(trustedImage.setHorizontalAlignment(HorizontalAlignment.CENTER));
table.addCell(trustedIdentity.setVerticalAlignment(VerticalAlignment.MIDDLE));

事件处理器调用代码

pdf.addEventHandler(PdfDocumentEvent.END_PAGE, new TableFooterEventHandler(creaTabellaFineDocumentoPlaceholder()));

TableFooterEventHandler类代码

import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.HorizontalAlignment;

public class TableFooterEventHandler implements IEventHandler {

    private Table table;
    public TableFooterEventHandler(Table table) {
        this.table=table;
    }

    @Override
    public void handleEvent(Event event) {

        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfDocument pdfDoc = docEvent.getDocument();
        PdfPage page = docEvent.getPage();
        PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);

        float tableHeight = table.getHeight() == null ? 30  :  table.getHeight().getValue();
        float tableWidth = table.getWidth() == null ? 30  :  table.getWidth().getValue();


        float x = (page.getPageSize().getWidth() - table.getWidth().getValue()) /2;

        new Canvas(canvas, new Rectangle(x, 20, table.getWidth().getValue(), 30))
                .add(table.setHorizontalAlignment(HorizontalAlignment.CENTER)).setHorizontalAlignment(HorizontalAlignment.CENTER)
                .close();
    }
}

我遵循iText官方示例开发,但除页脚样式外其他功能勉强可用,求问问题原因及修复方法。


问题分析与修复方案

1. 页脚无法居中、宽度压缩问题

原因

  • 复用同一个Table实例,iText添加到Canvas后会修改其内部状态,后续页面复用会导致样式错乱;
  • 未显式设置表格宽度,表格会自动收缩为内容宽度,引发压缩;
  • Canvas高度硬编码为30,若表格实际高度超出,会挤压内容。

修复代码

修改事件处理器,每次处理事件时创建表格副本,显式设置表格宽度为页面可用宽度:

import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.itextpdf.layout.properties.UnitValue;

public class TableFooterEventHandler implements IEventHandler {

    private final Table templateTable;

    public TableFooterEventHandler(Table templateTable) {
        this.templateTable = templateTable;
    }

    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfDocument pdfDoc = docEvent.getDocument();
        PdfPage page = docEvent.getPage();
        PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);

        Rectangle pageSize = page.getPageSize();
        float footerWidth = pageSize.getWidth() - 40; // 左右各留20边距
        // 创建表格副本,避免状态污染
        Table table = new Table(templateTable.getNumberOfColumns())
                .setWidth(UnitValue.createPercentValue(100))
                .setHorizontalAlignment(HorizontalAlignment.CENTER);
        
        // 复制原表格的单元格内容
        for (int i = 0; i < templateTable.getNumberOfRows(); i++) {
            table.addCell(templateTable.getCell(i).clone(true));
        }

        float footerY = 20; // 固定页脚在底部20位置
        float tableHeight = table.getHeight() != null ? table.getHeight().getValue() : 50;

        new Canvas(canvas, new Rectangle(pageSize.getLeft() + 20, footerY, footerWidth, tableHeight))
                .add(table)
                .close();
    }
}

2. Logo与文本无间距问题

原因

单元格未设置内边距,导致图片紧贴边框。

修复代码

修改单元格创建逻辑,添加内边距:

Image trustedImage = new Image(ImageDataFactory.create(pathLogo3));
trustedImage.scaleToFit(100, 100);

Cell trustedIdentity = new Cell()
        .setBorder(new SolidBorder(whiteColor, 1f))
        .setPadding(10) // 添加内边距拉开间距
        .setVerticalAlignment(VerticalAlignment.MIDDLE);
trustedIdentity.add(trustedImage.setHorizontalAlignment(HorizontalAlignment.CENTER));
table.addCell(trustedIdentity);

3. 页脚位置随页数变化问题

原因

原代码Canvas高度硬编码为30,表格高度超出时会导致内容溢出,位置偏移。修复后通过固定Y坐标,同时根据表格实际高度设置Canvas高度,确保页脚位置稳定。

4. 纯文本页脚居中问题

针对文本页脚,创建独立事件处理器,确保每次使用新的文本实例并设置居中:

import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.HorizontalAlignment;

public class TextFooterEventHandler implements IEventHandler {
    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfDocument pdfDoc = docEvent.getDocument();
        PdfPage page = docEvent.getPage();
        PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);

        Rectangle pageSize = page.getPageSize();
        Paragraph footerText = new Paragraph("This PDF is a sample")
                .setHorizontalAlignment(HorizontalAlignment.CENTER)
                .setFontSize(10);

        float footerY = 20;
        new Canvas(canvas, new Rectangle(pageSize.getLeft(), footerY, pageSize.getWidth(), 20))
                .add(footerText)
                .close();
    }
}

内容的提问来源于stack exchange,提问作者asdrubalo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:55:40