I
I
iText Software2019-06-27 05:45:45
Java
iText Software, 2019-06-27 05:45:45

How to divide a page into N parts and fill each of them from different sources?

The first half of the page will be in English and the second half in French:
5d142dbe7efd5099943891.png
A third language may be needed in the future. There will be a maximum of three parts. Now each page should have two blocks. How to achieve this using iTextPDF in Java?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
iText Software, 2019-06-27
@iText_Q

If I understand your question correctly, then you need to create something like this: 5d142dfe2f60f512136833.pngExample
This screenshot shows the first part of the first book of Caesar's Notes on the Gallic War. Gallia omnia est divisa in partes tres, each page is divided in the following order: the upper part contains text in Latin, the middle part in English, and the lower part in French. If you read the text, you will find that the Belgians (and I am Belgian) are the bravest people (although we are not as civilized as we would like). See three_parts.pdf for an example PDF file.
This PDF is created with the ThreeParts example . In this example, there are 9 text files: liber1_1_la.txt , liber1_1_en.txt, liber1_1_fr.txt , liber1_2_la.txt , liber1_2_en.txt , liber1_2_fr.txt , liber1_3_la.txt , liber1_3_en.txt and liber1_3_fr.txt .
"Liber" is Latin for "book" and all files are excerpts from the first book, specifically sections 1, 2 and 3 in Latin, English and French.
In my code, I create a loop through different sections and an object Paragraphfor each language:

PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
int firstPageNumber = 1;
for (int section = 0; section < 3; section++) {
    // latin
    addSection(pdfDoc, createParagraph(String.format("./src/test/resources/txt/liber1_%s_la.txt", section + 1)), firstPageNumber, 2);
    // english
    addSection(pdfDoc, createParagraph(String.format("./src/test/resources/txt/liber1_%s_en.txt", section + 1)), firstPageNumber, 1);
    // french
    addSection(pdfDoc, createParagraph(String.format("./src/test/resources/txt/liber1_%s_fr.txt", section + 1)), firstPageNumber, 0);
   firstPageNumber = pdfDoc.getNumberOfPages() + 1;
}

We create paragraphs Paragraphlike this:
public Paragraph createParagraph(String path) throws IOException {
    Paragraph p = new Paragraph();
    BufferedReader in = new BufferedReader(
            new InputStreamReader(new FileInputStream(path), "UTF-8"));
    StringBuffer buffer = new StringBuffer();
    String line = in.readLine();
    while (null != line) {
        buffer.append(line);
        line = in.readLine();
    }
    in.close();
    p.add(buffer.toString());
    return p;
}

Then we use the created paragraphs in the method addSection():
public void addSection(PdfDocument pdfDoc, Paragraph paragraph, int pageNumber, int sectionNumber) throws IOException {
    LayoutResult layoutResult;
    ParagraphRenderer renderer = (ParagraphRenderer) paragraph.createRendererSubTree();
    renderer.setParent(new DocumentRenderer(new Document(pdfDoc)));
    while (((layoutResult = renderer.layout(new LayoutContext(new LayoutArea(pageNumber, new Rectangle(36, 36 + ((842 - 72) / 3) * sectionNumber, 523, (842 - 72) / 3)))))).getStatus() != LayoutResult.FULL) {
        if (pdfDoc.getNumberOfPages() < pageNumber) {
            pdfDoc.addNewPage();
        }
        layoutResult.getSplitRenderer().draw(new DrawContext(pdfDoc, new PdfCanvas(pdfDoc.getPage(pageNumber++)), false));
        renderer = (ParagraphRenderer) layoutResult.getOverflowRenderer();
    }
    if (pdfDoc.getNumberOfPages() < pageNumber) {
        pdfDoc.addNewPage();
    }
    renderer.draw(new DrawContext(pdfDoc, new PdfCanvas(pdfDoc.getPage(pageNumber)), false));
}

Here we have initialized the object ParagraphRendererand modified it LayoutAreaaccording to the parameter sectionNumber. We check the status LayoutResultand process the content of one or more pages until all the texts for all pages are ready.
From the example, you can see that we also create a new page for each new section. This is optional, but Latin text can be translated into English and French in different ways, which means that serious inconsistencies can arise, for example, when section X with Latin text begins on the same page, but the same section in English or French begins on next page. So I'm creating a new page, although it's not necessary in such a small example.

C
Cheypnow, 2019-07-01
@Cheypnow

You write code that fills an area on a page with text, depending on the coordinates of the beginning and end of the area.
Then you divide into as many parts as you like and transfer their coordinates.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question