Java Itext 7在同一页上混合了全文和专栏布局

Java Itext 7在同一页上混合了全文和专栏布局,java,itext,itext7,Java,Itext,Itext7,我正在使用iText 7,并试图在同一页面上创建一个混合布局的文档 我需要在同一页上有完整的正文布局,然后是列布局,列可能会流到后续页面。然后,我需要返回到全文布局,后面是与全文部分在同一页面上开始的列,这些列可能会再次流向后续页面 但是,这似乎只适用于列从生成文档的第1页开始的情况。如果不是,则列的文本似乎要放在布局不正确的前几页上。我在这里试过这个例子: 不幸的是,它在我的场景中不起作用。以下是lorem ipsum测试的结果: 有人能帮忙吗 更新: 我正在接近一个解决方案。我已经更新了

我正在使用iText 7,并试图在同一页面上创建一个混合布局的文档

我需要在同一页上有完整的正文布局,然后是列布局,列可能会流到后续页面。然后,我需要返回到全文布局,后面是与全文部分在同一页面上开始的列,这些列可能会再次流向后续页面

但是,这似乎只适用于列从生成文档的第1页开始的情况。如果不是,则列的文本似乎要放在布局不正确的前几页上。我在这里试过这个例子:

不幸的是,它在我的场景中不起作用。以下是lorem ipsum测试的结果:

有人能帮忙吗

更新: 我正在接近一个解决方案。我已经更新了代码,列中的文本和牛体布局现在不再重叠。但是,在全文布局中,当在溢出到后续页面的段落之后开始在同一页面上呈现列时,该列布局部分中文本的起始部分将丢失。此外,呈现似乎在新页面上开始,而不是与先前呈现的段落相同的页面,该段落在全身布局中覆盖在后续页面上

我正在使用以下代码(3类):

package org.jsb.DocGen;
导入com.itextpdf.layout.element.paragration;
导入com.itextpdf.layout.renderer.DrawContext;
导入com.itextpdf.layout.renderer.IRenderer;
导入com.itextpdf.layout.renderer.ParagraphRenderer;
进口龙目吸气剂;
公共最终类CustomParagraphRenderer扩展了ParagraphRenderer{
私有@Getter float y=0.0f;
公共自定义段落呈现器(段落模型元素){
超级(模型元素);
}
@凌驾
公共空白绘图边框(DrawContext DrawContext){
super.drawBorder(drawContext);
this.y=getoccupiederabbox().getBottom();
}
@凌驾
公共iRenderGetNextrenderer(){
返回新的CustomParagraphRenderer((段落)modelElement);
}
}
包org.jsb.DocGen;
导入com.itextpdf.kernel.geom.PageSize;
导入com.itextpdf.kernel.geom.Rectangle;
导入com.itextpdf.layout.ColumnDocumentRenderer;
导入com.itextpdf.layout.Document;
公共类CustomColumnDocumentRenderer扩展了ColumnDocumentRenderer{
私有矩形[]列2=null;
公共CustomColumnDocumentRenderer(文档文档,矩形[]列1,矩形[]列2){
超级(文件,第1栏);
this.columns2=columns2;
}
@凌驾
受保护的PageSize addNewPage(PageSize customPageSize){
PageSize size=super.addNewPage(customPageSize);
super.columns=this.columns2;
返回大小;
}
}
包org.jsb.DocGen;
导入java.awt.Desktop;
导入java.io.File;
导入java.io.IOException;
导入org.junit.jupiter.api.Test;
导入com.itextpdf.kernel.geom.PageSize;
导入com.itextpdf.kernel.geom.Rectangle;
导入com.itextpdf.kernel.pdf.PdfDocument;
导入com.itextpdf.kernel.pdf.PdfWriter;
导入com.itextpdf.layout.Document;
导入com.itextpdf.layout.element.AreaBreak;
导入com.itextpdf.layout.element.paragration;
导入com.itextpdf.layout.property.AreaBreakType;
导入com.itextpdf.layout.renderer.DocumentRenderer;
导入lombok.extern.slf4j.slf4j;
@Slf4j
公开期末考试{
@试验
公共最终无效测试(){
单据=空;
String dest=String.format(“%s/Desktop/mixedrenders.pdf”,System.getProperty(“user.home”))。替换(“\\”,“/”)。替换(“//”,“/”;
文件文件=新文件(dest);
if(file.exists()){
delete();
}
试一试(
PdfWriter PdfWriter=新PdfWriter(目的地);
PdfDocument pdf=新PdfDocument(pdfWriter);
) {
字符串[]和={
“Lorem ipsum door sit amet,Adipiset Elite.Etiam interdum sollicitudin velit nec semper.Aliquam porta venenatis tortor,et viverra niss acumsan non.Sed euismod tincidut et portator.Duis lacinia efficity ur auctor.Quisque eros quam,maximus et sucipit quis quis,tempor frollia Lorem.Donec hendrerit hendrerit hendreit vehit.Integer在tincidunt.Fusce euismod sapien id iaculis efficitur.Suspendisse potenti.中的外泄酵素arcu。”,
“在调味品中,酒后酒、酒后酒、酒后酒、酒后酒、酒后酒、酒后酒、酒后酒、酒后酒、酒后酒、酒后酒、酒后酒。酒后酒、酒后酒、酒后酒、酒后酒、酒后酒康茂德·普鲁斯(commodo purus)。奎斯(Quisque Impertate Element um suscipit)。弗林蒂拉·多勒(Cras fringilla dolor)是一位修女,他在《正义》杂志上发表了自己的见解。他是一位修女,在《尼西》杂志上发表了自己的见解。修女在《伊普斯塔斯·波苏尔》杂志上发表了自己的见解sagittis sapien的Duis区域检察官。”,
“产于蒙特斯的天然肉牛品种,因其营养不良而死亡,因其营养不良而死亡的肉牛,因其营养不良而死亡的肉牛,因其营养不良而死亡的肉牛,因其营养不良而死亡的肉牛,因其营养不良而死亡的肉牛,因其营养不良而死亡的肉牛,因其营养不良而死亡的肉牛,因其营养不良而死亡我遇到了菲尼布斯、尼伯等人、奥奇里斯·奥奇斯、弗林利亚·厄洛斯、普洛斯·普洛斯·萨吉提斯、努克·维塔·鲁特鲁姆·波特提托、伊普苏姆自由主义者、非平等的智者、非平等的智者、无名氏、温文迪·拉库斯·维塔斯、威尼斯猫等。我是一个不属于图尔皮斯王朝的人在elit a的酒廊,在mauris的酒廊
package org.jsb.DocGen;

import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.layout.renderer.IRenderer;
import com.itextpdf.layout.renderer.ParagraphRenderer;

import lombok.Getter;

public final class CustomParagraphRenderer extends ParagraphRenderer {
    private @Getter float y = 0.0f;

    public CustomParagraphRenderer(Paragraph modelElement) {
        super(modelElement);
    }

    @Override
    public void drawBorder(DrawContext drawContext) {
        super.drawBorder(drawContext);
        this.y = getOccupiedAreaBBox().getBottom();
    }

    @Override
    public IRenderer getNextRenderer() {
        return new CustomParagraphRenderer((Paragraph) modelElement);
    }

}


package org.jsb.DocGen;

import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.layout.ColumnDocumentRenderer;
import com.itextpdf.layout.Document;

public class CustomColumnDocumentRenderer extends ColumnDocumentRenderer {

    private Rectangle [] columns2 = null;

    public CustomColumnDocumentRenderer(Document document, Rectangle [] columns1, Rectangle [] columns2) {
        super(document, columns1);
        this.columns2 = columns2;
    }

    @Override
    protected PageSize addNewPage(PageSize customPageSize) {
        PageSize size = super.addNewPage(customPageSize);
        super.columns = this.columns2;
        return size;
    }

}



package org.jsb.DocGen;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;

import org.junit.jupiter.api.Test;

import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.AreaBreakType;
import com.itextpdf.layout.renderer.DocumentRenderer;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public final class ColumnTest {

    @Test
    public final void test() {
        Document document = null;
        String dest = String.format("%s/Desktop/mixedrenderers.pdf", System.getProperty("user.home")).replace("\\", "/").replace("//", "/");
        File file = new File(dest);
        if(file.exists()) {
            file.delete();
        }
        try(
                PdfWriter pdfWriter = new PdfWriter(dest);
                PdfDocument pdf = new PdfDocument(pdfWriter);
        ) {
            String [] loremipsums = {
                "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam interdum sollicitudin velit nec semper. Aliquam porta venenatis tortor, et viverra nisl accumsan non. Sed euismod tincidunt ex et porttitor. Duis lacinia efficitur auctor. Quisque eros quam, maximus et suscipit quis, tempor fringilla lorem. Donec hendrerit hendrerit vehicula. Integer vulputate fermentum arcu in tincidunt. Fusce euismod sapien id iaculis efficitur. Suspendisse potenti.",
                "Proin condimentum lorem a enim cursus tincidunt. Proin dui ex, faucibus semper tincidunt vitae, lobortis ut urna. Nullam iaculis neque accumsan urna consectetur accumsan. Mauris quis est nunc. Pellentesque vitae urna congue, dignissim lacus quis, volutpat ipsum. Duis arcu neque, convallis et nunc aliquet, sollicitudin finibus sem. Donec malesuada commodo purus. Quisque imperdiet elementum suscipit. Cras fringilla dolor a nunc placerat porta. In id consequat justo, eget dictum mauris. Sed felis est, tristique vulputate nunc non, bibendum consequat nibh. Ut imperdiet sit amet lectus sed bibendum. Sed vitae blandit nibh, at tincidunt nisi. Nunc vulputate mi in ipsum egestas posuere eget ac arcu. Duis at sagittis sapien.",
                "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean odio lorem, porttitor id ante id, dapibus blandit orci. Donec molestie luctus neque sit amet fermentum. Aliquam nec tempus nulla. Aenean nec auctor metus. Curabitur non ultrices enim. In nec orci efficitur, vestibulum sem ut, molestie metus. Aenean sit amet purus finibus, tempor nibh et, ultrices orci. Fusce elementum fringilla eros, vel facilisis justo placerat et. Proin sagittis, nunc vitae rutrum porttitor, libero risus vulputate ipsum, quis dignissim sapien orci non quam. Cras eu dolor volutpat, blandit lacus vitae, venenatis felis. Sed laoreet mi non turpis feugiat pharetra. Fusce sem est, condimentum at elit a, consequat condimentum mauris. Vestibulum est est, tincidunt sed varius ac, gravida eget purus. Pellentesque sit amet nibh sit amet mi tincidunt tempor non vitae quam.",
                "Sed a augue nunc. Suspendisse potenti. Praesent hendrerit sem lacus, sodales bibendum nunc pretium vel. Proin tincidunt, orci porttitor suscipit consectetur, neque dui fringilla neque, vitae dapibus orci libero quis leo. Nunc velit arcu, accumsan et felis ut, sodales varius libero. Quisque vitae iaculis ante. Suspendisse potenti. Vivamus fringilla sollicitudin mollis. Etiam nulla dolor, placerat at molestie a, lobortis et diam. Phasellus egestas aliquet pellentesque. Etiam pretium sapien sed nunc vehicula, in fermentum quam euismod. Proin auctor leo eu urna tempus, quis auctor felis bibendum. Quisque sollicitudin lacinia urna a ultricies. Ut volutpat eros tristique tempor imperdiet. Sed sit amet nulla non elit sollicitudin rutrum. In suscipit mollis purus, non efficitur justo molestie tempus.",
                "Quisque sed est odio. Ut et sodales nulla, ornare mollis nunc. Curabitur nec bibendum nunc. Phasellus lobortis auctor faucibus. Praesent quis metus at diam mollis laoreet. Nulla viverra risus in blandit interdum. Praesent sed tortor id felis tincidunt luctus nec vel dolor. Vivamus hendrerit, enim vel sollicitudin consequat, dui augue tincidunt metus, quis pellentesque dui ante non leo. Mauris ultricies elit id tempus vehicula. Nunc mauris arcu, accumsan quis lorem quis, pharetra tincidunt sem. Donec ut lacus molestie dolor convallis elementum tincidunt vitae sem. Fusce viverra tortor libero, vitae ultricies lectus hendrerit interdum. In hac habitasse platea dictumst. Fusce ante eros, pretium at pellentesque id, auctor et mi. Nam ut accumsan dolor, ac cursus elit. Nunc nec sapien blandit, volutpat tortor eget, aliquet lacus.",
            };
            Paragraph para = null;
            CustomParagraphRenderer paragraphRenderer = null;

            document = new Document(pdf, PageSize.A4);
            document.setRenderer(new DocumentRenderer(document));

            // One full body paragraph that does not flow onto subsequent pages ...
            para = new Paragraph().add(loremipsums[0]);
            paragraphRenderer = new CustomParagraphRenderer(para);
            para.setNextRenderer(paragraphRenderer);
            document.add(para);

            // ... followed by column layout starting on the same page and flowing onto subsequent pages.
            float y = paragraphRenderer.getY();
            float offSet = 36; // margins
            float gutter = 23; // column gap
            float columnWidth = (PageSize.A4.getWidth() - offSet * 2) / 2 - gutter;
            float columnHeight1 = y - offSet * 2;
            Rectangle[] columns1 = {
                new Rectangle(offSet, offSet, columnWidth, columnHeight1),
                new Rectangle(offSet + columnWidth + gutter, offSet, columnWidth, columnHeight1)
            };
            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 CustomColumnDocumentRenderer(document, columns1, columns2));  
            for(int i = 0; i < 5; i++) {
                for(String loremipsum : loremipsums) {
                    document.add(new Paragraph(loremipsum));
                }
            }

            // Then followed by full body paragraphs stating on the page after the column layout and flowing onto subsequent pages ...
            document.setRenderer(new DocumentRenderer(document));
            document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
            document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
            for(int i = 0; i < 5; i++) {
                for(String loremipsum : loremipsums) {
                    para = new Paragraph().add(loremipsum);
                    paragraphRenderer = new CustomParagraphRenderer(para);
                    para.setNextRenderer(paragraphRenderer);
                    document.add(para);
                }
            }

            // ... finally followed by column layout starting on the same page as the last paragraph as the previous full body layout, and flowing onto subsequent pages.
            // BUG: However - this starts rendering at the top of a new page. It does NOT begin rendering on the same page as the last full body paragraph previously rendered.
            // BUG: And some of the text in gets lost at the start of rendering this section.
            y = ((CustomParagraphRenderer)para.getRenderer()).getY();
            offSet = 36; // margins
            gutter = 23; // column gap
            columnWidth = (PageSize.A4.getWidth() - offSet * 2) / 2 - gutter;
            columnHeight1 = y - offSet * 2;
            columns1 = new Rectangle[2];
            columns1[0] = new Rectangle(offSet, offSet, columnWidth, columnHeight1);
            columns1[1] = new Rectangle(offSet + columnWidth + gutter, offSet, columnWidth, columnHeight1);
            columnHeight2 = PageSize.A4.getHeight() - offSet * 2;
            columns2 = new Rectangle[2];
            columns2[0] = new Rectangle(offSet, offSet, columnWidth, columnHeight2);
            columns2[1] = new Rectangle(offSet + columnWidth + gutter, offSet, columnWidth, columnHeight2);
            document.setRenderer(new CustomColumnDocumentRenderer(document, columns1, columns2));
            for(int i = 0; i < 5; i++) {
                for(String loremipsum : loremipsums) {
                    document.add(new Paragraph(loremipsum));
                }
            }

            document.flush();
            document.close();
        } catch(Exception e) {
            log.error(null, e);
        } finally {
            if(document != null) {
                document.close();
            }
        }
        if(file.exists()) {
            try {
                Desktop.getDesktop().open(file);
            } catch (IOException e) {
                log.error(null, e);
            }
        }
    }

}
y = ((CustomParagraphRenderer)para.getRenderer()).getY();
private static float y = 0.0f;
...
columns2 = new Rectangle[2];
columns2[0] = new Rectangle(offSet, offSet, columnWidth, columnHeight2);
columns2[1] = new Rectangle(offSet + columnWidth + gutter, offSet, columnWidth, columnHeight2);
document.setRenderer(new CustomColumnDocumentRenderer(document, columns1, columns2));
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE)); // <---
for(int i = 0; i < 5; i++) {
    for(String loremipsum : loremipsums) {
        document.add(new Paragraph(loremipsum));
    }
}
...