Apache PDFBox adding multiline paragraph
In the previous tutorial we saw how to create a PDF document with Apache PDFBox. In this tutorial we demonstrate how to add multiline paragraph to a PDF document using Apache PDFBox.
Maven Dependencies
We use Apache Maven to manage our project dependencies. Make sure the following dependencies reside on the class-path.
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.8</version>
</dependency>
Apache PDFBox adding multiline paragraph
By default when you write a (long) text using PDPageContentStream#showText()
it is printed on a single line. We need to calculate how many words will fit on a single line and then write the text to the document. We also wrote a feature to calculate the justified text which you can enable by passing a boolean argument. Take a look at the following example.
package com.memorynotfound.pdf.pdfbox;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MultiLineParagraph {
private static final PDFont FONT = PDType1Font.HELVETICA;
private static final float FONT_SIZE = 12;
private static final float LEADING = -1.5f * FONT_SIZE;
public static void main(String... args) {
try (final PDDocument doc = new PDDocument()){
PDPage page = new PDPage();
doc.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(doc, page);
PDRectangle mediaBox = page.getMediaBox();
float marginY = 80;
float marginX = 60;
float width = mediaBox.getWidth() - 2 * marginX;
float startX = mediaBox.getLowerLeftX() + marginX;
float startY = mediaBox.getUpperRightY() - marginY;
String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" +
" ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco" +
" laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in " +
" ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco" +
" laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in " +
"voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat" +
" non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
contentStream.beginText();
addParagraph(contentStream, width, startX, startY, text, true);
addParagraph(contentStream, width, 0, -FONT_SIZE, text);
addParagraph(contentStream, width, 0, -FONT_SIZE, text, false);
contentStream.endText();
contentStream.close();
doc.save(new File("/tmp/example.pdf"));
} catch (IOException e){
System.err.println("Exception while trying to create pdf document - " + e);
}
}
private static void addParagraph(PDPageContentStream contentStream, float width, float sx,
float sy, String text) throws IOException {
addParagraph(contentStream, width, sx, sy, text, false);
}
private static void addParagraph(PDPageContentStream contentStream, float width, float sx,
float sy, String text, boolean justify) throws IOException {
List<String> lines = parseLines(text, width);
contentStream.setFont(FONT, FONT_SIZE);
contentStream.newLineAtOffset(sx, sy);
for (String line: lines) {
float charSpacing = 0;
if (justify){
if (line.length() > 1) {
float size = FONT_SIZE * FONT.getStringWidth(line) / 1000;
float free = width - size;
if (free > 0 && !lines.get(lines.size() - 1).equals(line)) {
charSpacing = free / (line.length() - 1);
}
}
}
contentStream.setCharacterSpacing(charSpacing);
contentStream.showText(line);
contentStream.newLineAtOffset(0, LEADING);
}
}
private static List<String> parseLines(String text, float width) throws IOException {
List<String> lines = new ArrayList<String>();
int lastSpace = -1;
while (text.length() > 0) {
int spaceIndex = text.indexOf(' ', lastSpace + 1);
if (spaceIndex < 0)
spaceIndex = text.length();
String subString = text.substring(0, spaceIndex);
float size = FONT_SIZE * FONT.getStringWidth(subString) / 1000;
if (size > width) {
if (lastSpace < 0){
lastSpace = spaceIndex;
}
subString = text.substring(0, lastSpace);
lines.add(subString);
text = text.substring(lastSpace).trim();
lastSpace = -1;
} else if (spaceIndex == text.length()) {
lines.add(text);
text = "";
} else {
lastSpace = spaceIndex;
}
}
return lines;
}
}
Demo
The previous example generates the following PDF document.
References
- Apache PdfBox Official Website
- Apache PdfBox API Javadoc
- PDDocument JavaDoc
- PDPage JavaDoc
- PDPageContentStream JavaDoc