Itext 7 Split Paragraph

萝らか妹 提交于 2021-02-08 10:16:29

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!