【问题标题】:Multiple Renderers per iText document: Updated with more details每个 iText 文档的多个渲染器:更新了更多详细信息
【发布时间】:2016-08-09 15:07:31
【问题描述】:

我正在使用 iText7 创建一个包含多个部分的文档。有些部分要正常格式化,但有些要格式化为列。我可以通过使用 ColumnDocumentRenderer 对象将其正确格式化为列,但是当我这样做时,整个文档被设置为使用列。有没有办法让 iText 即时交换要使用的渲染器?

当我尝试动态更换渲染器时,我得到一个空指针异常 (com.itextpdf.kernel.pdf.PdfDictionary.get(PdfDictionary.java:482))。

PdfDocument pdf = new PdfDocument(new PdfWriter(targetFile));
Document document = new Document(pdf);
DocumentRenderer defRender = new DocumentRenderer(document);
document.setRenderer(defRender);
ColumnDocumentRenderer dictRender = getColumnRender();

while (<CONDITION>) {
    document.setRenderer(dictRender);
    document.add(new Paragraph("THIS IS NORMAL TEXT"));
    document.add(new Paragraph("THIS IS NORMAL TEXT"));
    document.add(new Paragraph("THIS IS NORMAL TEXT"));
    <...> 
    document.setRenderer(defRender);
    document.add(new Paragraph("THIS IS COLUMN TEXT"));
    document.add(new Paragraph("THIS IS COLUMN TEXT"));
    document.add(new Paragraph("THIS IS COLUMN TEXT"));
    <...>
}

在我将渲染器设置为 dictRender 后,第一个 document.add() 语句在 com.itextpdf.kernel.pdf.PdfDictionary.get(PdfDictionary.java:482) 处引发空指针错误。

我不想创建多个不同的 PDF 文件,但我想这可能是我最终不得不做的事情。感谢您的帮助。

【问题讨论】:

  • 当我尝试动态更换渲染器时 - 你如何尝试?如果您展示,可能有人可以改进您的解决方案。
  • 更新了一个特定的代码示例。如果你能看看这个,让我知道你有什么特别的地方,我会非常感激的! ^^
  • 在循环中你总是设置dictRender。你是这个意思吗?
  • Ack,这是我在复制代码时简化代码的结果。我正在更改代码中的渲染器,并且示例已更新以反映这一点。
  • 好的。当您切换渲染器时,您的期望是什么?新渲染器可以在新页面上启动,还是您希望剩余的当前页面由新渲染器填充?

标签: java itext itext7


【解决方案1】:

出现异常是因为默认情况下会尽快刷新页面内容以节省内存。

为避免立即刷新内容,有DocumentRendererColumnDocumentRenderer 构造函数的参数。

因此,例如,要创建一个关闭立即刷新的DocumentRenderer,您必须按如下方式创建它:

DocumentRenderer defRender = new DocumentRenderer(document, false);

ColumnDocumentRenderer 非常相似。

接下来,由于您已关闭自动刷新并自行更改渲染器,因此在代码末尾,就在 document.close(); 之前,您必须手动刷新渲染器:

defRender.flush();
dictRender.flush();

现在内容出现了,但由于内容重叠,结果仍然可能看起来很难看。这要由开发人员来解决,因为两个渲染器是独立的实例,它们彼此独立地维护currentArea。要正确处理此问题,您必须使用刚刚完成的前一个渲染器的 currentArea 更新要切换到的渲染器的 currentArea。您可以通过扩展标准提供的渲染器,或调用 renderer.getCurrentArea() 并修改 bBox 来做到这一点。

【讨论】:

  • 感谢您的建议!我会尽快实施并确认答案。如果此处的标准 iText 模式不包含文档,那么我只需要自己整理一下如何同步文档的长度即可。
  • 我已经更新了iText 7: building blocks 教程。查看chapter 2 并查找标题在不同渲染器之间切换 或查看JekyllHydeV6 示例。
猜你喜欢
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-26
相关资源
最近更新 更多