Skip to main content
Skip table of contents

Positioning different text snippets on a page

These examples were written in response to questions such as:


centercolumnvertically

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.objects;

import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.layout.LayoutArea;
import com.itextpdf.layout.layout.LayoutContext;
import com.itextpdf.layout.layout.LayoutResult;
import com.itextpdf.layout.renderer.IRenderer;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class CenterColumnVertically {
    public static final String DEST = "./target/sandbox/objects/center_column_vertically.pdf";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new CenterColumnVertically().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws IOException {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        Document doc = new Document(pdfDoc);

        float llx = 50;
        float lly = 650;
        float urx = 400;
        float ury = 800;

        Rectangle rect = new Rectangle(llx, lly, urx - llx, ury - lly);
        PdfCanvas canvas = new PdfCanvas(pdfDoc.addNewPage());
        canvas.setStrokeColor(ColorConstants.RED)
                .setLineWidth(0.5f)
                .rectangle(rect)
                .stroke();

        Paragraph p = new Paragraph("This text is centered vertically. "
                + "It is rendered in the middle of the red rectangle.");
        float width = resolveTextHeight(doc, rect, p);
        new Canvas(canvas, rect)
                .add(p.setFixedPosition(llx, (ury + lly) / 2 - width / 2, urx - llx).setMargin(0));

        doc.close();
    }

    private static float resolveTextHeight(Document doc, Rectangle rect, Paragraph p) {
        IRenderer pRenderer = p.createRendererSubTree().setParent(doc.getRenderer());
        LayoutResult pLayoutResult = pRenderer.layout(new LayoutContext(new LayoutArea(0, rect)));

        Rectangle pBBox = pLayoutResult.getOccupiedArea().getBBox();
        return pBBox.getHeight();
    }
}

C#

C#
using System.IO;
using iText.Kernel.Colors;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Layout;
using iText.Layout.Element;

namespace iText.Samples.Sandbox.Objects
{
    public class CenterColumnVertically
    {
        public static readonly string DEST = "results/sandbox/objects/center_column_vertically.pdf";

        public static void Main(string[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
            new CenterColumnVertically().ManipulatePdf(DEST);
        }

        protected void ManipulatePdf(string dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));

            float llx = 50;
            float lly = 650;
            float urx = 400;
            float ury = 800;

            Rectangle rect = new Rectangle(llx, lly, urx - llx, ury - lly);
            PdfCanvas canvas = new PdfCanvas(pdfDoc.AddNewPage());
            canvas.SetStrokeColor(ColorConstants.RED)
                .SetLineWidth(0.5f)
                .Rectangle(rect)
                .Stroke();

            Paragraph p = new Paragraph("This text is displayed above the vertical middle of the red rectangle.");
            new Canvas(canvas, rect)
                .Add(p.SetFixedPosition(llx, (ury + lly) / 2, urx - llx).SetMargin(0));

            pdfDoc.Close();
        }
    }
}

centervertically

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.objects;

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.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.layout.LayoutArea;
import com.itextpdf.layout.layout.LayoutContext;
import com.itextpdf.layout.layout.LayoutResult;
import com.itextpdf.layout.properties.UnitValue;
import com.itextpdf.layout.renderer.IRenderer;
import com.itextpdf.layout.renderer.TableRenderer;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class CenterVertically {
    public static final String DEST = "./target/sandbox/objects/center_vertically.pdf";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new CenterVertically().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws IOException {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        Document doc = new Document(pdfDoc);

        Cell cell = new Cell();
        for (int i = 1; i <= 5; i++) {
            cell.add(new Paragraph("Line " + i));
        }

        Table table = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        table.addCell(cell);
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.setNextRenderer(new CustomTableRenderer(table, resolveTableRect(doc, table)));
        doc.add(table);
        doc.add(new AreaBreak());

        table = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.addCell(cell.clone(true));
        table.setNextRenderer(new CustomTableRenderer(table, resolveTableRect(doc, table)));
        doc.add(table);

        doc.close();
    }

    private static Rectangle resolveTableRect(Document doc, Table table) {
        Rectangle pageDimension = new Rectangle(36, 36, 523, 770);
        IRenderer tableRenderer = table.createRendererSubTree().setParent(doc.getRenderer());
        LayoutResult tableLayoutResult = tableRenderer.layout(new LayoutContext(new LayoutArea(0, pageDimension)));

        Rectangle resultRect;
        if (LayoutResult.PARTIAL == tableLayoutResult.getStatus()) {
            resultRect = pageDimension;
        } else {
            Rectangle tableBBox = tableLayoutResult.getOccupiedArea().getBBox();
            resultRect = new Rectangle(pageDimension.getX(), ((tableBBox.getBottom() + pageDimension.getX()) / 2),
                    pageDimension.getWidth(), tableBBox.getHeight());
        }
        return resultRect;
    }

    protected class CustomTableRenderer extends TableRenderer {
        protected Rectangle rect;

        public CustomTableRenderer(Table modelElement, Rectangle rect) {
            super(modelElement);
            this.rect = new Rectangle(rect);
        }

        // If a renderer overflows on the next area, iText uses #getNextRenderer() method to create a new renderer for the overflow part.
        // If #getNextRenderer() isn't overridden, the default method will be used and thus the default rather than the custom
        // renderer will be created
        @Override
        public IRenderer getNextRenderer() {
            return new CustomTableRenderer((Table) modelElement, rect);
        }

        @Override
        public LayoutResult layout(LayoutContext layoutContext) {
            return super.layout(new LayoutContext(new LayoutArea(layoutContext.getArea().getPageNumber(), rect)));
        }
    }
}

C#

C#
using System.IO;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Layout;
using iText.Layout.Properties;
using iText.Layout.Renderer;

namespace iText.Samples.Sandbox.Objects
{
    public class CenterVertically
    {
        public static readonly string DEST = "results/sandbox/objects/center_vertically.pdf";

        public static void Main(string[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
            new CenterVertically().ManipulatePdf(DEST);
        }

        protected void ManipulatePdf(string dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
            Document doc = new Document(pdfDoc);
            
            Cell cell = new Cell();
            for (int i = 1; i <= 5; i++)
            {
                cell.Add(new Paragraph("Line " + i));
            }

            Table table = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
            table.AddCell(cell);
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.SetNextRenderer(new CustomTableRenderer(table, ResolveTableRect(doc, table)));
            doc.Add(table);
            doc.Add(new AreaBreak());

            table = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.AddCell(cell.Clone(true));
            table.SetNextRenderer(new CustomTableRenderer(table, ResolveTableRect(doc, table)));
            doc.Add(table);

            doc.Close();
        }

        private static Rectangle ResolveTableRect(Document doc, Table table)
        {
            Rectangle pageDimension = new Rectangle(36, 36, 523, 770);
            IRenderer tableRenderer = table.CreateRendererSubTree().SetParent(doc.GetRenderer());
            LayoutResult tableLayoutResult = tableRenderer.Layout(new LayoutContext(new LayoutArea(0, pageDimension)));

            Rectangle resultRect;
            if (LayoutResult.PARTIAL == tableLayoutResult.GetStatus())
            {
                resultRect = pageDimension;
            }
            else
            {
                Rectangle tableBBox = tableLayoutResult.GetOccupiedArea().GetBBox();
                resultRect = new Rectangle(pageDimension.GetX(), ((tableBBox.GetBottom() + pageDimension.GetX()) / 2),
                    pageDimension.GetWidth(), tableBBox.GetHeight());
            }

            return resultRect;
        }

        protected class CustomTableRenderer : TableRenderer
        {
            protected Rectangle rect;

            public CustomTableRenderer(Table modelElement, Rectangle rect) : base(modelElement)
            {
                this.rect = new Rectangle(rect);
            }

            // If renderer overflows on the next area, iText uses getNextRender() method to create a renderer for the overflow part.
            // If getNextRenderer isn't overridden, the default method will be used and thus a default rather than custom
            // renderer will be created
            public override IRenderer GetNextRenderer()
            {
                return new CustomTableRenderer((Table) modelElement, rect);
            }

            public override LayoutResult Layout(LayoutContext layoutContext)
            {
                return base.Layout(new LayoutContext(new LayoutArea(layoutContext.GetArea().GetPageNumber(), rect)));
            }
        }
    }
}


columntextphrase

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.objects;

import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.font.PdfFontFactory.EmbeddingStrategy;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ColumnTextPhrase {
    public static final String DEST = "./target/sandbox/objects/column_text_phrase.pdf";
    public static final String SRC = "./src/main/resources/pdfs/hello.pdf";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new ColumnTextPhrase().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws IOException {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));

        PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD,
                PdfEncodings.CP1252, EmbeddingStrategy.PREFER_EMBEDDED);
        Paragraph pz = new Paragraph("Hello World!").setFont(font).setFontSize(13);
        new Canvas(new PdfCanvas(pdfDoc.getFirstPage()), new Rectangle(120, 48, 80, 580))
                .add(pz);

        // The Leading is used in this paragraph, the Leading is a spacing between lines of text
        font = PdfFontFactory.createFont(StandardFonts.HELVETICA);
        pz = new Paragraph("Hello World!").setFont(font).setFixedLeading(20);
        new Canvas(new PdfCanvas(pdfDoc.getFirstPage()), new Rectangle(120, 48, 80, 480))
                .add(pz);

        pdfDoc.close();
    }
}

C#

C#
using System.IO;
using iText.IO.Font;
using iText.IO.Font.Constants;
using iText.Kernel.Font;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Layout;
using iText.Layout.Element;

namespace iText.Samples.Sandbox.Objects
{
    public class ColumnTextPhrase
    {
        public static readonly string DEST = "results/sandbox/objects/column_text_phrase.pdf";
        public static readonly string SRC = "../../../resources/pdfs/hello.pdf";

        public static void Main(string[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
            new ColumnTextPhrase().ManipulatePdf(DEST);
        }

        protected void ManipulatePdf(string dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));

            PdfFont font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD, PdfEncodings.CP1252, 
                PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED);
            Paragraph pz = new Paragraph("Hello World!").SetFont(font).SetFontSize(13);
            new Canvas(new PdfCanvas(pdfDoc.GetFirstPage()), new Rectangle(120, 48, 80, 580))
                .Add(pz);

            // The Leading is used in this paragraph, the Leading is a spacing between lines of text
            font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
            pz = new Paragraph("Hello World!").SetFont(font).SetFixedLeading(20);
            new Canvas(new PdfCanvas(pdfDoc.GetFirstPage()), new Rectangle(120, 48, 80, 480))
                .Add(pz);

            pdfDoc.Close();
        }
    }
}

drawrectanglearoundtext

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.objects;

import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.layout.LayoutArea;
import com.itextpdf.layout.layout.LayoutContext;
import com.itextpdf.layout.renderer.ParagraphRenderer;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class DrawRectangleAroundText {
    public static final String DEST = "./target/sandbox/objects/draw_rectangle_around_text.pdf";
    public static final String SRC = "./src/main/resources/pdfs/hello.pdf";

    public static void main(String[] args) throws IOException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new DrawRectangleAroundText().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws IOException {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
        Document doc = new Document(pdfDoc);

        PdfCanvas canvas = new PdfCanvas(pdfDoc.getFirstPage());
        Paragraph p = new Paragraph("This is a long paragraph that doesn't"
                + "fit the width we defined for the simple column of the"
                + "ColumnText object, so it will be distributed over several"
                + "lines (and we don't know in advance how many).");

        Rectangle firstRect = new Rectangle(120, 500, 130, 280);
        new Canvas(canvas, firstRect)
                .add(p);
        canvas.rectangle(firstRect);
        canvas.stroke();

        // In the lines below the comment we try to reproduce the iText5 method to achieve the result
        // However it's much more simple to use the next line
        // p.setBorder(new SolidBorder(1));
        // Or you can implement your own ParagraphRenderer and change the behaviour of drawBorder(DrawContext)
        // or draw(DrawContext)
        Rectangle secRect = new Rectangle(300, 500, 130, 280);
        ParagraphRenderer renderer = (ParagraphRenderer) p.createRendererSubTree().setParent(doc.getRenderer());
        float height = renderer.layout(new LayoutContext(new LayoutArea(0, secRect)))
                .getOccupiedArea().getBBox().getHeight();

        new Canvas(canvas, secRect)
                .add(p);
        canvas.rectangle(secRect.getX(), secRect.getY() + secRect.getHeight() - height, secRect.getWidth(), height);
        canvas.stroke();

        doc.close();
    }
}

C#

C#
using System.IO;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Layout;
using iText.Layout.Renderer;

namespace iText.Samples.Sandbox.Objects
{
    public class DrawRectangleAroundText
    {
        public static readonly string DEST = "results/sandbox/objects/draw_rectangle_around_text.pdf";
        public static readonly string SRC = "../../../resources/pdfs/hello.pdf";

        public static void Main(string[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
            new DrawRectangleAroundText().ManipulatePdf(DEST);
        }

        protected void ManipulatePdf(string dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
            Document doc = new Document(pdfDoc);

            PdfCanvas canvas = new PdfCanvas(pdfDoc.GetFirstPage());
            Paragraph p = new Paragraph("This is a long paragraph that doesn't"
                                        + "fit the width we defined for the simple column of the"
                                        + "ColumnText object, so it will be distributed over several"
                                        + "lines (and we don't know in advance how many).");

            Rectangle firstRect = new Rectangle(120, 500, 130, 280);
            new Canvas(canvas, firstRect)
                .Add(p);
            canvas.Rectangle(firstRect);
            canvas.Stroke();

            // In the lines below the comment we try to reproduce the iText5 method to achieve the result
            // However it's much more simple to use the next line
            // p.SetBorder(new SolidBorder(1));
            // Or you can implement your own ParagraphRenderer and change the behaviour of drawBorder(DrawContext)
            // or draw(DrawContext)
            Rectangle secRect = new Rectangle(300, 500, 130, 280);
            ParagraphRenderer renderer = (ParagraphRenderer) p.CreateRendererSubTree().SetParent(doc.GetRenderer());
            float height = renderer.Layout(new LayoutContext(new LayoutArea(0, secRect)))
                .GetOccupiedArea().GetBBox().GetHeight();

            new Canvas(canvas, secRect)
                .Add(p);
            canvas.Rectangle(secRect.GetX(), secRect.GetY() + secRect.GetHeight() - height, secRect.GetWidth(), height);
            canvas.Stroke();

            doc.Close();
        }
    }
}


threeparts

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.events;

import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.layout.LayoutArea;
import com.itextpdf.layout.layout.LayoutContext;
import com.itextpdf.layout.layout.LayoutResult;
import com.itextpdf.layout.renderer.DocumentRenderer;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.layout.renderer.ParagraphRenderer;

import java.io.File;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.IOException;

public class ThreeParts {
    public static final String DEST = "./target/sandbox/events/three_parts.pdf";

    public static final String SRC_LA = "./src/main/resources/txt/liber1_%s_la.txt";
    public static final String SRC_EN = "./src/main/resources/txt/liber1_%s_en.txt";
    public static final String SRC_FR = "./src/main/resources/txt/liber1_%s_fr.txt";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();

        new ThreeParts().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        int firstPageNumber = 1;

        for (int i = 0; i < 3; i++) {

            // latin
            addSection(pdfDoc, readAndCreateParagraph(String.format(SRC_LA, i + 1)),
                    firstPageNumber, 0);

            // english
            addSection(pdfDoc, readAndCreateParagraph(String.format(SRC_EN, i + 1)),
                    firstPageNumber, 1);

            // french
            addSection(pdfDoc, readAndCreateParagraph(String.format(SRC_FR, i + 1)),
                    firstPageNumber, 2);

            firstPageNumber = pdfDoc.getNumberOfPages() + 1;
        }

        pdfDoc.close();
    }

    private static void addSection(PdfDocument pdfDoc, Paragraph paragraph, int pageNumber, int sectionNumber) {
        Document doc = new Document(pdfDoc);
        ParagraphRenderer renderer = (ParagraphRenderer) paragraph.createRendererSubTree();
        renderer.setParent(new DocumentRenderer(doc));

        float pageHeight = pdfDoc.getDefaultPageSize().getHeight();
        float pageWidth = pdfDoc.getDefaultPageSize().getWidth();
        Rectangle textSectionRectangle = new Rectangle(
                doc.getLeftMargin(),
                doc.getBottomMargin() + ((pageHeight - doc.getTopMargin() - doc.getBottomMargin()) / 3) * sectionNumber,
                pageWidth - doc.getLeftMargin() - doc.getRightMargin(),
                (pageHeight - doc.getTopMargin() - doc.getBottomMargin()) / 3);

        // Simulate the positioning of the renderer to find out how much space the text section will occupy.
        LayoutResult layoutResult = renderer
                .layout(new LayoutContext(new LayoutArea(pageNumber, textSectionRectangle)));

        /* Fill the current page section with the content.
         * If the content isn't fully placed in the current page section,
         * it will be split and drawn in the next page section.
         */
        while (layoutResult.getStatus() != LayoutResult.FULL) {
            if (pdfDoc.getNumberOfPages() < pageNumber) {
                pdfDoc.addNewPage();
            }

            pageNumber++;

            layoutResult.getSplitRenderer().draw(new DrawContext(pdfDoc,
                    new PdfCanvas(pdfDoc.getPage(pageNumber - 1)), false));

            renderer = (ParagraphRenderer) layoutResult.getOverflowRenderer();

            layoutResult = renderer
                    .layout(new LayoutContext(new LayoutArea(pageNumber, textSectionRectangle)));
        }

        if (pdfDoc.getNumberOfPages() < pageNumber) {
            pdfDoc.addNewPage();
        }

        renderer.draw(new DrawContext(pdfDoc, new PdfCanvas(pdfDoc.getPage(pageNumber)), false));
    }

    private static Paragraph readAndCreateParagraph(String path) throws IOException {
        Paragraph p = new Paragraph();
        StringBuffer buffer = new StringBuffer();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"))) {
            String line = reader.readLine();
            while (null != line) {
                buffer.append(line);
                line = reader.readLine();
            }
        }

        p.setBorder(new SolidBorder(ColorConstants.RED, 1));
        p.add(buffer.toString());
        return p;
    }
}

C#

C#
using System;
using System.IO;
using System.Text;
using iText.Kernel.Colors;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Layout;
using iText.Layout.Borders;
using iText.Layout.Element;
using iText.Layout.Layout;
using iText.Layout.Renderer;

namespace iText.Samples.Sandbox.Events
{
    public class ThreeParts
    {
        public static readonly String DEST = "results/sandbox/events/three_parts.pdf";

        public static readonly String SRC_LA = "../../../resources/txt/liber1_{0}_la.txt";
        public static readonly String SRC_EN = "../../../resources/txt/liber1_{0}_en.txt";
        public static readonly String SRC_FR = "../../../resources/txt/liber1_{0}_fr.txt";

        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();

            new ThreeParts().ManipulatePdf(DEST);
        }

        protected void ManipulatePdf(String dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
            int firstPageNumber = 1;

            for (int i = 0; i < 3; i++)
            {
                // latin
                AddSection(pdfDoc, ReadAndCreateParagraph(String.Format(SRC_LA, i + 1)),
                    firstPageNumber, 0);

                // english
                AddSection(pdfDoc, ReadAndCreateParagraph(String.Format(SRC_EN, i + 1)),
                    firstPageNumber, 1);

                // french
                AddSection(pdfDoc, ReadAndCreateParagraph(String.Format(SRC_FR, i + 1)),
                    firstPageNumber, 2);

                firstPageNumber = pdfDoc.GetNumberOfPages() + 1;
            }

            pdfDoc.Close();
        }

        private static void AddSection(PdfDocument pdfDoc, Paragraph paragraph, int pageNumber, int sectionNumber)
        {
            Document doc = new Document(pdfDoc);
            ParagraphRenderer renderer = (ParagraphRenderer) paragraph.CreateRendererSubTree();
            renderer.SetParent(new DocumentRenderer(doc));

            float pageHeight = pdfDoc.GetDefaultPageSize().GetHeight();
            float pageWidth = pdfDoc.GetDefaultPageSize().GetWidth();
            Rectangle textSectionRectangle = new Rectangle(
                doc.GetLeftMargin(),
                doc.GetBottomMargin() + ((pageHeight - doc.GetTopMargin() - doc.GetBottomMargin()) / 3) * sectionNumber,
                pageWidth - doc.GetLeftMargin() - doc.GetRightMargin(),
                (pageHeight - doc.GetTopMargin() - doc.GetBottomMargin()) / 3);

            // Simulate the positioning of the renderer to find out how much space the text section will occupy.
            LayoutResult layoutResult = renderer
                .Layout(new LayoutContext(new LayoutArea(pageNumber, textSectionRectangle)));

            /* Fill the current page section with the content.
             * If the content isn't fully placed in the current page section,
             * it will be split and drawn in the next page section.
             */
            while (layoutResult.GetStatus() != LayoutResult.FULL)
            {
                if (pdfDoc.GetNumberOfPages() < pageNumber)
                {
                    pdfDoc.AddNewPage();
                }

                pageNumber++;

                layoutResult.GetSplitRenderer().Draw(new DrawContext(pdfDoc,
                    new PdfCanvas(pdfDoc.GetPage(pageNumber - 1)), false));

                renderer = (ParagraphRenderer) layoutResult.GetOverflowRenderer();

                layoutResult = renderer
                    .Layout(new LayoutContext(new LayoutArea(pageNumber, textSectionRectangle)));
            }

            if (pdfDoc.GetNumberOfPages() < pageNumber)
            {
                pdfDoc.AddNewPage();
            }

            renderer.Draw(new DrawContext(pdfDoc, new PdfCanvas(pdfDoc.GetPage(pageNumber)), false));
        }

        private static Paragraph ReadAndCreateParagraph(String path)
        {
            Paragraph p = new Paragraph();
            StringBuilder buffer = new StringBuilder();
            using (StreamReader reader =
                new StreamReader(new FileStream(path, FileMode.Open)))
            {
                String line = reader.ReadLine();
                while (null != line)
                {
                    buffer.Append(line);
                    line = reader.ReadLine();
                }
            }

            p.SetBorder(new SolidBorder(ColorConstants.RED, 1));
            p.Add(buffer.ToString());
            return p;
        }
    }
}

addrotatedtemplate

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.stamper;

import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;

import java.io.File;

public class AddRotatedTemplate {
    public static final String SRC = "./src/main/resources/pdfs/hello.pdf";
    public static final String DEST = "./target/sandbox/stamper/add_rotated_template.pdf";

    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();

        new AddRotatedTemplate().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));

        // Add content to the template without rotation
        PdfFormXObject formXObject = new PdfFormXObject(new Rectangle(80, 120));
        new Canvas(formXObject, pdfDoc)
                .add(new Paragraph("Some long text that needs to be distributed over several lines."));

        // Add template to the pdf document page applying rotation
        PdfCanvas canvas = new PdfCanvas(pdfDoc.getFirstPage());
        canvas.addXObjectAt(formXObject, 36, 600);
        double angle = Math.PI / 4;
        canvas.addXObjectWithTransformationMatrix(formXObject,
                (float) Math.cos(angle), -(float) Math.sin(angle),
                (float) Math.cos(angle), (float) Math.sin(angle),
                150, 600);

        pdfDoc.close();
    }
}

C#

C#
using System;
using System.IO;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Kernel.Pdf.Xobject;
using iText.Layout;
using iText.Layout.Element;

namespace iText.Samples.Sandbox.Stamper 
{
    public class AddRotatedTemplate 
    {
        public static readonly String SRC = "../../../resources/pdfs/hello.pdf";
        public static readonly String DEST = "results/sandbox/stamper/add_rotated_template.pdf";

        public static void Main(String[] args) 
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
            
            new AddRotatedTemplate().ManipulatePdf(DEST);
        }

        protected void ManipulatePdf(String dest) 
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
            
            // Add content to the template without rotation
            PdfFormXObject formXObject = new PdfFormXObject(new Rectangle(80, 120));
            new Canvas(formXObject, pdfDoc)
                    .Add(new Paragraph("Some long text that needs to be distributed over several lines."));
            
            // Add template to the pdf document page applying rotation
            PdfCanvas canvas = new PdfCanvas(pdfDoc.GetFirstPage());
            canvas.AddXObjectAt(formXObject, 36, 600);
            double angle = Math.PI / 4;
            canvas.AddXObjectWithTransformationMatrix(formXObject, (float)Math.Cos(angle), 
                    -(float)Math.Sin(angle), (float)Math.Cos(angle), (float)Math.Sin(angle), 150, 600);
            
            pdfDoc.Close();
        }
    }
}
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.