每个 iText 文档的多个渲染器:更新了更多细节
Multiple Renderers per iText document: Updated with more details
我正在使用 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 文件,但我认为这可能是我最终不得不做的。感谢您的帮助。
出现异常是因为默认情况下会尽快刷新页面内容以节省内存。
为了避免立即刷新内容,有一个 DocumentRenderer
和 ColumnDocumentRenderer
构造函数的参数。
因此,例如,要创建一个关闭立即刷新的 DocumentRenderer
,您必须按如下方式创建它:
DocumentRenderer defRender = new DocumentRenderer(document, false);
ColumnDocumentRenderer
非常相似。
接下来,由于您已关闭自动刷新并自行更改渲染器,因此在代码末尾 document.close();
之前,您必须手动刷新渲染器:
defRender.flush();
dictRender.flush();
现在内容出现了,但由于内容重叠,结果可能看起来很难看。这要由开发者来解决,因为两个渲染器是独立的实例,它们保持 currentArea
相互独立。要适当地处理此问题,您必须使用刚刚完成使用的前一个渲染器的 currentArea
更新要切换到的渲染器的 currentArea
。您可以通过扩展标准提供的渲染器或调用 renderer.getCurrentArea()
并修改 bBox
.
来做到这一点
我正在使用 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 文件,但我认为这可能是我最终不得不做的。感谢您的帮助。
出现异常是因为默认情况下会尽快刷新页面内容以节省内存。
为了避免立即刷新内容,有一个 DocumentRenderer
和 ColumnDocumentRenderer
构造函数的参数。
因此,例如,要创建一个关闭立即刷新的 DocumentRenderer
,您必须按如下方式创建它:
DocumentRenderer defRender = new DocumentRenderer(document, false);
ColumnDocumentRenderer
非常相似。
接下来,由于您已关闭自动刷新并自行更改渲染器,因此在代码末尾 document.close();
之前,您必须手动刷新渲染器:
defRender.flush();
dictRender.flush();
现在内容出现了,但由于内容重叠,结果可能看起来很难看。这要由开发者来解决,因为两个渲染器是独立的实例,它们保持 currentArea
相互独立。要适当地处理此问题,您必须使用刚刚完成使用的前一个渲染器的 currentArea
更新要切换到的渲染器的 currentArea
。您可以通过扩展标准提供的渲染器或调用 renderer.getCurrentArea()
并修改 bBox
.