Requirement:
1. In Web application write a code to generate a PDF file
2. PDF file should have look and feel just like the HTML
3. PDF file contents could be in English, Spanish or Chinese
Solution:
Get the maven dependencies :
1. <dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.0.8</version>
</dependency>
2. This one is required to be R8, the higher version would not work.
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
3. <dependency>
<groupId>apache-xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>
</dependency>
Store the HTML on the server outside the WAR or bundle it inside the WAR.
Use below code to read the HTML and pass it to Flying Saucer api.
ByteArrayOutputStream os = new ByteArrayOutputStream();
String html = readFile(myfile);
//see below for readFile method code.
ITextRenderer renderer = new ITextRenderer();
//add font file, this will embed the font file in the pdf, so pdf file will be large in size.
renderer.getFontResolver().
addFont("images/ARIALUNI.TTF",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.getFontResolver().
addFont("images/VERDANA.TTF",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.getFontResolver().
addFont("images/verdanab.ttf",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.getFontResolver().
addFont("images/verdanai.ttf",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.getFontResolver().
addFont("images/verdanaz.ttf",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
ResourceLoaderUserAgent callback =
new ResourceLoaderUserAgent(renderer.getOutputDevice());
callback.setSharedContext(renderer.getSharedContext());
renderer.getSharedContext().setUserAgentCallback(callback);
renderer.setDocumentFromString(finalHTML);
renderer.layout();
renderer.createPDF(os);
//this will create the pdf in the byte array output stream
OutputStream file = new FileOutputStream(
new File("/filelocation/test.pdf"));
//open output stream to physical file
//Override this class so that you can manipulate the font or //image files' location that you put in the CSS or in //<img> tag //in html
private class ResourceLoaderUserAgent extends ITextUserAgent
{
public ResourceLoaderUserAgent(
ITextOutputDevice outputDevice) {
super(outputDevice);
}
protected InputStream resolveAndOpenStream(String uri) {
log.debug("uri : "+uri);
InputStream is = super.resolveAndOpenStream(uri);
String fileName = "";
try {
String[] split = uri.split("/");
fileName = split[split.length - 1];
log.debug("fileName : "+fileName);
} catch (Exception e) {
return null;
}
if (is == null) {
// Resource is on the classpath
try{
is = ResourceLoaderUserAgent.
class.getClassLoader().
getResourceAsStream("images/"
+ fileName);
} catch (Exception e) {
log.error(" resouce on class path :",e);
}
}
if (is == null) {
// Resource is in the file system
try {
is = new FileInputStream(
new File("images/" + fileName));
} catch (Exception e) {
log.error(" resouce on file path :",e);
}
}
return is;
}
}
//private method to read a file
private String readFile(String myfile){
InputStream inputStream = new FileInputStream(file);
Reader reader = new InputStreamReader(
inputStream,"UTF-8");
BufferedReader readerf = new BufferedReader(reader);
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
while((line = readerf.readLine() ) != null ) {
if(!StringUtils.isEmpty(line)){
stringBuilder.append( line);
stringBuilder.append( ls );
}
}
return stringBuilder.toString();
}
Below is the HTML
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html>
<head>
<style type="text/css">
div.ErrorPage {
margin: 15px auto 25px;
width: 514px;
}
div.ErrorPage h1 {
padding: 0 0 3px 55px;
color: #e66600;
background: url(images/icons_all.gif) no-repeat 20px -1679px;
font-size: 2em;
line-height: 1.25em;
}
@font-face {
font-family: 'Verdana';
src: url("VERDANA.TTF");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
@font-face {
font-family: 'Verdana';
src: url("verdanai.ttf");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
@font-face {
font-family: 'Verdana';
src: url("verdanab.ttf");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
@font-face {
font-family: 'ARIALUNI';
src: url("ARIALUNI.TTF");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
body {
font-family: "Arial Unicode MS";
font: 11pt;
background: #fff;
color: #252525;
font-weight: bold;
}
</style>
</head>
<body>
<img src='https://productionsite/where/image/is_stored.png'></img>
<div>Chinese text here or spanish text here or english text here</div>
</body>
</html>
That's all folks.
This is how to use Flying saucer API for PDF generation using HTML with iText, in English Spanish Chinese with fonts with Italic and Bold.
If you need any help please leave comment below and let me know and I will help you in this.
1. In Web application write a code to generate a PDF file
2. PDF file should have look and feel just like the HTML
3. PDF file contents could be in English, Spanish or Chinese
Solution:
Get the maven dependencies :
1. <dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.0.8</version>
</dependency>
2. This one is required to be R8, the higher version would not work.
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
3. <dependency>
<groupId>apache-xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>
</dependency>
Store the HTML on the server outside the WAR or bundle it inside the WAR.
Use below code to read the HTML and pass it to Flying Saucer api.
ByteArrayOutputStream os = new ByteArrayOutputStream();
String html = readFile(myfile);
//see below for readFile method code.
ITextRenderer renderer = new ITextRenderer();
//add font file, this will embed the font file in the pdf, so pdf file will be large in size.
renderer.getFontResolver().
addFont("images/ARIALUNI.TTF",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.getFontResolver().
addFont("images/VERDANA.TTF",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.getFontResolver().
addFont("images/verdanab.ttf",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.getFontResolver().
addFont("images/verdanai.ttf",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.getFontResolver().
addFont("images/verdanaz.ttf",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
ResourceLoaderUserAgent callback =
new ResourceLoaderUserAgent(renderer.getOutputDevice());
callback.setSharedContext(renderer.getSharedContext());
renderer.getSharedContext().setUserAgentCallback(callback);
renderer.setDocumentFromString(finalHTML);
renderer.layout();
renderer.createPDF(os);
//this will create the pdf in the byte array output stream
OutputStream file = new FileOutputStream(
new File("/filelocation/test.pdf"));
//open output stream to physical file
file.write(os.toByteArray());
//get the bytes from byte array output stream and write to //outputstream
file.close(); //close the output stream
os.close(); //close the byte array output stream
//Override this class so that you can manipulate the font or //image files' location that you put in the CSS or in //<img> tag //in html
private class ResourceLoaderUserAgent extends ITextUserAgent
{
public ResourceLoaderUserAgent(
ITextOutputDevice outputDevice) {
super(outputDevice);
}
protected InputStream resolveAndOpenStream(String uri) {
log.debug("uri : "+uri);
InputStream is = super.resolveAndOpenStream(uri);
String fileName = "";
try {
String[] split = uri.split("/");
fileName = split[split.length - 1];
log.debug("fileName : "+fileName);
} catch (Exception e) {
return null;
}
if (is == null) {
// Resource is on the classpath
try{
is = ResourceLoaderUserAgent.
class.getClassLoader().
getResourceAsStream("images/"
+ fileName);
} catch (Exception e) {
log.error(" resouce on class path :",e);
}
}
if (is == null) {
// Resource is in the file system
try {
is = new FileInputStream(
new File("images/" + fileName));
} catch (Exception e) {
log.error(" resouce on file path :",e);
}
}
return is;
}
}
//private method to read a file
private String readFile(String myfile){
InputStream inputStream = new FileInputStream(file);
Reader reader = new InputStreamReader(
inputStream,"UTF-8");
BufferedReader readerf = new BufferedReader(reader);
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
while((line = readerf.readLine() ) != null ) {
if(!StringUtils.isEmpty(line)){
stringBuilder.append( line);
stringBuilder.append( ls );
}
}
return stringBuilder.toString();
}
Below is the HTML
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html>
<head>
<style type="text/css">
div.ErrorPage {
margin: 15px auto 25px;
width: 514px;
}
div.ErrorPage h1 {
padding: 0 0 3px 55px;
color: #e66600;
background: url(images/icons_all.gif) no-repeat 20px -1679px;
font-size: 2em;
line-height: 1.25em;
}
@font-face {
font-family: 'Verdana';
src: url("VERDANA.TTF");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
@font-face {
font-family: 'Verdana';
src: url("verdanai.ttf");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
@font-face {
font-family: 'Verdana';
src: url("verdanab.ttf");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
@font-face {
font-family: 'ARIALUNI';
src: url("ARIALUNI.TTF");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
body {
font-family: "Arial Unicode MS";
font: 11pt;
background: #fff;
color: #252525;
font-weight: bold;
}
</head>
<body>
<img src='https://productionsite/where/image/is_stored.png'></img>
<div>Chinese text here or spanish text here or english text here</div>
</body>
</html>
That's all folks.
This is how to use Flying saucer API for PDF generation using HTML with iText, in English Spanish Chinese with fonts with Italic and Bold.
If you need any help please leave comment below and let me know and I will help you in this.