Showing posts with label how to use Flying saucer API for PDF generation using HTML with iText. Show all posts
Showing posts with label how to use Flying saucer API for PDF generation using HTML with iText. Show all posts

Sunday, December 7, 2014

how to use Flying saucer API for PDF generation using HTML with iText, in English Spanish Chinese with fonts with Italic and Bold.

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

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

</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.