首页 > 解决方案 > iText 7 pdhHtml 将表格行保持在一起

问题描述

我是 iText 7 的新手,我正在开发一个 spa 项目(asp.net、c# 和 angularjs),我需要为现有的 html 页面实现报告。我发现 iText 7(.Net)有一个简单的实现方法它。使用下面的代码行,这将返回一个字节数组,我可以轻松地在浏览器中显示为 pdf 也可以下载。

var memStream = new MemoryStream();
ConverterProperties converterProperties = new ConverterProperties();
converterProperties.SetFontProvider(fontProvider);              converterProperties.SetBaseUri(System.AppDomain.CurrentDomain.BaseDirectory);
HtmlConverter.ConvertToPdf(htmlText, memStream, converterProperties);

在我的原始 html 中有一些 html 表(每个表都有一些特定的行),我想将它们保留在一个页面中(我的意思是如果表行不适合单个页面,则从下一页开始)。我得到了如下解决方案

Paragraph p = new Paragraph("Test");
PdfPTable table = new PdfPTable(2);
for (int i = 1; i < 6; i++) {
    table.addCell("key " + i);
    table.addCell("value " + i);
}
for (int i = 0; i < 40; i++) {
    document.add(p);
}
// Try to keep the table on 1 page
table.setKeepTogether(true);
document.add(table);

但在我的情况下,我不能这样实现,因为内容已经存在于 html 表中(在我现有的 html 页面中)。

提前谢谢,如果有人可以帮助我。

标签: itext7

解决方案


这可以使用自定义TagWorkerFactoryTableTagWorker类轻松完成。看看下面的代码示例。

我们应该做的第一件事是创建一个自定义 TableTagWorker,它告诉 iText 将表格保持在一起。我们使用您提到的代码执行此操作:table.setKeepTogether(true)

class CustomTableTagWorker extends TableTagWorker{

    public CustomTableTagWorker(IElementNode element, ProcessorContext context) {
        super(element, context);
    }

    @Override
    public void processEnd(IElementNode element, ProcessorContext context) {
        super.processEnd(element, context);
        ((com.itextpdf.layout.element.Table) getElementResult()).setKeepTogether(true);
    }
}

如您所见,我们对自定义 TableTagWorker 所做的唯一更改是它必须将表格保持在一起。

下一步是创建一个自定义TagWorkerFactory,将我们的CustomTableTagWorker映射到 HTML 中的表格标签。我们这样做:

class CustomTagWorkerFactory extends DefaultTagWorkerFactory{
    @Override
    public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) {
        if (tag.name().equalsIgnoreCase("table")) {
            return new CustomTableTagWorker(tag, context); // implements ITagWorker
        }
        return super.getCustomTagWorker(tag, context);
    }
}

我们在这里所做的只是告诉 iText,如果它找到一个表格标签,它应该将该元素传递给CustomTableTagWorker,以便转换为 PDF 对象(其中 setKeepTogether == true)。

最后一步是在我们的ConverterProperties上注册这个CustomTagWorkerFactory

ConverterProperties converterProperties = new ConverterProperties();
converterProperties.setTagWorkerFactory(new CustomTagWorkerFactory());
HtmlConverter.convertToPdf(HTML, new FileOutputStream(DEST), converterProperties);

使用这些代码示例,我能够生成一个输出 PDF,其中的表格(如果小到可以在整个页面上呈现)永远不会被拆分为多个页面。


推荐阅读