java - Itext7 CellRenderer 并不总是有效

标签 java itext7

我正在使用 Itext7 创建一个包含表格的 pdf。
表格占多页。
我还重写了单元格渲染器以将表单域添加到某些单元格。
我注意到当表格转到新页面时,第一行不会触发 CellRender 类的 draw 方法。
我在下面放了一些代码以便更好地理解。

...
//adding the cells to table
for (int i = 0; i < 10; i++) {
    addRow(table,i);
}
...
//addRow implementation
private void addRow(Table table, int row) throws IOException {
    table.startNewRow();

    PdfFont zapfdingbats = PdfFontFactory.createFont(FontConstants.ZAPFDINGBATS);

    Cell checkBoxCell = new Cell().add(new Paragraph("o").setFont(zapfdingbats).setMargins(9, 0, 0, 11)).setKeepTogether(true);
    checkBoxCell.setNextRenderer(new CheckboxCellRenderer(checkBoxCell, "cb"+row));
    table.addCell(checkBoxCell);
    ...
    //other cells here
}
...
//The implementation of the custom CellRender
protected class CheckboxCellRenderer extends CellRenderer {
    protected String name;

    public CheckboxCellRenderer(Cell modelElement, String name) {
        super(modelElement);
        this.name = name;
    }
    //this method is not triggered for the first row when a new page is created
    @Override
    public void draw(DrawContext drawContext) {
        System.out.println(name);
        super.draw(drawContext);
        float x = getOccupiedAreaBBox().getLeft();
        float y = getOccupiedAreaBBox().getBottom();
        float width = getOccupiedAreaBBox().getRight()-getOccupiedAreaBBox().getLeft();
        float height = getOccupiedAreaBBox().getTop()-getOccupiedAreaBBox().getBottom();
        Rectangle rect = new Rectangle(x+5, y+5, width-10, height-10);
        PdfTextFormField pdfTextFormField = PdfFormField.createText(drawContext.getDocument(), rect, name);
        PdfAcroForm.getAcroForm(drawContext.getDocument(), true).addField(pdfTextFormField);
    }
}

我做错了什么?

最佳答案

您没有覆盖一个非常重要的方法:public IRenderer getNextRenderer()

如果单元格无法放置在页面上,iText 会创建一个溢出单元格(请参阅 protected AbstractRenderer createOverflowRenderer(int layoutResult) 方法。如果不覆盖 getNextRenderer iText默认情况下将使用其 getModelElement() 创建简单的 CellRenderer。

所以我建议你应该添加 summat: @覆盖 公共(public) IRenderer getNextRenderer() { 返回新的 CheckboxCellRenderer(getModelElement(),名称); }

我已经使用您的代码创建了下一个示例,它按您预期的那样工作。 `

public class ArrayToTable extends GenericTest {
public static final String DEST = "./target/test/resources/sandbox/tables/array_to_table.pdf";

public static void main(String[] args) throws Exception {
    File file = new File(DEST);
    file.getParentFile().mkdirs();
    new CustomRendererTest().manipulatePdf(DEST);
}

@Override
protected void manipulatePdf(String dest) throws Exception {
    PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
    Document doc = new Document(pdfDoc);

    Table table = new Table(1);
    //adding the cells to table
    for (int i = 0; i < 25; i++) {
        addRow(table, i);
    }

    doc.add(table);
    doc.close();
}

    //addRow implementation
    private void addRow(Table table, int row) throws IOException {
        table.startNewRow();

        PdfFont zapfdingbats = PdfFontFactory.createFont(FontConstants.ZAPFDINGBATS);

        Cell checkBoxCell = new Cell().add(new Paragraph("o").setFont(zapfdingbats).setMargins(9, 0, 0, 11)).setKeepTogether(true);
        checkBoxCell.setNextRenderer(new CheckboxCellRenderer(checkBoxCell, "cb"+row));
        table.addCell(checkBoxCell);
        //other cells here
    }

    //The implementation of the custom CellRender
    protected class CheckboxCellRenderer extends CellRenderer {
        protected String name;

        public CheckboxCellRenderer(Cell modelElement, String name) {
            super(modelElement);
            this.name = name;
        }
        //this method is not triggered for the first row when a new page is created
        @Override
        public void draw(DrawContext drawContext) {
            System.out.println(name);
            super.draw(drawContext);
            float x = getOccupiedAreaBBox().getLeft();
            float y = getOccupiedAreaBBox().getBottom();
            float width = getOccupiedAreaBBox().getRight()-getOccupiedAreaBBox().getLeft();
            float height = getOccupiedAreaBBox().getTop()-getOccupiedAreaBBox().getBottom();
            Rectangle rect = new Rectangle(x+5, y+5, width-10, height-10);
            PdfTextFormField pdfTextFormField = PdfFormField.createText(drawContext.getDocument(), rect, name);
            PdfAcroForm.getAcroForm(drawContext.getDocument(), true).addField(pdfTextFormField);
        }

        @Override
        public IRenderer getNextRenderer() {
            return new CheckboxCellRenderer(getModelElement(), name);
        }

    }

} `

关于java - Itext7 CellRenderer 并不总是有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45957620/

相关文章:

java - 无法让spring boot在gradle项目中自动创建数据库模式

java - 具有多个签名的 iText7 PDF

java - iText7可以用IVS(表意变化序列)显示字体吗?

macos - 在 Mac 上使用比较工具

java - CSS 背景属性在使用 java 的 pdfHTML iText7 中不起作用

java - 更改 PDF 文件中轮廓(书签)的缩放级别

java - Http 获取响应 utf-8

java - 获取URL中的图片

java - 如何使用 Jersey 的内部路由机制来提取类/方法引用?

java - 更新时 Recyclerview 移至底部