英文:
How to render two tables simultaneously (tables are having content more than single page) using iText7
问题
我需要在两个并行的列上从第一页开始添加两个表格,而且两个表格的内容都超过一页。Table1在页面的左半部分运行,Table2在右半部分运行。我已经开始渲染表格1,但它溢出了。现在在继续下一页之前,我想要开始渲染表格2(添加新页会使前一页不可访问)。
在iText5中,使用ColumnText.hasMoreText(status)来检查表格溢出的情况来实现这个。但在iText7中,这种方法是不同的。以下是我在iText7中尝试解决问题的示例代码:
public void createPdf(String dest) throws FileNotFoundException {
// ... (略去了之前的代码)
Table table1 = new Table(2);
Table table2 = new Table(2);
// ... (略去了之前的代码)
drawTables(pdfDoc, document, new Table[] {table1, table2}, columnsEven);
document.close();
}
public void drawTables(PdfDocument pdfDoc, Document document, Table[] tables , Rectangle[] rects) {
// for table 1
DocumentRenderer renderer1 = new MyColumnDocumentRenderer(document, new Rectangle[] {rects[0]});
document.add(table1);
// for table 2
DocumentRenderer renderer2 = new MyColumnDocumentRenderer(document, new Rectangle[] {rects[1]});
document.add(table2);
}
public class MyColumnDocumentRenderer extends DocumentRenderer {
protected Rectangle column;
public MyColumnDocumentRenderer(Document document, Rectangle[] column) {
super(document);
this.column = column[0];
}
@Override
protected LayoutArea updateCurrentArea(LayoutResult overflowResult) {
if (overflowResult != null && overflowResult.getStatus() == LayoutResult.PARTIAL) {
column = new Rectangle(300, 100, 200, 600);
}
super.updateCurrentArea(overflowResult);
return (currentArea = new RootLayoutArea(currentPageNumber, column.clone()));
}
}
我正在将iText5迁移到iText7。你能否建议我最佳的方法来实现所述的问题?
对于你的后续问题:
-
是的,可以同时处理
document.add(table1)
和document.add(table2)
,但是在默认情况下,文档渲染器将会逐个处理添加的元素。如果你想要并行处理这两个表格,你可能需要自定义文档渲染器的行为。 -
在iText7中,文档渲染器是与每个表格的内容无关的。你可以创建不同的文档渲染器实例来处理不同的表格,但是在每个文档渲染器中,你需要确保正确地管理当前的页面、列和区域等状态。
请注意,由于我只能提供文本回复,而不能执行代码,因此如果需要更详细的帮助和调试,你可能需要参考iText7的文档或者向iText官方寻求支持。
英文:
I need to add 2 tables on 2 parallel columns starting from page 1, and both tables have content more than a single page. Table1 runs on left half of page and table2 runs on right half. I started rendering table 1 and it overflows. Now before proceeding to next page, I want to start rendering table 2 (adding new page makes previous page inaccessible).
The implementation of this in iText5 was done using CoulmnText. In iText5, I used 'ColumnText.hasMoreText(status)' to check the overflowing nature of table.
But in iText7 this approach is different. This is the sample code in iText7 which i tried to solve the problem stated.
public void createPdf(String dest) throws FileNotFoundException {
Rectangle[] columnsEven = {new Rectangle(200, 100, 100, 500), new Rectangle(500, 100, 100, 500)};
PdfWriter writer =new PdfWriter(DEST);
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
Table table1 = new Table(2);
Table table2 = new Table(2);
String cellContent1="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam metus elit, ornare et justo nec, ornare dignissim leo. Praesent in egestas erat. Donec id nunc libero. Nullam aliquam sodales sollicitudin. Proin ac egestas nunc. Nunc et suscipit augue. Curabitur porta tempor nunc vel suscipit. Suspendisse imperdiet nunc id quam aliquet fermentum. Pellentesque ut dolor non odio congue blandit. Morbi laoreet magna quam, quis suscipit nunc pulvinar et. Nullam sit amet semper odio, sagittis dictum erat.\n"+
"Curabitur sagittis arcu turpis, et tincidunt quam congue in. Nullam vitae felis id dui fringilla tincidunt. Nulla ullamcorper nisi non arcu fermentum, eu tempor lectus mattis. Aliquam leo purus, vulputate et ornare in, tincidunt sit amet mi. Sed sollicitudin et sapien vel hendrerit. Morbi id sodales sapien. In non nisl velit. Mauris maximus sodales lectus, ac dignissim elit cursus ac. Nulla viverra, velit sed cursus tincidunt, ex risus posuere diam, lobortis congue metus eros at lorem. Cras a ligula tortor. Vestibulum efficitur diam eros, eget dapibus magna cursus sed.\n"+
"Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam ut velit pretium diam vestibulum consectetur. Praesent dignissim id sapien eget ultrices. Nam non libero iaculis dolor mattis egestas et quis leo. Sed vitae libero a enim viverra finibus sit amet sed nulla. Sed vitae sem hendrerit, posuere justo sagittis, placerat justo. Aenean felis nisi, tincidunt faucibus sem at, egestas interdum nibh. Curabitur venenatis neque nec volutpat mollis. Phasellus vel tellus ut nisl consequat gravida. Maecenas eget ligula vestibulum, finibus turpis a, hendrerit est. Cras eleifend mollis commodo.\n"+
"Morbi quam velit, elementum nec turpis porttitor, venenatis sagittis nunc. Sed et nisi ipsum. Maecenas eget tellus in dui condimentum dictum a tempus sem. Maecenas consectetur nisl sit amet accumsan volutpat. Sed dictum massa vitae urna aliquam imperdiet. Nam at ex feugiat dolor vestibulum vehicula. Nullam leo magna, porta ac ex vitae, malesuada fermentum turpis. Donec vel turpis quis ligula feugiat molestie quis at nisi. Quisque efficitur velit odio, id rhoncus diam varius eu. Duis dui mi, scelerisque at faucibus ac, sodales sed est. Sed dictum aliquet semper.\n"+
"Sed erat ipsum, vehicula nec magna sed, aliquam volutpat lorem. Integer et auctor nisl, at auctor lorem. Nam bibendum urna nec quam cursus, vitae rhoncus justo semper. Morbi posuere dapibus quam vel euismod. Morbi id maximus augue, ut vulputate turpis. Cras posuere auctor justo, in ultricies nunc tincidunt id. Sed luctus nisl lacus, in facilisis erat ultricies id. Aliquam erat volutpat. Morbi accumsan lectus nec dolor ultricies dignissim. Sed quis finibus lectus.\n"+
"Pellentesque aliquet ex eget cursus accumsan. In ultrices tempus orci sed ultrices. Maecenas lectus nunc, consectetur ac suscipit et, tempus rutrum ipsum. Nulla accumsan tincidunt dignissim. Sed malesuada sapien elit, ac semper urna maximus at. Nunc eleifend tortor nec ligula auctor, sit amet sagittis turpis sagittis. Nam laoreet justo sed gravida iaculis. Fusce ornare quam quis arcu gravida rutrum. Aliquam vitae augue sit amet nisi finibus ullamcorper. Proin quis placerat velit. Integer malesuada erat nec massa tempus pretium.";
Cell cell = new Cell().add(new Paragraph("INDIA"));
table1.addCell(cell);
table2.addCell(cell);
cell = new Cell().add(new Paragraph(cellContent1));
table1.addCell(cell);
table2.addCell(cell);
drawTables(pdfDoc, document, new Table[] {table1, table2}, columnsEven);
document.close();
}
public void drawTables(PdfDocument pdfDoc, Document document, Table[] tables , Rectangle[] rects) {
// for table 1
DocumentRenderer renderer1= new MyColumnDocumentRenderer(document, new Rectangle[] {rects[0]});
document.add(table1);
// for table 2
DocumentRenderer renderer2= new MyColumnDocumentRenderer(document, new Rectangle[] {rects[1]});
document.add(table2);
}
public class MyColumnDocumentRenderer extends DocumentRenderer {
protected Rectangle column;
public MyColumnDocumentRenderer(Document document, Rectangle[] column) {
super(document);
this.column = column[0];
}
@Override
protected LayoutArea updateCurrentArea(LayoutResult overflowResult) {
if(overflowResult!=null && overflowResult.getStatus()== LayoutResult.PARTIAL) {
column = new Rectangle(300, 100, 200, 600);
}
super.updateCurrentArea(overflowResult);
return (currentArea = new RootLayoutArea(currentPageNumber, column.clone()));
}
I am migrating iText5 to iText7. Can you suggest me the best approach to implement the problem stated?
I need some help on the questions below as well.
Is it possible to process document.add(table1) and document.add(table2) simultaneously? Can we save state of document renderer for one table while we render other table?
答案1
得分: 1
你可以始终通过多次操作来实现此目标:以盖章模式打开文档(使用PdfReader
和PdfWriter
),添加所需内容,关闭文档,然后打开文档的新版本,添加更多内容,再次关闭文档,依此类推。
可用的现有实现不支持你需要的在多个页面上同时进行布局的情况。然而,整个布局框架足够灵活,所以如果你深入源代码,稍微修改现有实现,就可以实现你的情况。
我们将从ColumnDocumentRenderer
扩展,以便访问一些protected
字段,并添加返回渲染器第一页的可能性。请注意,为了使此解决方案起作用,我们需要将immediateFlush=false
传递给父类的构造函数,这会稍微增加内存占用。还请注意,此解决方案在某种程度上取决于实现细节,因此即使在补丁升级期间也可能停止工作。但这更多是一个理论可能性,请密切关注。
private static final class ResettingColumnDocumentRenderer extends ColumnDocumentRenderer {
public ResettingColumnDocumentRenderer(Document document, Rectangle[] columns) {
super(document, false, columns);
}
public void resetToFirstPage() {
currentArea = null;
currentPageNumber = 0;
nextAreaNumber = 0;
}
}
现在我们有了自定义的文档渲染器实现,我们可以将你的drawTables
方法概括为支持渲染 N 张表的情况:
public void drawTables(Document document, Table[] tables, Rectangle[] rects) {
for (int i = 0; i < tables.length; i++) {
ResettingColumnDocumentRenderer renderer = new ResettingColumnDocumentRenderer(document, new Rectangle[] {rects[i]});
document.setRenderer(renderer);
document.add(tables[i]);
renderer.resetToFirstPage();
renderer.flush();
}
}
最后,以下是外部调用代码,与你原始版本几乎没有修改:
public void createPdf() throws FileNotFoundException {
Rectangle[] columnsEven = {new Rectangle(70, 100, 200, 500), new Rectangle(350, 100, 200, 500)};
PdfWriter writer = new PdfWriter("C:/Users/Alexey/Desktop/23423423.pdf");
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
Table table1 = new Table(2);
Table table2 = new Table(2);
String cellContent1 = "Lorem ipsum dolor sit amet, ... (内容较长,省略)";
Cell cell = new Cell().add(new Paragraph("INDIA"));
table1.addCell(cell);
table2.addCell(cell);
cell = new Cell().add(new Paragraph(cellContent1));
table1.addCell(cell);
table2.addCell(cell);
drawTables(document, new Table[] {table1, table2}, columnsEven);
document.close();
}
以上内容为翻译结果,仅包括代码部分,不包含其他回答。
英文:
You can always do this in many passes: open the document in stamping mode (with PdfReader
and PdfWriter
), add the necessary content, close the document, then open the new version of the document, add more content, close the document and so on.
There implementations that are available out of the box do not support your case of simultaneous layouting of several objects across many pages. However, the whole layouting framework is flexible enough so if you dig into the source code a but you can extend from existing implementations and only modify them slightly to achieve your case.
We will extend from ColumnDocumentRenderer
to have access to some protected
fields and will add a possibility to go back to the first page in the renderer. Please note that in order for this solution to work we need to pass immediateFlush=false
to parent's constructor which will increase the memory footprint a bit.
Please also note that the solution depends on the implementation details a bit so it might stop working even during a patch upgrade. But this is more of a theoretical possibility, just keep an eye on it.
private static final class ResettingColumnDocumentRenderer extends ColumnDocumentRenderer {
public ResettingColumnDocumentRenderer(Document document, Rectangle[] columns) {
super(document, false, columns);
}
public void resetToFirstPage() {
currentArea = null;
currentPageNumber = 0;
nextAreaNumber = 0;
}
}
Now that we have a custom document renderer implementation we can generalize your drawTables
method to support case of rendering of N tables:
public void drawTables(Document document, Table[] tables , Rectangle[] rects) {
for (int i = 0; i < tables.length; i++) {
ResettingColumnDocumentRenderer renderer = new ResettingColumnDocumentRenderer(document, new Rectangle[] {rects[i]});
document.setRenderer(renderer);
document.add(tables[i]);
renderer.resetToFirstPage();
renderer.flush();
}
}
Finally, here is the outer calling code, with almost no modifications compared to your original version:
public void createPdf() throws FileNotFoundException {
Rectangle[] columnsEven = {new Rectangle(70, 100, 200, 500), new Rectangle(350, 100, 200, 500)};
PdfWriter writer =new PdfWriter("C:/Users/Alexey/Desktop/23423423.pdf");
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
Table table1 = new Table(2);
Table table2 = new Table(2);
String cellContent1="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam metus elit, ornare et justo nec, ornare dignissim leo. Praesent in egestas erat. Donec id nunc libero. Nullam aliquam sodales sollicitudin. Proin ac egestas nunc. Nunc et suscipit augue. Curabitur porta tempor nunc vel suscipit. Suspendisse imperdiet nunc id quam aliquet fermentum. Pellentesque ut dolor non odio congue blandit. Morbi laoreet magna quam, quis suscipit nunc pulvinar et. Nullam sit amet semper odio, sagittis dictum erat.\n"+
"Curabitur sagittis arcu turpis, et tincidunt quam congue in. Nullam vitae felis id dui fringilla tincidunt. Nulla ullamcorper nisi non arcu fermentum, eu tempor lectus mattis. Aliquam leo purus, vulputate et ornare in, tincidunt sit amet mi. Sed sollicitudin et sapien vel hendrerit. Morbi id sodales sapien. In non nisl velit. Mauris maximus sodales lectus, ac dignissim elit cursus ac. Nulla viverra, velit sed cursus tincidunt, ex risus posuere diam, lobortis congue metus eros at lorem. Cras a ligula tortor. Vestibulum efficitur diam eros, eget dapibus magna cursus sed.\n"+
"Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam ut velit pretium diam vestibulum consectetur. Praesent dignissim id sapien eget ultrices. Nam non libero iaculis dolor mattis egestas et quis leo. Sed vitae libero a enim viverra finibus sit amet sed nulla. Sed vitae sem hendrerit, posuere justo sagittis, placerat justo. Aenean felis nisi, tincidunt faucibus sem at, egestas interdum nibh. Curabitur venenatis neque nec volutpat mollis. Phasellus vel tellus ut nisl consequat gravida. Maecenas eget ligula vestibulum, finibus turpis a, hendrerit est. Cras eleifend mollis commodo.\n"+
"Morbi quam velit, elementum nec turpis porttitor, venenatis sagittis nunc. Sed et nisi ipsum. Maecenas eget tellus in dui condimentum dictum a tempus sem. Maecenas consectetur nisl sit amet accumsan volutpat. Sed dictum massa vitae urna aliquam imperdiet. Nam at ex feugiat dolor vestibulum vehicula. Nullam leo magna, porta ac ex vitae, malesuada fermentum turpis. Donec vel turpis quis ligula feugiat molestie quis at nisi. Quisque efficitur velit odio, id rhoncus diam varius eu. Duis dui mi, scelerisque at faucibus ac, sodales sed est. Sed dictum aliquet semper.\n"+
"Sed erat ipsum, vehicula nec magna sed, aliquam volutpat lorem. Integer et auctor nisl, at auctor lorem. Nam bibendum urna nec quam cursus, vitae rhoncus justo semper. Morbi posuere dapibus quam vel euismod. Morbi id maximus augue, ut vulputate turpis. Cras posuere auctor justo, in ultricies nunc tincidunt id. Sed luctus nisl lacus, in facilisis erat ultricies id. Aliquam erat volutpat. Morbi accumsan lectus nec dolor ultricies dignissim. Sed quis finibus lectus.\n"+
"Pellentesque aliquet ex eget cursus accumsan. In ultrices tempus orci sed ultrices. Maecenas lectus nunc, consectetur ac suscipit et, tempus rutrum ipsum. Nulla accumsan tincidunt dignissim. Sed malesuada sapien elit, ac semper urna maximus at. Nunc eleifend tortor nec ligula auctor, sit amet sagittis turpis sagittis. Nam laoreet justo sed gravida iaculis. Fusce ornare quam quis arcu gravida rutrum. Aliquam vitae augue sit amet nisi finibus ullamcorper. Proin quis placerat velit. Integer malesuada erat nec massa tempus pretium.";
Cell cell = new Cell().add(new Paragraph("INDIA"));
table1.addCell(cell);
table2.addCell(cell);
cell = new Cell().add(new Paragraph(cellContent1));
table1.addCell(cell);
table2.addCell(cell);
drawTables(document, new Table[] {table1, table2}, columnsEven);
document.close();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论