我正在使用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文件,但是我想这可能就是我最终要做的事情。感谢您的帮助。

最佳答案

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

为了避免立即清除内容,有一个DocumentRendererColumnDocumentRenderer构造函数的参数。

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

DocumentRenderer defRender = new DocumentRenderer(document, false);


ColumnDocumentRenderer非常相似。

接下来,由于您自己关闭了自动刷新并更改了渲染器,因此在代码的最后,在document.close();之前,您将必须手动刷新渲染器:

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


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

关于java - 每个iText文档有多个渲染器:更新了更多详细信息,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38854402/

10-13 00:03