Согласно ответу Алексея this case , мы можем использовать различные средства визуализации с настроенным RootLayoutArea для достижения такого поведения макета, как показано ниже.
Индивидуальный макет документа
Вот код:
public void ManipulatePdf(String dest)
{
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc, PageSize.A4);
doc.SetMargins(36, 36, 36, 36);
Paragraph p = new Paragraph();
p.SetBorder(new SolidBorder(0.5f));
for (int i = 1; i <= 500; i++)
{
p.Add(new Text(i + " "));
}
doc.Add(p);
RootLayoutArea endOfFullWidthContentArea = (RootLayoutArea)doc.GetRenderer().GetCurrentArea();
ExtendedDocumentRenderer renderer1 = new ExtendedDocumentRenderer(doc,
new RootLayoutArea(endOfFullWidthContentArea.GetPageNumber(), endOfFullWidthContentArea.GetBBox().Clone().SetWidth(200)));
doc.SetRightMargin(doc.GetRightMargin() + doc.GetPageEffectiveArea(PageSize.A4).GetWidth() - 200);
doc.SetRenderer(renderer1);
//The paragraph drawn in the left
Paragraph p1 = new Paragraph();
p1.SetBorder(new SolidBorder(0.5f));
for (int i = 1; i <= 500; i++)
{
p1.Add(new Text(i + " "));
}
doc.Add(p1);
ExtendedDocumentRenderer renderer2 = new ExtendedDocumentRenderer(doc,
new RootLayoutArea(endOfFullWidthContentArea.GetPageNumber(),
endOfFullWidthContentArea.GetBBox().Clone().MoveRight(200 + 20)
.SetWidth(endOfFullWidthContentArea.GetBBox().GetWidth() - 200 - 20)));
doc.SetRightMargin(36);
doc.SetLeftMargin(200 + 36 + 20);
doc.SetRenderer(renderer2);
Paragraph p2 = new Paragraph();
for (int i = 1; i <= 1000; i++)
{
p2.Add(new Text(i + " "));
}
doc.Add(p2);
//Compute which free area is lower in the document
RootLayoutArea areaColumn1 = (RootLayoutArea)renderer1.GetCurrentArea();
RootLayoutArea areaColumn2 = (RootLayoutArea)renderer2.GetCurrentArea();
RootLayoutArea downArea =
areaColumn1.GetPageNumber() > areaColumn2.GetPageNumber() ? areaColumn1 :
(areaColumn1.GetPageNumber() < areaColumn2.GetPageNumber() ? areaColumn2 :
(areaColumn1.GetBBox().GetTop() < areaColumn2.GetBBox().GetTop() ? areaColumn1 : areaColumn2));
doc.SetMargins(36, 36, 36, 36);
DocumentRenderer renderer3 = new ExtendedDocumentRenderer(doc,
new RootLayoutArea(downArea.GetPageNumber(), downArea.GetBBox().Clone().SetX(36).SetWidth(doc.GetPageEffectiveArea(PageSize.A4).GetWidth())));
doc.SetRenderer(renderer3);
Paragraph p3 = new Paragraph();
for (int i = 1; i <= 1000; i++)
{
p3.Add(new Text(i + " "));
}
doc.Add(p3);
doc.Close();
}
private class ExtendedDocumentRenderer : DocumentRenderer
{
public ExtendedDocumentRenderer(Document document, RootLayoutArea currentArea) : base(document)
{
this.currentArea = new RootLayoutArea(currentArea.GetPageNumber(), currentArea.GetBBox().Clone());
this.currentPageNumber = this.currentArea.GetPageNumber();
}
}
Мы видим, что абзац 1 в левом столбце занимает две страницы, а абзац 2 - три страницы, в этом сценарии код работает хорошо .
Но если мы добавим больше содержимого в абзац 1 и сделаем его охватывающим 3 страницы, как показано ниже:
//The paragraph drawn in the left has more contents
Paragraph p1 = new Paragraph();
p1.SetBorder(new SolidBorder(0.5f));
for (int i = 1; i <= 800; i++)
{
p1.Add(new Text(i + " "));
}
doc.Add(p1);
Когда абзац 2 отрисовывается, он выдает исключение «Невозможно нарисовать элементы. на уже промытых страницах ». Как решить эту проблему? Спасибо!