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 righ
I have taken this code: C02E08_JekyllHydeV4
And I updated it according to what you have in your question:
//Initialize PDF document
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
// Initialize document
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));
//Set column parameters
...
//Define column areas
...
document.setRenderer(new ColumnDocumentRenderer(document, columns));
document.add(new AreaBreak(AreaBreakType.LAST_PAGE));
// Add the full Jekyl and Hyde text
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);
//Close document
document.close();
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 {
float y;
public MyParagraphRenderer(Paragraph modelElement) {
super(modelElement);
}
@Override
public void drawBorder(DrawContext drawContext) {
super.drawBorder(drawContext);
y = getOccupiedAreaBBox().getBottom();
}
public float getY() {
return y;
}
}
When we add the first paragraph, we need to use this custom ParagraphRenderer
:
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.");
MyParagraphRenderer renderer = new MyParagraphRenderer(p);
p.setNextRenderer(renderer);
document.add(p);
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:
float offSet = 36;
float gutter = 23;
float columnWidth = (PageSize.A4.getWidth() - offSet * 2) / 2 - gutter;
float columnHeight1 = renderer.getY() - offSet * 2;
Rectangle[] columns1 = {
new Rectangle(offSet, offSet, columnWidth, columnHeight1),
new Rectangle(offSet + columnWidth + gutter, offSet, columnWidth, columnHeight1)};
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 custom ColumnDocumentRenderer
:
class MyColumnDocumentRenderer extends ColumnDocumentRenderer {
Rectangle[] columns2;
public MyColumnDocumentRenderer(Document document, Rectangle[] columns1, Rectangle[] columns2) {
super(document, columns1);
this.columns2 = columns2;
}
@Override
protected PageSize addNewPage(PageSize customPageSize) {
PageSize size = super.addNewPage(customPageSize);
columns = columns2;
return size;
}
}
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 custom ColumnDocumentRenderer
:
float columnHeight2 = PageSize.A4.getHeight() - offSet * 2;
Rectangle[] columns2 = {
new Rectangle(offSet, offSet, columnWidth, columnHeight2),
new Rectangle(offSet + columnWidth + gutter, offSet, columnWidth, columnHeight2)};
document.setRenderer(new MyColumnDocumentRenderer(document, columns1, columns2));
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
.