import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.xml.xmp.XmpWriter;
import java.io.ByteArrayOutputStream;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.File;
import java.nio.*;
import javax.swing.*;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.awt.*;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import java.awt.event.*;
public class Invoicer {
protected static JFrame frame;
JTextField accountNo, invoiceNo, amount, date, po, ourRef;
JButton processPDF, clear;
static String directory = "";
static final String AUTHORNAME = "";
public static void main(String[] args) {
new Invoicer();
}
public Invoicer(){
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
directory = chooser.getSelectedFile().toString();
}
// Create the JFrame for the tool and populate it with the various input fields and labels
frame = new JFrame("Invoicer");
processPDF = new JButton("Process PDF");
processPDF.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
processPDFActionPerformed(evt);
}
});
clear = new JButton("Clear");
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
clearActionPerformed(evt);
}
});
JLabel accNoLabel = new JLabel("Account No: ");
accountNo = new JTextField();
JLabel dateLabel = new JLabel("Date: ");
date = new JTextField();
JLabel invoiceNoLabel = new JLabel("Invoice No: ");
invoiceNo = new JTextField();
JLabel ourRefLabel = new JLabel("Our ref: ");
ourRef = new JTextField();
JLabel poLabel = new JLabel("PO: ");
po = new JTextField();
JLabel amountLabel = new JLabel("Amount: ");
amount = new JTextField();
// Good old confusing grouplayout - this is 2 columns.
// Column 1 are the labels (and clear button).
// Column 2 contains the textfields and the process button.
GroupLayout layout = new GroupLayout(frame.getContentPane());
frame.getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(dateLabel)
.addComponent(accNoLabel)
.addComponent(invoiceNoLabel)
.addComponent(poLabel)
.addComponent(ourRefLabel)
.addComponent(amountLabel)
.addComponent(clear)
)
.addGroup(layout.createParallelGroup()
.addComponent(date)
.addComponent(accountNo)
.addComponent(invoiceNo)
.addComponent(po)
.addComponent(ourRef)
.addComponent(amount)
.addComponent(processPDF)
)
);
layout.setVerticalGroup(
layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(dateLabel)
.addComponent(date)
)
.addGroup(layout.createParallelGroup()
.addComponent(accNoLabel)
.addComponent(accountNo)
)
.addGroup(layout.createParallelGroup()
.addComponent(invoiceNoLabel)
.addComponent(invoiceNo)
)
.addGroup(layout.createParallelGroup()
.addComponent(poLabel)
.addComponent(po)
)
.addGroup(layout.createParallelGroup()
.addComponent(ourRefLabel)
.addComponent(ourRef)
)
.addGroup(layout.createParallelGroup()
.addComponent(amountLabel)
.addComponent(amount)
)
.addGroup(layout.createParallelGroup()
.addComponent(processPDF)
.addComponent(clear)
)
);
// Set the miniumsize so that we can actually see everything at a decent size and make everything visible
frame.setMinimumSize(new Dimension(320, 0));
frame.pack();
frame.setVisible(true);
}
// Where the magic happens | take all the inputs add add them as meta data to the selected PDF
public void processPDF(String location, String invoiceNo, String date, String accountNo, String amount, String ourRef, String po){
try {
// Read the PDF in
PdfReader reader = new PdfReader(location);
PdfStamper stamp = new PdfStamper(reader,
new FileOutputStream(directory+"/Invoice "+invoiceNo+"s.pdf"));
// Custom parse the date - this is brittle but helps the user out as they only have to type ddmmyy rather than dd/mm/yy | Customer request
String newDate = date.substring(0,2)+"/"+date.substring(2,4)+"/"+date.substring(4,6);
// Create the metadata
HashMap<String, String> moreInfo = new HashMap<String, String>();
moreInfo.put("Author", AUTHORNAME);
// Keywords \r\n sets a new line.
moreInfo.put("Keywords","\r\ndate: "+newDate+"\r\na/c: "+accountNo.toUpperCase()+"\r\ninv: "+invoiceNo+"\r\npo: "+po+"\r\nref: "+ourRef+"\r\ninc. vat: "+amount+"\r\n");
// Set the metadata the old skool way
stamp.setMoreInfo(moreInfo);
// Set the metadata the new improved RDF way
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XmpWriter xmp = new XmpWriter(baos, moreInfo);
xmp.close();
stamp.setXmpMetadata(baos.toByteArray());
// Close the stamp
stamp.close();
// create a handle for the old pdf and then delete
File temp = new File(location);
temp.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
// Static method to display a JFileChooser and return the location of the chosen file
public static String getFilePath() {
JFileChooser temp = new JFileChooser();
temp.setDialogTitle("Please select the location");
int returnVal;
// Customer request - Save the user hunting on the computer add set the initial directory to where the invoices are scanned
temp.setCurrentDirectory(new File(directory));
returnVal = temp.showOpenDialog(null);
File file = temp.getSelectedFile();
return file.getPath();
}
// For when the Process PDF button is pressed
private void processPDFActionPerformed(ActionEvent evt){
processPDF(Invoicer.getFilePath(), invoiceNo.getText(), date.getText(), accountNo.getText(), amount.getText(), ourRef.getText(), po.getText());
}
// For when the Clear button is pressed.
private void clearActionPerformed(ActionEvent evt){
invoiceNo.setText("");
date.setText("");
accountNo.setText("");
amount.setText("");
po.setText("");
ourRef.setText("");
}
}