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); } } |