Thursday, July 2, 2020

Creating PDF in Java Using iText

In this post we’ll see how to create PDF in Java using iText library. Version of iText used here is 7.x.x which has different API from iText 5.x.x versions. We’ll see various examples of PDF creation using iText showing the use of classes in iText like PdfDocument, Document, PdfWriter, Paragraph, Table, PdfFont, PDFReader.

Note that iText is open source but the open source version is AGPL licensed which means you must distribute all source code, including your own product and web-based applications.

Maven dependecy

For using iText library you must add the following dependencies to your pom.xml file.

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <itext.version>7.1.3</itext.version>
</properties>
<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>kernel</artifactId>
  <version>${itext.version}</version>
</dependency>
<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>io</artifactId>
  <version>${itext.version}</version>
</dependency>
<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>layout</artifactId>
  <version>${itext.version}</version>
</dependency>
<!-- Java logging used-->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-jdk14</artifactId>
  <version>1.7.13</version>
</dependency>

This adds the following jars to the project’s class path.

kernel-7.1.3.jar
io-7.1.3.jar
layout-7.1.3.jar
slf4j-api-1.7.13.jar
slf4j-jdk14-1.7.13.jar

Following examples are listed in this post for generating PDF in Java using iText.

Creating PDF in Java using iText – Hello World

First lets see a simple iText PDF creation example where “Hello world” is written to the PDF using a Java program. Also the font and color for the text is specified before writing it to the PDF.

import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Text;

public class PDFCreation {
 public static final String DEST = "G://Test//hello_world.pdf";
 public static void main(String[] args) {
  PdfWriter writer;
  try {
   writer = new PdfWriter(new FileOutputStream(DEST));
   PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD);
   PdfDocument pdf = new PdfDocument(writer);
   Document document = new Document(pdf);
   Text text = new Text("Hello World with font and color")
         .setFont(font)
         .setFontColor(ColorConstants.BLUE);
   //Add paragraph to the document
   document.add(new Paragraph(text));
   document.close();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }   
 }
}

Creating PDF in Java using iText – Content in a Table

In this example we’ll see how to present content as a table in PDF using iText from your Java program. Example uses a bean class User, fields of object of type User are displayed in the table.

User.java

public class User {
  private String firstName;
  private String lastName;
  private String email;
  public User() {
   
  }
  public User(String firstName, String lastName, String email) {
   this.firstName = firstName;
   this.lastName = lastName;
   this.email = email;
  }
  
  public String getFirstName() {
   return firstName;
  }
  public void setFirstName(String firstName) {
   this.firstName = firstName;
  }
  public String getLastName() {
   return lastName;
  }
  public void setLastName(String lastName) {
   this.lastName = lastName;
  }
  public String getEmail() {
   return email;
  }
  public void setEmail(String email) {
   this.email = email;
  }
}

Class used for creating PDF showing data in a table.

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.netjs.Model.User;
import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.UnitValue;

public class PDFTableCreation {
  public static void main(String[] args) {
    new PDFTableCreation().createTablePDF("G://Test//table.pdf");
  }
    
  private void createTablePDF(String PDFPath){
    PdfWriter writer;
    try {
      writer = new PdfWriter(new FileOutputStream(PDFPath));
      PdfDocument pdf = new PdfDocument(writer);
      Document document = new Document(pdf, new PageSize(PageSize.A4));
      PdfFont headerFont = PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD);
      PdfFont cellFont = PdfFontFactory.createFont(StandardFonts.COURIER);
      // Create table with 3 columns of similar length
      Table table = new Table(new float[]{4, 4, 4});
      table.setWidth(UnitValue.createPercentValue(100));
      // adding header
      table.addHeaderCell(new Cell().add(new Paragraph(
              "First Name").setFont(headerFont)));
      table.addHeaderCell(new Cell().add(new Paragraph(
              "Last Name").setFont(headerFont)));
      table.addHeaderCell(new Cell().add(new Paragraph(
              "Email").setFont(headerFont)));
      List<User> users = getListOfUsers();
      // adding rows
      for(User user : users) {
        table.addCell(new Cell().add(new Paragraph(
             user.getFirstName()).setFont(cellFont)));
        table.addCell(new Cell().add(new Paragraph(
             user.getLastName()).setFont(cellFont)));
        table.addCell(new Cell().add(new Paragraph(
             user.getEmail()).setFont(cellFont)));
      }
      document.add(table);
      document.close();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }    
  }
    
  // Dummy method for adding List of Users
  private List<User> getListOfUsers() {
    List<User> users = new ArrayList<User>();
    users.add(new User("Jack", "Reacher", "abc@xyz.com"));
    users.add(new User("Remington", "Steele", "rs@cbd.com"));
    users.add(new User("Jonathan", "Raven", "jr@sn.com"));
    return users;
  }
}

Created PDF

Creating table in PDF Using iText- Java

Generating PDF in Java using iText – Adding background image to PDF

public class PDFCreation {
  public static final String DEST = "G://Test//image.pdf";
  public static void main(String[] args) {
    new PDFCreation().addImageToPDF(DEST);
  }
 
  private void addImageToPDF(String PDFPath){
    PdfWriter writer;
    try {
      writer = new PdfWriter(new FileOutputStream(PDFPath));
      PdfDocument pdfDoc = new PdfDocument(writer);
      Document document = new Document(pdfDoc);
      PageSize pageSize = new PageSize(PageSize.A4).rotate();
   
      PdfCanvas canvas = new PdfCanvas(pdfDoc.addNewPage());
      // creating image data instance by passing the path to image
      ImageData img = ImageDataFactory.create("resources//netjs.png");
      canvas.saveState();
      // graphic state
      PdfExtGState state = new PdfExtGState();
      state.setFillOpacity(0.2f);
      canvas.setExtGState(state);
      canvas.addImage(img, 20, 650, pageSize.getWidth()/2, false);
      canvas.restoreState();
      document.add(new Paragraph("Adding image to PDF Example"));      
      document.close();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
  }
}

Created PDF

adding image to PDF in Java

Creating PDF in Java using iText – Adding image to PDF

If you want to add image to PDF.

public class PDFCreation {
  public static final String DEST = "G://Test//image.pdf";

  public static void main(String[] args) {
    new PDFCreation().addImageToPDF(DEST);
  }
 
  private void addImageToPDF(String PDFPath){
    PdfWriter writer;
    try {
      // creating image data instance by passing the path to image
      Image image = new Image(ImageDataFactory.create("resources//netjs.png"));
      writer = new PdfWriter(new FileOutputStream(PDFPath));
      PdfDocument pdfDoc = new PdfDocument(writer);
      Document document = new Document(pdfDoc);       
      document.add(new Paragraph("Adding image to PDF Example"));
      document.add(image);      
      document.close();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
  }
}

Creating PDF in Java using iText – Adding List to PDF

If you want to show a list of items in PDF then you can create a List and add ListItems to it. Symbol used for marking ListItems can be passed using setListSymbol() method. There is an Enum ListNumberingType that holds possible values for list item prefix. You can also pass a unicode character.

import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.List;
import com.itextpdf.layout.element.ListItem;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.ListNumberingType;

public class PDFCreation {
  public static void main(String[] args) {
    new PDFCreation().addImageToPDF("G://Test//list.pdf");
  }

  private void addImageToPDF(String PDFPath){
    PdfWriter writer;
    try {
      writer = new PdfWriter(new FileOutputStream(PDFPath));
      PdfDocument pdfDoc = new PdfDocument(writer);
      Document document = new Document(pdfDoc);       
      document.add(new Paragraph("Choices Are (Using English Letters)"));
            // for offset (space from the left)
      List list = new List().setSymbolIndent(14) 
                            .setListSymbol(ListNumberingType.ENGLISH_LOWER);
       
      // Add ListItem objects
      list.add(new ListItem("Aerobic"))
          .add(new ListItem("Anaerobic"))
          .add(new ListItem("Flexibility Training"));
      // Add the list
      document.add(list);
      
      document.add(new Paragraph("Choices Are (Using Roman upper)"));
      list = new List()
           .setSymbolIndent(14)
           .setListSymbol(ListNumberingType.ROMAN_UPPER);
      // Add ListItem objects
      list.add(new ListItem("Aerobic"))
          .add(new ListItem("Anaerobic"))
          .add(new ListItem("Flexibility Training"));
      // Add the list
      document.add(list);
      
      document.add(new Paragraph("Choices Are (Using bullet symbol)"));
      list = new List()
           .setSymbolIndent(14) 
           .setListSymbol("\u2022"); // Passing unicode for bullet
      // Add ListItem objects
      list.add(new ListItem("Aerobic"))
          .add(new ListItem("Anaerobic"))
          .add(new ListItem("Flexibility Training"));
      // Add the list
      document.add(list);            
      document.close();         
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
  }
}

Created PDF

creating PDF with list items using Java

Creating PDF in Java using iText – Rendered to browser as web response

If you want to render PDF to the browser in your web project using the HTTPResponse, then you can do it as follows. PDFWriter constructor also accepts an OutputStream as parameter. If you want to write a web application, then you can create a ServletOutputStream.

PdfWriter writer;
try{
  response.setContentType("application/pdf");
  writer = new PdfWriter(response.getOutputStream());
  PdfDocument pdfDoc = new PdfDocument(writer);
  Document document = new Document(pdfDoc); 
  PdfFont titleFont = PdfFontFactory.createFont(StandardFonts.TIMES_BOLD);
  PdfFont textFont = PdfFontFactory.createFont(StandardFonts.COURIER);
  document.add(new Paragraph("PDF generated in Web")
          .setFont(titleFont).setFontColor(ColorConstants.RED)
          .setTextAlignment(TextAlignment.CENTER));
  Paragraph p = new Paragraph("This is the text of the PDF created using iText library and 
               rendered to the browser using a Servlet.");
  document.add(p.setFont(textFont).setFontColor(ColorConstants.ORANGE));
  document.close();
}catch(Exception e){
  e.printStackTrace();
}

Created PDF

rendering PDF in web application

Creating PDF in Java using iText – Password protected PDF with user permissions

You can encrypt the created PDF, there are two types of passwords you can set-

  • User password
  • Owner password

The userPassword and the ownerPassword can be null or have zero length.

You can also set user permissions (operation permitted when the PDF document is opened with the user password). Available user permissions are defined in the EncryptionConstants class.

  • EncryptionConstants.ALLOW_PRINTING
  • EncryptionConstants.ALLOW_MODIFY_CONTENTS
  • EncryptionConstants.ALLOW_COPY
  • EncryptionConstants.ALLOW_MODIFY_ANNOTATIONS
  • EncryptionConstants.ALLOW_FILL_IN
  • EncryptionConstants.ALLOW_SCREENREADERS
  • EncryptionConstants.ALLOW_ASSEMBLY
  • EncryptionConstants.ALLOW_DEGRADED_PRINTING

The permissions can be combined by ORing them, as example (EncryptionConstants.ALLOW_PRINTING | EncryptionConstants.ALLOW_MODIFY_CONTENTS)

Example code

For this code to run you will need bouncycastle jar. Maven dependency for it is as follows-

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.60</version>
</dependency>

which adds the following jar-

  • bcprov-jdk15on-1.60.jar
public class PDFWithPwd {

  public static void main(String[] args) {
    new PDFWithPwd().changePermissions("G://Test//Permissions.pdf");
  }
 
  private void changePermissions(String pdfPath) {
    final String USER_PWD="user";
    final String OWNER_PWD="owner";
    try {
      PdfWriter writer = new PdfWriter(pdfPath, new WriterProperties()
                  .setStandardEncryption(USER_PWD.getBytes(), OWNER_PWD.getBytes(), 
                   EncryptionConstants.ALLOW_PRINTING, 
                   EncryptionConstants.ENCRYPTION_AES_128 | EncryptionConstants.DO_NOT_ENCRYPT_METADATA));
      PdfDocument pdfDoc = new PdfDocument(writer);
      Document document = new Document(pdfDoc); 
      document.add(new Paragraph("This PDF is password protected and its content can’t be copied by user."));
      document.close();
    }catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
  }
}

If you open the created PDF it will ask for the password. If you open it using the user password then you won’t be able to copy the content as per the user permission settings.

password protected PDF in Java using iText

That's all for this topic Creating PDF in Java Using iText. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. How to Create PDF From XML Using Apache FOP
  2. Spring MVC PDF Generation Example
  3. How to Create Password Protected Zip File in Java
  4. Print Odd-Even Numbers Using Threads And wait-notify - Java Program
  5. Converting double to int - Java Program

You may also like-

  1. How to Count Lines in a File - Java Program
  2. Creating Tar File And GZipping Multiple Files - Java Program
  3. Comparing Enum to String - Java Program
  4. How to Remove Duplicate Elements From an Array - Java Program
  5. Difference Between Comparable and Comparator in Java
  6. SerialVersionUID And Versioning in Java Serialization
  7. Difference Between Abstract Class And Interface in Java
  8. Dependency Injection in Spring Framework