Divide page in 2 parts so we can fill each with different source

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 ?



Following is the structure for more insight of the question.

<img src="https://i.stack.imgur.com/joWrC.png" alt="enter image description here">


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

<img src="https://i.stack.imgur.com/GdAoR.png" alt="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:

    <li>http://itextpdf.com/sites/default/files/liber1_1_la.txt</li> <li>http://itextpdf.com/sites/default/files/liber1_1_en.txt</li> <li>http://itextpdf.com/sites/default/files/liber1_1_fr.txt</li> <li>http://itextpdf.com/sites/default/files/liber1_2_la.txt</li> <li>http://itextpdf.com/sites/default/files/liber1_2_en.txt</li> <li>http://itextpdf.com/sites/default/files/liber1_2_fr.txt</li> <li>http://itextpdf.com/sites/default/files/liber1_3_la.txt</li> <li>http://itextpdf.com/sites/default/files/liber1_3_en.txt</li> <li>http://itextpdf.com/sites/default/files/liber1_3_fr.txt</li> </ul>

    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.


  • PDFStamper fails on several PDF files (itext 5.5.1)
  • Itext 5.5 Converting HTML to PDF for RTL languages (Arabic) not working on tomcat
  • touchesBegan not responding
  • Parsing/Looping over JSON objects from a text file (Python)
  • Apply kurtosis to a distribution in python
  • Morphological Reconstruction in OpenCV
  • TextBox controls are not Working with Export To PDF(iTextSharp)
  • Windows Phone 7.1 “Send To” functionality?
  • How can i display a PDF file in an Android ImageView
  • How open new window with base64 PDF content?
  • Getting the “Do you want to overwrite the file” dialog box to show when saving with VBA
  • ABCpdf convert text to image
  • How to Get reports in odt format from rml files in openerp
  • how to download csv with fusion charts in codeigniter
  • PHP PDF generation problem
  • MySQL wildcard replace
  • Determining the length of a read stream in node js
  • PDF using WCF Restful Services
  • How to display the images in listview
  • Get the number 18437736874454810627
  • Is there a way to dynamically embed PDF Files in a JSP pulled from the file system?
  • Creating PDF from TIFF image using iText
  • Why are YouTube videos using 'youtube.com/v' not loading
  • Web.config system.webserver errors
  • Not able to aggregate on nested fields in elasticsearch
  • Why HTML5 Canvas with a larger size stretch a drawn line?
  • Spray.io: When (not) to use non-blocking route handling?
  • Incrementing object id automatically JS constructor (static method and variable)
  • Modifying destination and filename of gulp-svg-sprite
  • GridView Sorting works once only
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • How do I rollback to a specific git commit
  • Is there a mandatory requirement to switch app.yaml?
  • bootstrap to use multiple ng-app
  • How to get icons for entities from eclipse?
  • Free memory of cv::Mat loaded using FileStorage API
  • Turn off referential integrity in Derby? is it possible?
  • unknown Exception android
  • JaxB to read class hierarchy
  • Busy indicator not showing up in wpf window [duplicate]