Capture a signature image, create a PDF from HTML, and send an email with PDF file on the fly

Capture a signature image, create a  HTML with signature image, convert HTML to PDF file,  and send an email with PDF file.

The title might give you headache from the starting point but once you know each details as my instruction, it will be simple and easy to implement it.

The requirements from my client was quite a simple as below;

1. have customer read agreement contents and sign it on any digital equipment or device.

2. get a copy of signature and create a PDF.

3. Send this PDF file to customer through email.

As you can see above requirements, it sounds not that complicate.

So, I have designed a simple application to fulfill these requirements through following technologies.

1. AngularJS

2. RESTful API in Java using JAX-RS and Jersey.

3.Itext with Flying source + rendering tool

4. Sendgrid email

 

First, The Angular JS framework is providing  lots of breathing room without worrying about structuring whole project. It is simple and easy to start.

Second. the Jersey restful webservice is another simple set to connect to database and utilize the JSON type of data. If you would like to design Backend service, this will be the simple and quick answer to everybody.

Third,  Itext with flying source is providing good library to convert from HTML to PDF. It was bit picky to make right format of HTML in order to be converted properly.

Finally, the sendgrid library is providing many headache to configure the mail server and simple to use too.

The below are details and should know for implementing this.

1. download the AngularJS + Java backbone RESTful API in Java using JAX-RS and Jersey from this site. (http://coenraets.org/blog/2012/02/sample-application-with-angular-js/)

 

2. Setup a Eclipse project  that should have connection to tomcat server

3. Important things to know at the Angularjs setting;

– app.js :  declare the overall app for service, controller, and routing

ex.)

angular.module(‘king’, [‘king.filters’, ‘king.directives’,’king.services.signature’,’king.services.cashsignature’]).

$routeProvider.when(‘/search’, {templateUrl: ‘partials/search.html’, controller: SearchCtrl});

 

– controller.js : handle events from page

ex.)

function MainCtrl($rootScope,$scope) {

window.location = “#/search”;
$rootScope.$apply();

}

– service.jsp : connect to the backend service

ex.)

angular.module(‘king.services.signature’, [‘ngResource’]).
factory(‘Signature’, function($resource){
return $resource(‘api/signature/:rewardcardId’, {}, {
query: {method:’GET’, params:{rewardcardId:’signature’}, isArray:false},
update: {method:’PUT’, params:{rewardcardId:’signature’}, isArray:false}
});
});

 

4. The web.xml file that should be set asbelow example;

 

<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.bm.web.java</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>

 

5. For the signautre it will need jSignature.js library. The code example is below;

– ex.) HTML code;

<!– This will be the area of sign –>
<div id=”signature”></div>
</div>
<div id=”tools”></div>

– ex.) controller.js;

function SignCtrl($rootScope,$scope,CashSignature,Signature) {
console.log(” SignCtrl is invoked”);
$scope.signature =CashSignature.getSign();

(function($) {
var topics = {};
$.publish = function(topic, args) {
if (topics[topic]) {
var currentTopic = topics[topic],
args = args || {};

for (var i = 0, j = currentTopic.length; i < j; i++) {
currentTopic[i].call($, args);
}
}
};
$.subscribe = function(topic, callback) {
if (!topics[topic]) {
topics[topic] = [];
}
topics[topic].push(callback);
return {
“topic”: topic,
“callback”: callback
};
};
$.unsubscribe = function(handle) {
var topic = handle.topic;
if (topics[topic]) {
var currentTopic = topics[topic];

for (var i = 0, j = currentTopic.length; i < j; i++) {
if (currentTopic[i] === handle.callback) {
currentTopic.splice(i, 1);
}
}
}
};
})(jQuery);
$(document).ready(function() {

// This is the part where jSignature is initialized.
var $sigdiv = $(“#signature”).jSignature({‘UndoButton’:false})

// All the code below is just code driving the demo.
, $tools = $(‘#tools’)
, $extraarea = $(‘#displayarea’)
, pubsubprefix = ‘jSignature.demo.’

$(‘<span><b>Please confirm your sign by clicking this Sign button: </b></span><input type=”button” value=”SIGN NOW” >’).bind(‘click’, function(e){
var data = $sigdiv.jSignature(‘getData’,’image’)
var signature = CashSignature.getSign();
signature.signString=data;
console.log(“signature is processing ” );
//updateSignature($rootScope,$scope,signature,CashSignature.getSign().customerid);
signature.$update({ customerid: signature.customerid});

console.log(” SignCtrl is invoked and will save data :”)
window.location = “#/search”;
//}
}).appendTo($tools)

$(‘<span><b> or: </b></span><input type=”button” value=”Reset”>’).bind(‘click’, function(e){
$sigdiv.jSignature(‘reset’)
}).appendTo($tools)

if (Modernizr.touch){
$(‘#scrollgrabber’).height($(‘#content’).height())
}

})
}

6. creating sign image from byte array

ex.)

//String imagefilename=Utils.getTempSignSlot();
String imagefilename=”sign_”+customerID+”.png”;
System.out.println(“imagefilename ” + imagefilename);
try {

byte[] bytearray = Base64.decode(sign);

BufferedImage imag=ImageIO.read(new ByteArrayInputStream(bytearray));
ImageIO.write(imag, “png”, new File(Utils.getsignImagePath(),imagefilename));
} catch (Exception e ){
System.err.println(“Exception at “+ e.getMessage());
}

return imagefilename;

 

7. convert HTL to PDF example code

ex.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;

import org.xhtmlrenderer.pdf.ITextRenderer;

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.lowagie.text.DocumentException;

public class ReleaseSignedPDF {
public static void createSignedPDF (Signature sig, String FileName)
throws IOException, DocumentException {

String localtmphtmlpath = Utils.getTempHtmlServerPath()+”/tmphtml/” + FileName;
System.out.println(“URL is ” + localtmphtmlpath);

WebClient webClient = new WebClient();

HtmlPage page = webClient.getPage(localtmphtmlpath);

OutputStream os = null;
try{
os = new FileOutputStream(Utils.getTempPDFPath()+ “/”+sig.getName().trim().replaceAll(” “, “_”)+ “_”+sig.getBarcode() +”_signed.pdf”);

ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(page,null);
renderer.layout();
renderer.createPDF(os);
} finally{
if(os != null) os.close();
}

}

}

8.send mail with PDF file;

ex.)

import com.github.sendgrid.SendGrid;

public class SendMail {

public static void sendMail(Signature sig)
{
try {
boolean noemailflag=false;

SendGrid sendgrid = new SendGrid(Utils.getEmailUserID(), Utils.getEmailPassword());

if(sig.getEmail() != null || !sig.getEmail().equals(“”)){
sendgrid.addTo(sig.getEmail());
sendgrid.addTo(Utils.getEmailAddTo());

}
else
noemailflag=true;

sendgrid.setFrom(Utils.getEmailAddTo());
sendgrid.setFromName(Utils.getEmailFromName());
sendgrid.setSubject(Utils.getEmailSubject());
sendgrid.setText(Utils.getEmailText());
sendgrid.addFile(new File(Utils.getTempPDFPath()+ “/”+sig.getName().trim().replaceAll(” “, “_”)+ “_”+sig.getBarcode() +”_signed.pdf”));
sendgrid.send();

}catch (Exception mex) {
mex.printStackTrace();
System.err.println(“Send MAil has an exception “+ mex.getMessage());
}
}

}

 

error: Content is protected !!