I was testing few things with iText7 and I have a scenario where I need to have DocumentRenderer paragraph at the top and then start the ColumnDocumentRender with 2 columns right below it on the same page. The problem I am having is when I change the content on same page it overlaps content from DocumentRenderer with content from ColumnDocumentRenderer. I believe it is because one render does not know about the other render and contents starts from the top of the page. I followed this tutorial but it only shows how to add content to the next page. It does say
we'll have to instruct iText not to flush the content to the OutputStream
But can anyone show me exactly how we can achieve this?
public void createPdf(String dest) throws IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
Paragraph p = new Paragraph()
.add("Be prepared to read a story about a London lawyer "
+ "named Gabriel John Utterson who investigates strange "
+ "occurrences between his old friend, Dr. Henry Jekyll, "
+ "and the evil Edward Hyde.");
document.add(p);
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
... // Define column areas
document.setRenderer(new ColumnDocumentRenderer(document, columns));
document.add(new AreaBreak(AreaBreakType.LAST_PAGE));
... // Add novel in two columns
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
document.setRenderer(new DocumentRenderer(document));
document.add(new AreaBreak(AreaBreakType.LAST_PAGE));
p = new Paragraph()
.add("This was the story about the London lawyer "
+ "named Gabriel John Utterson who investigates strange "
+ "occurrences between his old friend, Dr. Henry Jekyll, "
+ "and the evil Edward Hyde. THE END!");
document.add(p);
document.close();
}
I need something like this:
Whenever you create a new DocumentRenderer, iText starts returns to the top of the document –that is: from the first page. This allows you to use different renderers on the same document next to each other on the same page. If that is needed, we'll have to instruct iText not to flush the content to the OutputStream; otherwise we won't have access to previous pages. In this case, we don't need to change anything on previous pages. We just want to switch to another renderer on the next page. Introducing a page break that goes to the last page will avoid that new content overwrites old content.
I have taken this code: C02E08_JekyllHydeV4
And I updated it according to what you have in your question:
The result looks like this:
I think that's the behavior you are looking for. If it's not, please explain what goes wrong.
UPDATE:
After clarifying the question, it is clear that the above answer doesn't solve the problem. This is the solution to the actual problem:
We need to create a custom
ParagraphRenderer
to determine a Y-position: class MyParagraphRenderer extends ParagraphRenderer {When we add the first paragraph, we need to use this custom
ParagraphRenderer
:We can now get the Y position we need like this:
renderer.getY()
; we use this Y position to define a first set of columns:We could use this set of columns to create a
ColumnDocumentRenderer
, but if more than one page is needed to render all the content, then the offset of the columns on the second page will be wrong, hence we also create a customColumnDocumentRenderer
:This
ColumnDocumentRenderer
accepts two sets of columns, one set will be used on the first page, the second set will be used on all subsequent pages. This is how we define and apply the customColumnDocumentRenderer
:Now the result looks like this:
Depending on the distance you want between the first page-wide paragraph and the subsequent content in the columns, you can adjust the value of
renderer.getY() - offSet * 2
.