Как переключать разные средства визуализации документов iText на одной странице - PullRequest
0 голосов
/ 17 июня 2020

Дело в том, что в начале страницы элементы должны быть нарисованы в одном столбце, а после этого элементы на той же странице должны быть нарисованы в двух столбцах.

Пока что, согласно iText например « c02e10_jekyllhydev6 », я просто могу переключать разные средства визуализации между страницами, что означает сначала применение DocumentRenderer, затем добавление AreaBreak of Next Page и применение ColumnDocumentRenderer на новой странице.

Here is the created PDF:

Код:

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);
**doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));**


PageSize ps = PageSize.A4;
var effectiveArea = doc.GetPageEffectiveArea(PageSize.A4);
float columnHeight = effectiveArea.GetHeight();
//Define column areas
Rectangle[] columns = new Rectangle[] {
    new Rectangle(36, 36, 200, columnHeight),
    new Rectangle(36 + 200 + 20, 36, effectiveArea.GetWidth()- 200 - 20, columnHeight)
};

ColumnDocumentRenderer renderer1 = new ColumnDocumentRenderer(doc, new Rectangle[] { columns[0] });
doc.SetRenderer(renderer1);
**doc.Add(new AreaBreak(AreaBreakType.LAST_PAGE));**
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);

ColumnDocumentRenderer renderer2 = new ColumnDocumentRenderer(doc, new Rectangle[] { columns[1] });
doc.SetRenderer(renderer2);
Paragraph p2 = new Paragraph();
for (int i = 1; i <= 1000; i++)
{
    p2.Add(new Text(i + " "));
}
doc.Add(p2);

doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
DocumentRenderer renderer3 = new DocumentRenderer(doc);
doc.SetRenderer(renderer3);
doc.Add(new AreaBreak(AreaBreakType.LAST_PAGE));
Paragraph p3 = new Paragraph();
for (int i = 1; i <= 1000; i++)
{
    p3.Add(new Text(i + " "));
}
doc.Add(p3);

doc.Close();

Если в документ не добавлен AreaBreak, содержимое с разными модулями визуализации будет перекрываться.

Из комментария Алексея в this case , кажется возможным, что переключение разных рендереров на одной странице без перекрытия контента.

Чтобы справиться с этим соответствующим образом, вам нужно будет обновить currentArea из рендерер, на который вы собираетесь переключиться с currentArea предыдущего рендерера, с которым вы только что закончили работать. Вы можете сделать это, расширив стандартные предоставленные средства визуализации или вызвав renderer.getCurrentArea () и изменив bBox.

Но я не знаю, как этого добиться в соответствии с приведенными выше руководствами.

1 Ответ

0 голосов
/ 18 июня 2020

В вашем случае нет необходимости в ColumnDocumentRenderer - этот рендерер был создан для случаев, когда вы хотите разместить свой контент в столбцах в пределах одной страницы, а затем перейти к следующей странице и c. В вашем случае вы размещаете контент в столбцах, охватывающих множество страниц, и это эквивалентно простой установке правильных полей для DocumentRenderer вместо передачи столбцов в ColumnDocumentRenderer.

Для переключения рекламы рендереров -ho c вам действительно нужно настроить их поле currentArea и currentPageNumber. Обратите внимание, что приведенное ниже решение не гарантирует работу во всех сложных случаях и во всех версиях iText. Это просто руководство о том, как реализовать то, что вам нужно, а не полное решение для всех случаев.

Нужный нам вспомогательный класс рендеринга очень прост - он позволяет настроить текущую область: 1012 * Теперь я адаптировал ваш код, чтобы избавиться от ColumnDocumentRenderer и использовать вместо него обычный DocumentRenderer. Вам просто нужно настроить поля документа и правильно пересчитать текущую область (пространство, которое осталось на странице):

Document doc = new Document(pdfDocument);


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);
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)
            .SetWidth(endOfFullWidthContentArea.GetBBox().GetWidth() - 200)));
doc.SetRightMargin(36);
doc.SetLeftMargin(200 + 36);
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();

Результат выглядит следующим образом:

result

...