Filling Values in Editable PDF Forms in Java
Filling out PDF forms programmatically in Java is a common requirement for many applications. Whether you're handling user-generated data or automating data entry, Apache PDFBox is a powerful Java library that can simplify the process. In this tutorial, we'll explore how to use Apache PDFBox library to fill values into editable PDF forms seamlessly.
Apache PDFBox is an open source Java library that helps to work with PDF documents. PDFBox library allows to create new PDF documents, updating of existing PDF documents, and is also capable of extracting content from documents.
Follow the steps below to fill values in an editable PDF form and generate a new PDF document in Java:
- To begin using Apache PDFBox for PDF form filling, you'll need to include the PDFBox library in your Java project. You can add the library to your project from the Maven repository:
- To fill out an editable PDF form and create a new PDF document, use the code as demonstrated in the example below:
- Sometimes, you may need to fill data into editable PDF forms and send the final generated document to a remote computer for download via a Spring Boot REST API. In such cases, you will need the final document in the form of byte streams, as demonstrated in the example below:
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>3.0.0</version> </dependency>
implementation group: 'org.apache.pdfbox', name: 'pdfbox', version: '3.0.0'
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
public class Example {
public static void main(String[] args) {
// Loading editable pdf file
File input = new File("C:\\Users\\documents\\editable-form.pdf");
try (PDDocument pdfDoc = Loader.loadPDF(input);) {
// Accessing form fields
PDDocumentCatalog docCatalog = pdfDoc.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
// Filling form fields
PDField firstnameField = acroForm.getField("first_name");
firstnameField.setValue("Danny");
PDField lastnameField = acroForm.getField("last_name");
lastnameField.setValue("Clark");
PDField registrationDateField = acroForm.getField("registration_date");
registrationDateField.setValue(String.valueOf(LocalDate.now()));
PDField registrationFeeField = acroForm.getField("registration_fee");
registrationFeeField.setValue(String.valueOf(100.50));
/* make the final document uneditable */
acroForm.flatten();
/* generate a new pdf file and save it to the given location */
pdfDoc.save(new File("C:\\Users\\documents\\final-document.pdf"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import jakarta.servlet.http.HttpServletResponse;
@RestController
@RequestMapping(path = "/files")
public class ControllerPDFDownload {
@GetMapping(value = "/pdf-download")
public ResponseEntity<StreamingResponseBody> downloadFile(HttpServletResponse response,
@PathVariable(name = "fileId", required = true) String fileId) {
StreamingResponseBody streamResponseBody = outputStream -> {
// Get filename from database using fileId from the request
String filename = "my-editable-form.pdf";
String fileLocation = "C:\\documents\\";
String filePathName = fileLocation.concat(filename);
// Loading editable pdf file
File input = new File(filePathName);
try (PDDocument pdfDoc = Loader.loadPDF(input);) {
// Accessing form fields
PDDocumentCatalog docCatalog = pdfDoc.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
ByteArrayOutputStream out = new ByteArrayOutputStream();
// Filling form fields
PDField firstnameField = acroForm.getField("first_name");
firstnameField.setValue("example-firstname");
PDField lastnameField = acroForm.getField("last_name");
lastnameField.setValue("example-lastname");
PDField registrationDateField = acroForm.getField("registration_date");
registrationDateField.setValue(String.valueOf(LocalDate.now()));
PDField registrationFeeField = acroForm.getField("registration_fee");
registrationFeeField.setValue(String.valueOf(100.50));
/* make the final document uneditable */
acroForm.flatten();
pdfDoc.save(out);
// Getting the size of the file from ByteArrayOutputStream
long fileLength = out.size();
response.setContentLength((int) fileLength);
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
// Write the content of the ByteArrayOutputStream to the outputStream
out.writeTo(outputStream);
} catch (IOException e) {
e.printStackTrace();
}
};
return ResponseEntity.ok(streamResponseBody);
}
}
In this code, the StreamingResponseBody streams the content of the ByteArrayOutputStream (out) to the response output stream. This is a common way to handle streaming large responses in web applications.