java - 使用 iText 的页脚中的动态高度大小

标签 java itext

我在报告页脚中使用了一个 HTML 代码。但是,此页脚的高度可能会根据我的 HTML 代码的内容而有所不同。是否可以根据代码的大小自动调整页脚的高度?

页脚.java

public class Footer extends PdfPageEventHelper {
    protected ElementList footer;
    public Footer(String html) throws IOException {
        footer = XMLWorkerHelper.parseToElementList(html, null);
    }
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        try {
            ColumnText ct = new ColumnText(writer.getDirectContent());

            // In my case this rectagle is resizeable height
            ct.setSimpleColumn(new Rectangle(36, 200, 559, 32));

            for (Element e : footer) {
                ct.addElement(e);
            }
            ct.go();
        } catch (DocumentException de) {
            throw new ExceptionConverter(de);
        }
    }
}

最佳答案

您的页脚似乎没有任何动态部分,因页面而异。在这种情况下,您可以简单地开始将该 html 呈现为一些一次性 PDF 并测量其尺寸,然后使用这些尺寸来设置您创建的实际文档的边距。

您可以实现这种方法,例如使用这样的页面事件监听器类:

public static class Footer extends PdfPageEventHelper {
    private final Rectangle boundingBox;
    private final List<Element> elements;
    private PdfTemplate template = null;
    private float blankAfter = 0;

    public Footer(String html, float width) throws DocumentException, IOException {
        this(XMLWorkerHelper.parseToElementList(html, null), width);
    }

    public Footer(List<Element> elements, float width) throws DocumentException, IOException {
        this.elements = elements;
        try (   OutputStream os = new NullOutputStream()    ) {
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, os);
            document.open();

            Rectangle bbox = new Rectangle(0, 0, width, 1000);
            float bottomLine = createTemplate(writer, bbox);
            boundingBox = new Rectangle(width, bbox.getTop() - bottomLine);
            template = null;

            writer.setPageEmpty(false);
            document.close();
        }
    }

    float createTemplate(PdfWriter writer, Rectangle boundingBox) throws DocumentException {
        template = writer.getDirectContent().createTemplate(10000, 10000);
        template.setBoundingBox(boundingBox);
        ColumnText columnText = new ColumnText(template);
        Rectangle bbox = template.getBoundingBox();
        columnText.setSimpleColumn(bbox.getLeft(), bbox.getBottom(), bbox.getRight(), bbox.getTop());
        for (Element element : elements) {
            columnText.addElement(element);
        }
        columnText.go();
        return columnText.getYLine() + columnText.getDescender();
    }

    void ensureTemplate(PdfWriter writer) throws DocumentException {
        if (template == null) {
            createTemplate(writer, boundingBox);
        }
    }

    public void setBottomMargin(Document document, float blankBefore, float blankAfter) {
        float marginBottom = boundingBox.getHeight() + blankBefore + blankAfter;
        document.setMargins(document.leftMargin(), document.rightMargin(), document.topMargin(), marginBottom);
        this.blankAfter = blankAfter;
    }

    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        try {
            ensureTemplate(writer);

            Rectangle bbox = template.getBoundingBox();
            Rectangle pageSize = document.getPageSize();

            float x = pageSize.getLeft((pageSize.getWidth() - bbox.getWidth()) / 2f - bbox.getLeft());
            float y = pageSize.getBottom(blankAfter - bbox.getBottom());
            writer.getDirectContentUnder().addTemplate(template, x, y);
        } catch (DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        super.onEndPage(writer, document);
    }
}

( StaticFooter 辅助类)

你这样应用它:

Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(new File(RESULT_FOLDER, "StaticFooterShort.pdf")));

String html = "<p>Short Test Footer.</p>";
Footer footer = new Footer(html, document.right() - document.left());
writer.setPageEvent(footer);
footer.setBottomMargin(document, 10, 10);

document.open();

for (int i = 0; i < 200; i++) {
    document.add(new Paragraph("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, ..."));
}

document.close();

( StaticFooter 测试 testShortFooter)


PS:我使用的 NullOutputStream 类是一个 Apache Commons IO 帮助程序,但如果您不想要额外的依赖,您可以轻松地实现类似的东西,只需实现一个 OutputStream 忽略所有输入。

关于java - 使用 iText 的页脚中的动态高度大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55735723/

相关文章:

java - 更改由 "Key Owner Name"进行数字签名

java - 如何在iText pdf中知道pdf的剩余空间

iTextSharp PdfStamper.PartialFormFlattening 仅展平部分而非全部字段

java - 如何在 Java 类应用程序中添加另存为对话框

java - 具有 spring 框架支持的 cms

java - android 添加 java.lang.management API

java - 通过 REST 的 Spring JPA

java - Ogg格式的录音?

java - GridBagLayout 动态使用面板内的额外空间

java - iText7 使用 Java 进行缩进列表格式化