We have already seen examples of generating PDF in Java using iText and generating PDF in Java using OpenPDF. In this post we’ll learn about another option for generating PDF in Java using Apache PDFBox.
Apache PDFBox library
The Apache PDFBox library (https://pdfbox.apache.org/) is an open source Java tool for working with PDF documents. This project allows creation of new PDF documents, manipulation of existing documents and the ability to extract content from documents.
Maven Dependency for PDFBox
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.13</version> </dependency>
Examples of PDF generation using PDFBox and Java given in this post.
HelloWorld PDF using Java and PDFBox
We’ll start with creating a simple HelloWorld PDF which also shows font and text color settings for the content. For creating a PDF using PDFBox and adding content to it you need to do the following steps.
- Create a new PDF document using PDDocument class. Instantiating this class you can create an empty PDF document.
- Add page to that empty PDF document using PDPage class. This adds a blank page to the PDF document.
- Write to that page using PDPageContentStream class.
- You need to call beginText() method of the PDPageContentStream class before starting text operations and endText() method to end text operations.
- For setting the starting position for the line use newLineAtOffset() method. Original position on a page is at the bottom left corner, you need to bring it to the position from where you want the text to start.
import java.awt.Color; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; public class HelloWorldPDF { public static final String CREATED_PDF = "F://knpcode//result//PDFBox//HelloWorld.pdf"; public static void main(String[] args) { try { PDDocument pdfDoc = new PDDocument(); PDPage firstPage = new PDPage(); // add page to the PDF document pdfDoc.addPage(firstPage); // For writing to a page content stream try(PDPageContentStream cs = new PDPageContentStream(pdfDoc, firstPage)){ cs.beginText(); // setting font family and font size cs.setFont(PDType1Font.COURIER, 15); // color for the text cs.setNonStrokingColor(Color.RED); // starting position cs.newLineAtOffset(20, 750); cs.showText("Hello World PDF created using PDFBox"); // go to next line cs.newLine(); cs.endText(); } // save PDF document pdfDoc.save(CREATED_PDF); pdfDoc.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Adding Multiple lines and multi-line text to PDF using PDFBox
If you have to add multiple lines to PDF and there is a text that spans multiple lines then the extra methods that you need to use are-
- Use newLine() method of the PDPageContentStream class to move to the start of the next line of text. This requires the leading to have been set which can be done using setLeading() method.
- For text spanning multiple lines there is no support in PDFBox so you need to do that calculation using the allowed width for the page and using the font size and width to calculate the space taken by each word in the line.
import java.awt.Color; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDType1Font; public class CreatePDF { public static final String CREATED_PDF = "F://knpcode//result//PDFBox//Content.pdf"; public static void main(String[] args) { try { PDDocument pdfDoc = new PDDocument(); PDPage firstPage = new PDPage(); // add page to the PDF document pdfDoc.addPage(firstPage); // For writing to a page content stream try(PDPageContentStream cs = new PDPageContentStream(pdfDoc, firstPage)){ cs.beginText(); cs.setFont(PDType1Font.COURIER, 15); cs.newLineAtOffset(20, 750); cs.setLeading(12); cs.showText("Hello World PDF created using PDFBox"); cs.newLine(); String text = "This text spans multiple lines and it is added to the PDF dcoument generated using PDFBox"; showMultiLineText(text, 20, 762, 580, firstPage, cs, PDType1Font.COURIER, 15); cs.setFont(PDType1Font.TIMES_BOLD, 15); cs.setNonStrokingColor(Color.RED); cs.showText("While adding this line font and color settings are changed."); cs.newLine(); cs.endText(); } pdfDoc.save(CREATED_PDF); pdfDoc.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void showMultiLineText(String text, int x, int y, int allowedWidth, PDPage page, PDPageContentStream contentStream, PDFont font, int fontSize) throws IOException { List<String> lines = new ArrayList<String>(); String line = ""; // split the text on spaces String[] words = text.split(" "); for(String word : words) { if(!line.isEmpty()) { line += " "; } // check if adding the word to the line surpasses the width of the page int size = (int) (fontSize * font.getStringWidth(line + word) / 1000); if(size > allowedWidth) { // if line + word surpasses the width of the page, add the line without the current word lines.add(line); // start new line with the current word line = word; } else { // if line + word fits the page width, add the current word to the line line += word; } } lines.add(line); for(String ln : lines) { System.out.println("Line- " + ln); contentStream.showText(ln); contentStream.newLine(); } } }
Adding text to an existing PDF using PDFBox
If you want to add a new page to an existing PDF document then you can load existing PDF using load() method of the PDDocument class.
import java.io.File; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; public class CreatePDF { public static final String CREATED_PDF = "F://knpcode//result//PDFBox//Content.pdf"; public static void main(String[] args) { try { // Load existing PDF PDDocument pdfDoc = PDDocument.load(new File(CREATED_PDF)); PDPage page = new PDPage(); // add page to the PDF document pdfDoc.addPage(page); // For writing to a page content stream try(PDPageContentStream cs = new PDPageContentStream(pdfDoc, page)){ cs.beginText(); cs.setFont(PDType1Font.TIMES_ROMAN, 12); cs.newLineAtOffset(20, 750); cs.setLeading(12); cs.showText("This is a new page added to an existing PDF document"); cs.newLine(); cs.endText(); } pdfDoc.save(CREATED_PDF); pdfDoc.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Converting text file to PDF using PDFBox
In the Java example there is a text file (Test.txt) which is converted to a PDF using PDFBox. In this example we’ll also cover the scenario where apart from text that may span multiple lines there is content that may span multiple pages in the PDF. In PDFBox each new page has to be created and added to the document before content can be written to that page.
For content in multiple pages in PDFBox you need to keep track of the height of the content in the page and when that height exceeds the allowed height add a new page. Allowed height may vary based on the type of the document, in this example A4 page size is considered.
Current height is calculated by adding line height to current height for each line written to the PDF document.
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDType1Font; public class CreatePDF { // Text file that has to be converted public static final String SOURCE_FILE = "F://knpcode//result//Test.txt"; public static final String CREATED_PDF = "F://knpcode//result//PDFBox//Content.pdf"; static double currentHeight = 0; static PDPageContentStream cs = null; public static void main(String[] args) { try { PDDocument pdfDoc = new PDDocument(); // for text file BufferedReader br = new BufferedReader(new FileReader(SOURCE_FILE)); PDPage page = new PDPage(); // add page to the PDF document pdfDoc.addPage(page); String line; cs = new PDPageContentStream(pdfDoc, page); cs.beginText(); cs.setFont(PDType1Font.TIMES_ROMAN, 12); cs.newLineAtOffset(20, 750); cs.setLeading(12); // Read text file line by line while ((line = br.readLine()) != null) { System.out.println("Line-- " + line); showMultiLineText(pdfDoc, line, 20, 750, 580, 820, page, PDType1Font.TIMES_ROMAN, 15); } if(cs != null) { cs.endText(); cs.close(); } pdfDoc.save(CREATED_PDF); br.close(); pdfDoc.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * * @param pdfDoc * @param text * @param x * @param y * @param allowedWidth - allowed width for the line before content goes to next line * @param allowedHeight - Allowed height for the page before another page is added * @param page * @param font * @param fontSize * @throws IOException */ private static void showMultiLineText(PDDocument pdfDoc, String text, int x, int y, int allowedWidth, double allowedHeight, PDPage page, PDFont font, int fontSize) throws IOException { List<String> lines = new ArrayList<String>(); String line = ""; // split the text on spaces String[] words = text.split(" "); for(String word : words) { if(!line.isEmpty()) { line += " "; } // check if adding the word to the line surpasses the width of the page int size = (int) (fontSize * font.getStringWidth(line + word) / 1000); if(size > allowedWidth) { // if line + word surpasses the width of the page, add the line without the current word lines.add(line); // start new line with the current word line = word; } else { // if line + word fits the page width, add the current word to the line line += word; } } lines.add(line); for(String ln : lines) { System.out.println("Line- " + ln); // for each line add line height to current height // line height = 1.2 * fontSize is taken here currentHeight = currentHeight + 1.2 * fontSize; System.out.println("currentHeight " + currentHeight); if(currentHeight >= allowedHeight) { System.out.println("adding new page " + currentHeight); // When current height is more than allowed height for the page // create a new page page = new PDPage(); // add page to the PDF document pdfDoc.addPage(page); // reset currentHeight currentHeight = 0; cs.endText(); cs.close(); cs = new PDPageContentStream(pdfDoc, page); cs.beginText(); cs.setFont(PDType1Font.TIMES_ROMAN, 12); cs.newLineAtOffset(20, 750); cs.setLeading(12); } cs.showText(ln); cs.newLine(); } } }
Adding image to a PDF documents using PDFBox
To add an image to PDF document, PDImageXObject class in PDFBox library is used.
import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; public class PDFImage { public static final String CREATED_PDF = "F://knpcode//result//PDFBox//Image.pdf"; public static void main(String[] args) { PDDocument pdfDoc; try { pdfDoc = new PDDocument(); PDPage page = new PDPage(); pdfDoc.addPage(page); // Create image object using the image location PDImageXObject image = PDImageXObject.createFromFile("images//PDFBox image.png", pdfDoc); try(PDPageContentStream cs = new PDPageContentStream(pdfDoc, page)){ cs.beginText(); // setting font family and font size cs.setFont(PDType1Font.HELVETICA_BOLD, 14); // starting position in the page cs.newLineAtOffset(20, 700); cs.setLeading(12); cs.showText("In this page an image is added using PDFBox"); cs.newLine(); cs.endText(); cs.drawImage(image, 20, 550); } pdfDoc.save(CREATED_PDF); pdfDoc.close(); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
That's all for the topic Generating PDF in Java Using PDFBox Tutorial. If something is missing or you have something to share about the topic please write a comment.
You may also like
- Convert HTML to PDF in Java Using Openhtmltopdf, PDFBox
- Password Protected PDF Using OpenPDF in Java
- Arrange Given Numbers to Form The Biggest Number in Java
- How to Split a String in Java
- ArrayList Internal Implementation in Java
- AtomicInteger in Java With Examples
- Java Continue Statement With Examples
- super() in Python With Examples
No comments:
Post a Comment