This is an sample of a CustomProcess for Qoppa’s PDF Automation Server.

This job takes in a PDF document, splits it into multiple 2 page PDFs, identifies text strings based on their location on the first page of each PDF and finally email the PDF to various addresses depending on the value of the text found.

In this example, 4 text strings / fields are identified on the first page of each split PDF based on their rectangular location on the page: a department name, a record number, date and time. Using Qoppa’s jPDFProcess library, it is simple to identify text contained in a rectangle on PDF page using to code below:

// get first Page in PDF Document
PDFPage page = pdfDoc.getPage(0);
// Get text contained within a rectangle in a PDF page 
TextSelection selection = page.getTextInArea(rectangle);

Based on the department name, the resulting PDF will be emailed to a different email address for processing.

If the process fails to identify any of the field on the page, an error email is sent out.

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.logging.Level;
 
import com.qoppa.pas.api.CustomProcess;
import com.qoppa.pas.api.JobStatus;
import com.qoppa.pas.api.ServerContext;
import com.qoppa.pas.api.WorkingBundle;
import com.qoppa.pas.api.service.EmailService;
import com.qoppa.pas.api.service.EmailService.Email;
import com.qoppa.pas.api.service.LogService;
import com.qoppa.pdf.PDFException;
import com.qoppa.pdf.TextSelection;
import com.qoppa.pdfProcess.PDFDocument;
import com.qoppa.pdfProcess.PDFPage;
 
public class SplitAndEmail implements CustomProcess
{
// Change this to always show the "search" rectangles 
// on the output documents so you can identify them visually 
private static final boolean DEBUG_RECTANGLES = false;
 
// Define the rectangles for the text / fields to be identified on the page 
// These coordinates are in 72 dpi.
	private static final Rectangle RECT_DEPT = new Rectangle(90, 133, 250, 10);
	private static final Rectangle RECT_RECORD_NUMBER = new Rectangle(220, 298, 80, 10);
	private static final Rectangle RECT_DATE = new Rectangle(220, 320, 90, 10);
	private static final Rectangle RECT_TIME = new Rectangle(400, 320, 70, 10);
 
	// This is the formatter for the date/time filenames
	// Change this to meet your needs. Look at
	// https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
	private static final SimpleDateFormat FORMAT_DATE = new SimpleDateFormat("EEEE MMM d yyyy 'at' h_mm_ss a");
 
	// The path to the output folder
	private static final String OUTPUT_PATH = "C:\\PDFOutPut\\";
 
	// SMTP Server
	private static final String SMTP_SERVER = "mail.company.com";
 
	// Email list
	private static final String FROM_EMAIL = "sender.email@company.com";
	private static final String CC_EMAIL = "ccemail@company.com";
 
	private static final String ERROR_FROM_EMAIL = "FailedNotice@company.com";
	private static final String ERROR_TO_EMAIL = "itguy@company.com";
 
	private static Hashtable<String, String> DEPARTMENT_SENDLIST = new Hashtable<String, String>();
	static
	{
		DEPARTMENT_SENDLIST.put("DPT 1", "dept1@company.com");
		DEPARTMENT_SENDLIST.put("DPT 2", "dept2@company.com");
		DEPARTMENT_SENDLIST.put("DEPT 3", "dept3@company.com");
	}
 
	@Override
	public boolean process(ServerContext serverContext, JobStatus jobStatus, WorkingBundle bundle)
	{
		// set up log service
		LogService logService = serverContext.createLogService();
 
		// set up email service 
		EmailService emailService = serverContext.createEmailService();
		emailService.setSMTPServer(SMTP_SERVER);
		emailService.setSMTPFromName(FROM_EMAIL);
 
           // get the PDF document from the bundle
		PDFDocument pdfDoc = bundle.getPDFDocument();
 
		// Loop through the pages, incrementing pageIndex by 2
		for (int pageIndex = 0; pageIndex < pdfDoc.getPageCount(); pageIndex += 2)
		{
			String filePath = null;
			try
			{
				logService.log(Level.INFO, "Processing page " + (pageIndex + 1) + " of " + pdfDoc.getPageCount());
 
				try
				{
					Thread.sleep(1500);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
 
				// Create a new document with 2 next pages
				PDFDocument singleDoc = new PDFDocument();
				singleDoc.appendPage(pdfDoc.getPage(pageIndex));
 
				singleDoc.appendPage(pdfDoc.getPage(pageIndex + 1));
				}
 
				// Get the first page
				PDFPage page = singleDoc.getPage(0);
 
// Read information from page
				String department = getTextOnPage(page, RECT_DEPT);
				String recordNumber = getTextOnPage(page, RECT_RECORD_NUMBER);
				String date = getTextOnPage(page, RECT_DATE);
				String time = getTextOnPage(page, RECT_TIME);
 
				if (recordNumber == null)
				{
					recordNumber = "MISSING_RECORD_NUMBER";
				}
 
				// Define the file name, in this case a combination of the record number and the current date
				Date now = new Date();
				String fileName = recordNumber + " " + FORMAT_DATE.format(now) + ".pdf";
 
				// Save the document
				filePath = OUTPUT_PATH + fileName;
				singleDoc.saveDocument(filePath);
 
// send an error email in case we were unable to identify the text / fields on the document 
				if (department == null || recordNumber == null || date == null || time == null)
				{
					// ERROR - missing data
					StringBuffer message = new StringBuffer("File " + fileName + " is missing data. Page " + (pageIndex + 1) + " of " + bundle.getInitialFileName());
					sendErrorEmail(emailService, logService, message.toString(), filePath, fileName);
				}
				else
				{
					// Make sure we can match up the department to the email info
					String sendList = DEPARTMENT_SENDLIST.get(department.toUpperCase());
					// send error email if we could not match the department
					if (sendList == null)
					{
						// ERROR
						StringBuffer message = new StringBuffer("Unable to match department for file " + fileName + ". Page " + (pageIndex + 1) + " of " + bundle.getInitialFileName());
						sendErrorEmail(emailService, logService, message.toString(), filePath, fileName);
					}
					// send email to appropriate email address if we were able to match the department
					else
					{
						// Add the CC_EMAIL
						sendList = sendList + "," + CC_EMAIL;
 
						Email email = emailService.createNewEmail();
// set your email subject
						email.setSubject("RECORD NUMBER " + recordNumber + " FOR DEPT " + department.toUpperCase());
// add your content
						email.setMessage("Your content here");
						email.setSendList(sendList);
// 2 page document is attached to the email 
						email.addAttachment(fileName, new File(filePath));
 
						// Send the Email
						emailService.sendEmail(email);
					}
				}
			}
			catch (PDFException ex)
			{
				logService.log(Level.SEVERE, "PDFExeption processing document", ex);
			}
			catch (IOException ex)
			{
				logService.log(Level.SEVERE, "IOException processing document. Unable to save document " + filePath, ex);
			}
		}
 
		return true;
	}
 
// this is the method using Qoppa's PDF library jPDFProcess
// to identify text in a PDF document given a specific 
// rectangle on the page
	private String getTextOnPage(PDFPage page, Rectangle rectangle) throws PDFException
	{
		// Get the text for the page
		TextSelection selection = page.getTextInArea(rectangle);
 
		String text = null;
 
		if (selection != null && selection.getText().trim().length() > 0)
		{
			text = selection.getText().trim();
		}
 
		// This will draw a red rectangle around the search area on the PDF page
		if (DEBUG_RECTANGLES || text == null)
		{
			Graphics2D g2d = page.createGraphics();
			g2d.setColor(Color.red);
			g2d.draw(rectangle);
		}
 
		return text;
	}
 
// Method to send an email
	private void sendErrorEmail(EmailService emailService, LogService logService, String message, String filePath, String fileName)
	{
		logService.log(Level.SEVERE, message);
 
		Email email = emailService.createNewEmail();
		email.setSubject("failed email - please check");
		email.setMessage(message);
		email.setSendList(ERROR_TO_EMAIL);
		email.setImportance(Email.IMPORTANT_MORE);
           // add file attachment
		email.addAttachment(fileName, new File(filePath));
 
		// Change the FROM email
		emailService.setSMTPFromName(ERROR_FROM_EMAIL);
 
		// Send the email
		emailService.sendEmail(email);
 
		// Change the FROM email back
		emailService.setSMTPFromName(FROM_EMAIL);
	}
}