1

I need to create an User guide, where I've to put the content in 2 different language but on the same page. so the first half of the page would be in English while the second part would be in French. (In future they might ask for 3rd language also, but maximum 3). So each page would have 2 blocks. How can I achieve this using iTextPDF in java ?


UPDATE

Following is the structure for more insight of the question.

enter image description here

IT ppl
  • 2,626
  • 1
  • 39
  • 56
  • Have you tried using `ColumnText`? – Bruno Lowagie Feb 13 '15 at 15:44
  • @BrunoLowagie Thanks for your time sir, I require the page structure to be row alligned. For more insight I've added a sample. Please suggest. – IT ppl Feb 14 '15 at 07:22
  • I looked at the example, and I must repeat: have you tried using `ColumnText`? Because that's how I would work if I want the output you describe in your graphical representation of what you need. – Bruno Lowagie Feb 14 '15 at 11:21

1 Answers1

2

If I understand your question correctly, you need to create something like this:

enter image description here

In this screen shot, you see the first part of the first book of Caesar's Commentaries on the Gallic War. Gallia omnia est divisa in partes tres, and so is each page in this document: the upper part shows the text in Latin, the middle part shows the text in English, the lower part shows the text in French. If you read the text, you'll discover that Belgians like me are considered being the bravest of all (although we aren't as civilized as one would wish). See three_parts.pdf if you want to take a look at the PDF.

This PDF was created with the ThreeParts example. In this example, I have 9 text files:

Liber is the latin word for book, so all files are snippets from the first book, more specifically sections 1, 2, and 3, in Latin, English and French.

This is how I defined the languages and he rectangles for each language:

public static final String[] LANGUAGES = { "la", "en", "fr" };
public static final Rectangle[] RECTANGLES = {
    new Rectangle(36, 581, 559, 806),
    new Rectangle(36, 308.5f, 559, 533.5f),
    new Rectangle(36, 36, 559, 261) };

In my code, I loop over the different sections, and I create a ColumnText object for each language:

PdfContentByte cb = writer.getDirectContent();
ColumnText[] columns = new ColumnText[3];
for (int section = 1; section <= 3; section++) {
    for (int la = 0; la < 3; la++) {
        columns[la] = createColumn(cb, section, LANGUAGES[la], RECTANGLES[la]);
    }
    while (addColumns(columns)) {
        document.newPage();
        for (int la = 0; la < 3; la++) {
            columns[la].setSimpleColumn(RECTANGLES[la]);
        }
    }
    document.newPage();
}

If you examine the body of the inner loop, you see that I first define three ColumnText objects, one for each language:

public ColumnText createColumn(PdfContentByte cb, int i, String la, Rectangle rect)
    throws IOException {
    ColumnText ct = new ColumnText(cb);
    ct.setSimpleColumn(rect);
    Phrase p = createPhrase(String.format("resources/text/liber1_%s_%s.txt", i, la));
    ct.addText(p);
    return ct;
}

In this case, I'm using ColumnText in text mode, and I read the text from the different files into a Phrase like this:

public Phrase createPhrase(String path) throws IOException {
    Phrase p = new Phrase();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(new FileInputStream(path), "UTF8"));
    String str;
    while ((str = in.readLine()) != null) {
        p.add(str);
    }
    in.close();
    return p;
}

Once I have defined the ColumnText objects and added their content, I need to render the content to one of more pages until all the text is rendered from all columns. To achieve this, we use this method:

public boolean addColumns(ColumnText[] columns) throws DocumentException {
    int status = ColumnText.NO_MORE_TEXT;
    for (ColumnText column : columns) {
        if (ColumnText.hasMoreText(column.go()))
            status = ColumnText.NO_MORE_COLUMN;
    }
    return ColumnText.hasMoreText(status);
}

As you can see, I also create a new page for every new section I start. This isn't really necessary: I could add all the section to a single ColumnText, but depending on how the Latin text translated into English and French, you could end up with large discrepancies where section X of the Latin text starts on one page and the same section in English or French starts on another page. Hence my choice to start a new page, although it's not really necessary in this small proof of concept.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165