Last active
September 9, 2015 17:25
-
-
Save JoelGeraci-Datalogics/1680b6d84e42742555e0 to your computer and use it in GitHub Desktop.
This sample will populate a PDF form based on data in a MySQL database including image data. One PDF per record will be created. There are 9 records.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright Datalogics, Inc. 2015 | |
*/ | |
package pdfjt.cookbook.forms; | |
import java.awt.image.BufferedImage; | |
import java.io.InputStream; | |
import java.net.URL; | |
import java.sql.DriverManager; | |
import java.sql.Connection; | |
import java.sql.ResultSet; | |
import java.sql.ResultSetMetaData; | |
import java.util.HashMap; | |
import javax.imageio.ImageIO; | |
import pdfjt.util.SampleFileServices; | |
import com.adobe.fontengine.font.Font; | |
import com.adobe.internal.io.ByteReader; | |
import com.adobe.internal.io.ByteWriter; | |
import com.adobe.internal.io.InputStreamByteReader; | |
import com.adobe.pdfjt.pdf.document.PDFDocument; | |
import com.adobe.pdfjt.pdf.document.PDFOpenOptions; | |
import com.adobe.pdfjt.pdf.document.PDFSaveFullOptions; | |
import com.adobe.pdfjt.pdf.graphics.font.PDFFont; | |
import com.adobe.pdfjt.pdf.graphics.xobject.PDFXObjectForm; | |
import com.adobe.pdfjt.pdf.interactive.annotation.PDFAnnotationWidget; | |
import com.adobe.pdfjt.pdf.interactive.annotation.PDFAppearance; | |
import com.adobe.pdfjt.pdf.interactive.forms.PDFField; | |
import com.adobe.pdfjt.pdf.interactive.forms.PDFFieldList; | |
import com.adobe.pdfjt.pdf.interactive.forms.PDFFieldNode; | |
import com.adobe.pdfjt.services.ap.AppearanceService; | |
import com.adobe.pdfjt.services.ap.spi.APContext; | |
import com.adobe.pdfjt.services.ap.spi.APResources; | |
import com.adobe.pdfjt.services.imageconversion.ImageManager; | |
import com.adobe.pdfjt.services.xobjhandler.XObjectUseOptions; | |
import com.mysql.jdbc.Statement; | |
/** | |
* This sample will populate a PDF form based on data in a MySQL database | |
* including image data. One PDF per record will be created. There are 9 | |
* records. | |
*/ | |
public class FillFormsWithImagesFromSQL { | |
private static final String inputPDF = "http://dev.datalogics.com/cookbook/forms/BlankInputFormWithImage.pdf"; | |
private static final String outputDir = "cookbook/Forms/output/"; | |
private static final String databaseConnection = "jdbc:mysql://dev.datalogics.com:3306/datalogi_northwind"; | |
static public void main(String[] args) throws Exception { | |
/* | |
* Check if the JDBC Driver is available first. | |
*/ | |
try { | |
Class.forName("com.mysql.jdbc.Driver"); | |
} catch (ClassNotFoundException e) { | |
System.out.println("No MySQL JDBC Driver"); | |
e.printStackTrace(); | |
return; | |
} | |
/* | |
* Try to connect to the database before we even get the PDF file. | |
*/ | |
Connection connection = DriverManager.getConnection(databaseConnection, "datalogi_demo", "4ObLvP1NXo6U9gCxmU"); | |
if (connection != null) { | |
/* | |
* Get the PDF File | |
*/ | |
InputStream fis = new URL(inputPDF).openStream(); | |
ByteReader byteReader = new InputStreamByteReader(fis); | |
PDFDocument pdfDocument = PDFDocument.newInstance(byteReader, PDFOpenOptions.newInstance()); | |
/* | |
* Get the field list from the interactive form object | |
*/ | |
PDFFieldList fieldList = pdfDocument.getInteractiveForm().getChildren(); | |
/* | |
* Get the resources necessary to generate the field appearances | |
* after we add the data. | |
*/ | |
APResources apResources = new APResources(pdfDocument.getCosDocument().getOptions().getFontSet(), pdfDocument.getCosDocument() | |
.getOptions().getDocLocale(), new HashMap<Font, PDFFont>()); | |
APContext apContext = new APContext(apResources, true, null); | |
/* | |
* Make sure the output directory is created so we can save the new | |
* PDF files. | |
*/ | |
SampleFileServices.createDir(outputDir); | |
/* | |
* Get all the records in the Employees database | |
*/ | |
Statement statement = (Statement) connection.createStatement(); | |
ResultSet resultSet = statement.executeQuery("SELECT * FROM Employees;"); | |
/* | |
* Get the number of columns (fields) in the result set. | |
*/ | |
ResultSetMetaData metaData = resultSet.getMetaData(); | |
int numColumns = metaData.getColumnCount(); | |
/* | |
* Iterate through the result set. If a field name matches a column | |
* name, populate the field with the data. | |
*/ | |
while (resultSet.next()) { | |
for (int i = 1; i < numColumns + 1; i++) { | |
String fieldName = metaData.getColumnLabel(i); | |
PDFFieldNode pdfFieldNode = fieldList.getFieldNamed(fieldName); | |
if (pdfFieldNode != null) { | |
/* | |
* A PDF field with the same name as the column exists | |
* in the form. | |
*/ | |
String fieldType = metaData.getColumnTypeName(i); | |
switch (fieldType) { | |
case "VARCHAR": | |
if (resultSet.getObject(fieldName) == null) { | |
pdfFieldNode.setStringValue(""); | |
} else { | |
pdfFieldNode.setStringValue(resultSet.getString(fieldName)); | |
} | |
/* | |
* Set the appearance on a field by field basis. | |
* Because we are setting the appearance for the | |
* button field in code, we don't want the toolkit | |
* to generate all appearances at the document level | |
* because our button appearance would get | |
* overwritten. | |
*/ | |
AppearanceService.generateFieldAppearances(pdfDocument, PDFField.getInstance(pdfFieldNode.getCosObject()), | |
apContext, null); | |
break; | |
/* | |
* In this particular table, the only column with a type | |
* of "LONGBLOG" is the Photo. You may want to add more | |
* verification here for your own databases. | |
*/ | |
case "LONGBLOB": | |
if (resultSet.getObject(fieldName) != null) { | |
/* | |
* Create a PDFField from a terminal | |
* PDFFieldNode so we can get it's | |
* annotations. | |
*/ | |
PDFField pdfField = PDFField.getInstance(pdfFieldNode.getCosObject()); | |
// Is this field a button? | |
if (pdfField.getFieldType().getValue().asString().matches("Btn")) { | |
/* Read the database blob into a | |
* BufferedImage | |
*/ | |
BufferedImage bufferedImage = ImageIO.read(resultSet.getBinaryStream(fieldName)); | |
/* | |
* Convert the image to an object that the | |
* toolkit can use to set the appearance of | |
* a button | |
*/ | |
PDFXObjectForm pdfXObjectForm = ImageManager.getXObjPDFImage(pdfDocument, bufferedImage, | |
new XObjectUseOptions()); | |
/* | |
* The "Photo" field is read-only so it will | |
* only have a "Normal" appearance so we can | |
* just get the first one. | |
*/ | |
PDFAnnotationWidget fieldWidget = (PDFAnnotationWidget) pdfField.getAnnotationsIterator().next(); | |
/* | |
* Create a new appearance and use it to set | |
* the "Normal" appearance for the widget. | |
*/ | |
PDFAppearance pdfAppearance = PDFAppearance.newInstance(pdfDocument); | |
pdfAppearance.setNormalAppearance(pdfXObjectForm); | |
fieldWidget.setAppearance(pdfAppearance); | |
} | |
} | |
break; | |
} | |
} | |
} | |
/* | |
* Write out the file | |
*/ | |
String outputFileName = "NewForm_" + resultSet.getString("EmployeeID") + ".pdf"; | |
ByteWriter outputFile = SampleFileServices.getRAFByteWriter(outputDir + outputFileName); | |
pdfDocument.save(outputFile, PDFSaveFullOptions.newInstance()); | |
System.out.println("Created: " + outputFileName); | |
} | |
connection.close(); | |
} else { | |
System.out.println("Couldn't connect to table."); | |
return; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment