Automating Administrative Tasks with iText and DocuSign

The one thing I hate the most is wasting time in administrative tasks. When you have a company, deal with customers, invoice, pay taxes, sign contracts, etc. you end up spending a lot of time doing admin instead of your real work. What do you do? Well, you don’t have the choice. At the beginning it’s so scary, that you print paper, sign it with a pen, scan it, send it via email, or worth, via post, and do it again and again…. until you go “Ok, let’s automate these boring tasks with code!“.

In this blog post I show you how to generate a PDF with iText and how to send it via DocuSign so your partners can sign it electronically. All through Java code and APIs. This means you don’t have to touch MicroSoft Word to create a document nor log on into DocuSign to send it to someone to be signed.

Generating a PDF with iText

PDF has been around for a long time (1990) and iText was created in 1999 to allow developers to generate PDF files using a Java API (then, iText was ported to other languages). Today it has a dual licence, and the latest version is iText 7 (announced in May 2016 and quite different from iText 5).

Maven Dependencies

First, let’s setup our Maven dependencies. iText 7 is divided into several Maven artifacts. So it just depends on what you need. Here is what I’ve used (I could have avoid kernel as most artifacts depend on it):

[sourcecode language=”xml” title=”pom.xml” highlight=”8,13,18″]
<properties>
<version.itext>7.0.1</version.itext>
</properties>

<dependencies>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>${version.itext}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>${version.itext}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>forms</artifactId>
<version>${version.itext}</version>
</dependency>
</dependencies>
[/sourcecode]

Synchronize PDF while Developing

Before coding with iText, let me give you a piece of advise. One annoying thing when generating a PDF, is that it takes time to have it the way you want. So, you change your code, generate the PDF, open the file (this usually opens Adobe Reader), look at it, close the PDF, and so on. I couldn’t find any way for Acrobate Reader to automatically reload the PDF once the file changes, so I looked around and discovered Skim (there are other solutions, but this one worked for me). Skim automatically synchronizes the PDF when the file changes.

[sourcecode language=”shell” title=”Installing, twicking and opening a file”]
$ brew cask install skim

$ defaults write -app Skim SKAutoReloadFileUpdate -boolean true

$ open -a Skim MyGenerated.pdf
[/sourcecode]

I installed it, tweaked it a bit, and set the automatic reload (open Skim -> Preferences -> Synchro). Now I’m ready to code my PDF document.

skim

Three pages to Generate

The contract I want to generate is three pages long. As you can see in the thumbnails below, these three pages have a few images, text, lists, tables, a footer, A4 portrait, A4 landscape… All this text and graphics is doable with the iText APIs.

3 pages Contract

I won’t go through all the code that generates these 3 pages (just have a look at the GitHub repo), but I want to highlight something important: the zone where the customer needs to sign:

zone to be signed

If you look at the iText code below, this zone is modeled as a table. Basically, it is just a 3×2 table, where the text name, date and signature is displayed on the left, and empty cells on the right. That’s all. There is no extra data to tell the customer where to sign. This is actually done with the DocuSign APIs.

[sourcecode language=”java” title=”PdfGenerator.java” highlight=”3,5,7″]
private static Table drawSignature() {
Table table = new Table(2).setWidthPercent(60).setHorizontalAlignment(HorizontalAlignment.CENTER).setBackgroundColor(Color.LIGHT_GRAY);
table.addCell(new Cell().add(new Paragraph(“Name”).setMultipliedLeading(3).setBold()).setBorder(Border.NO_BORDER));
table.addCell(new Cell().add(new Paragraph()).setBorder(Border.NO_BORDER));
table.addCell(new Cell().add(new Paragraph(“Date”).setMultipliedLeading(2).setBold()).setBorder(Border.NO_BORDER));
table.addCell(new Cell().add(new Paragraph()).setBorder(Border.NO_BORDER));
table.addCell(new Cell().add(new Paragraph(“Signature”).setMultipliedLeading(5).setBold()).setBorder(Border.NO_BORDER));
table.addCell(new Cell().add(new Paragraph()).setBorder(Border.NO_BORDER));
return table;
}
[/sourcecode]

Sending a PDF with DocuSign

IANAL but I know documents need to be signed, and I also know that digital signature are legal in Europe. DocuSign was founded in 2003 in the US and is now accepted in Europe. I’ve been a big fan of DocuSign for a few years now.

What I usually do, is that I go to the DocuSign web interface, I upload a PDF, I add what they call “tags” (basically, the zones on the PDF where the customer signs), the name and email address of the person signing the document, and click send. This sends an email to the customer, he/she opens it, and signes the document automatically. When I need to send the same document for several people, I can upload a PDF that will act as a template. That saves a bit of time, but still, there’s a lot of time wasted.

I discovered recently that DocuSign has a set of APIs and even a SDK for Java. It allows me to send a document, but also to add tags to my generated PDF. So let’s see how to use DocuSign from Java code.

Creating a Developer Sandbox

The first thing you need to do to start using the DocuSign APIs is to create a developer’s sandbox (this way you are sure your documents are not legally signed while developing). Enter your name and email address, you then receive a validation email, log on and generate an integrator key.

The Integrator Key identifies your application and is also used as your client id during OAuth token requests. It looks like this:

[sourcecode language=”shell”]
4765b81-3558-4289-bf9d-e40977653c4
[/sourcecode]

Maven Dependencies

The DocuSign SDK is quite easy in terms of dependencies, only one is needed.

[sourcecode language=”xml” title=”pom.xml” highlight=”7″]
<properties>
<version.docusign>2.0.2</version.docusign>
</properties>
<dependencies>
<dependency>
<groupId>com.docusign</groupId>
<artifactId>docusign-esign-java</artifactId>
<version>${version.docusign}</version>
</dependency>
</dependencies>
[/sourcecode]

Adding Tags to the PDF

I won’t go through all the Java code used to send a PDF. Check the code, I hope it is easy to read. Basically, we Base64 encode the PDF file to put it inside a DocuSign envelop, add the recipients, and send the envelop. The interesting part is how to add tags on the needed zones.

_pdfsigned

As you can see above, the DocuSign tags are the place holders that will hold the information about the customer (name) and his/her signature (date of signature, and signature itself). These tags cannot be added to the PDF itself with iText, you need the DocuSign API.

Below, the getTabFullName method sets the FullName tag at a X Y position on the PDF (on page 1). Look at the code, you will see a getTabDateSigned and a getTabSignHere methods. Based on the same logic, these two methods add the date of the signature and the signature itself.

[sourcecode language=”java” title=”PdfGenerator.java” highlight=”8,9,18″]
private static EnvelopeDefinition generateEnvelopeDefinition(String pdfFile) throws IOException {
// create an envelope that will store the document(s), field(s), and recipient(s)
// …
// add a document to the envelope
// …

// Set tabs
Tabs tabs = new Tabs();
tabs.setFullNameTabs(getTabFullName());
tabs.setDateSignedTabs(getTabDateSigned());
tabs.setSignHereTabs(getTabSignHere());
signer.setTabs(tabs);

// add recipients (in this case a single signer) to the envelope
// send the envelope
}

private static java.util.List<FullName> getTabFullName() {
FullName tab = new FullName();
tab.setDocumentId(“1”);
tab.setPageNumber(“1”);
tab.setRecipientId(“1”);
tab.setXPosition(“210”);
tab.setYPosition(“636”);
java.util.List<FullName> tabs = new ArrayList<>();
tabs.add(tab);
return tabs;
}
[/sourcecode]

Conclusion

Here I just gave you a simple example, but I use this technic for more complex things, such as resource bundle (so I can swap languages in the contract) or more advanced DocuSign tags. Basically, with the iText and DocuSign APIs, the sky is the limit ;o)

Administrative tasks are boring and they take a lot of our precious time. Generating PDF with code is fun, using DocuSign APIs to legally sign documents if also fun.

Bottom line: administrative tasks are boring, typing code is fun.

References

Leave a Reply