问题
How can I split a given paragraph to 2 paragraphs, due to that it fits only partial into canvas. After split, I would like to add the first part into canvas and the second to a new canvas.
public Paragraph addParagraphToPage(PdfDocument pdfDocument, int pageNum, Rectangle rectangle, Paragraph p)
{
PdfPage page = pdfDocument.getPage(pageNum);
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDocument);
Canvas canvas = new Canvas(pdfCanvas, pdfDocument, rectangle);
ParagraphRenderer currentRenderer = (ParagraphRenderer) p.createRendererSubTree();
currentRenderer.setParent(canvas.getRenderer());
result = currentRenderer.layout(new LayoutContext(new LayoutArea(pageNum, rectangle)));
ArrayList<Paragraph> paragraphs = new ArrayList<Paragraph>();
if (result.getStatus() != LayoutResult.FULL)
{
paragraphs = ????? // getNextParagraph(paragraphs, result, pageNum, rectangle, canvas);
if(paragraphs.size() == 2)
{
canvas.add( paragraphs.get(0));
return paragraphs.get(1);
}
}
return null;
}
回答1:
Your approach is correct in general and layout in iText7 is flexible enough to allow you to do required thing in an easy manner. The only thing I see that is not very clear is that Paragraph
is actually an element that cannot split itself and no classes in layout framework facilitate element splitting. You could do it manually, but there is no need to. Instead you should work with IRenderer
, and ParagraphRenderer
in particular, directly.
IRenderer
can split itself as a result of layout
operation and represents the necessary portion of data only compared to the Paragraph
which contains full data.
You can add an IRenderer
to the CanvasRenderer
:
canvas.getRenderer().addChild(rendererToAdd.setParent(canvas.getRenderer()));
And you can access the partial renderers (the portion that fit the passed area and overflow part) from LayoutResult#getSplitRenderer()
and LayoutResult#getOverflowRenderer()
.
In general, your code can be adapted like follows:
public ParagraphRenderer addParagraphToPage(PdfDocument pdfDocument, int pageNum, Rectangle rectangle, ParagraphRenderer renderer) {
PdfPage page = pdfDocument.getPage(pageNum);
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDocument);
Canvas canvas = new Canvas(pdfCanvas, pdfDocument, rectangle);
renderer.setParent(canvas.getRenderer());
LayoutResult result = renderer.layout(new LayoutContext(new LayoutArea(pageNum, rectangle)));
IRenderer rendererToAdd = result.getStatus() == LayoutResult.FULL ? renderer : result.getSplitRenderer();
canvas.getRenderer().addChild(rendererToAdd.setParent(canvas.getRenderer()));
return result.getStatus() != LayoutResult.FULL ? (ParagraphRenderer) result.getOverflowRenderer() : null;
}
And then for adding paragraph to sequential pages until all the content is placed you basically need only two lines of code:
ParagraphRenderer renderer = (ParagraphRenderer) p.createRendererSubTree();
while ((renderer = addParagraphToPage(pdfDocument, pageNum++, rectangle, renderer)) != null);
来源:https://stackoverflow.com/questions/46895474/itext-7-split-paragraph