Friday 13 September 2013

Struts 2 Jasper integration using maven

1. maven dependencies need
<dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>5.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-jasperreports-plugin</artifactId>
            <version>2.3.15.1</version>
        </dependency>

2. Sample POJO Class
package com.doctorAppointment.action;

public class DoctorDetail {

    private String firstname;
   
    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getScheduleAppointment() {
        return scheduleAppointment;
    }

    public void setScheduleAppointment(String scheduleAppointment) {
        this.scheduleAppointment = scheduleAppointment;
    }

    public String getDoctor() {
        return doctor;
    }

    public void setDoctor(String doctor) {
        this.doctor = doctor;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    private String lastname;
   
    private String scheduleAppointment;
   
    private String doctor;
   
    private String comments;
}

3. Sample jasper_template.jrxml : template design of document generated using jasper
<?xml version="1.0"?>
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport name="jasper_test" language="java">
  <!-- Our fields from the DoctorDetail class. -->
  <field name="firstname" class="java.lang.String"/>
  <field name="lastname" class="java.lang.String"/>
  <field name="doctor" class="java.lang.String"/>
  <field name="comments" class="java.lang.String"/>
  <field name="scheduleAppointment" class="java.lang.String"/>
  <title>
    <band height="50">
      <staticText>
        <reportElement x="0" y="0" width="180" height="15"/>
        <textElement/>
        <text><![CDATA[Appointment]]></text>
      </staticText>
    </band>
  </title>
  <pageHeader>
    <band/>
  </pageHeader>
  <columnHeader>
    <band height="20">
      <staticText>
        <reportElement x="0" y="0" width="90" height="20"/>
        <textElement>
          <font isUnderline="true"/>
        </textElement>
        <text><![CDATA[FIRST NAME]]></text>
      </staticText>
      <staticText>
        <reportElement x="90" y="0" width="90" height="20"/>
        <textElement>
          <font isUnderline="true"/>
        </textElement>
        <text><![CDATA[LASTNAME]]></text>
      </staticText>
    
       <staticText>
        <reportElement x="180" y="0" width="90" height="20"/>
        <textElement>
          <font isUnderline="true"/>
        </textElement>
        <text><![CDATA[SCHEDULE APPOINTMENT]]></text>
      </staticText>
       <staticText>
        <reportElement x="270" y="0" width="90" height="20"/>
        <textElement>
          <font isUnderline="true"/>
        </textElement>
        <text><![CDATA[DOCTOR]]></text>
      </staticText>
       <staticText>
        <reportElement x="360" y="0" width="90" height="20"/>
        <textElement>
          <font isUnderline="true"/>
        </textElement>
        <text><![CDATA[COMMENTS]]></text>
      </staticText>
    </band>
  </columnHeader>
  <detail>
    <band height="20">
      <textField>
        <reportElement x="0" y="0" width="180" height="15"/>
        <textElement/>
        <textFieldExpression><![CDATA[$F{firstname}]]></textFieldExpression>
      </textField>
      <textField>
        <reportElement x="90" y="0" width="180" height="15"/>
        <textElement/>
        <textFieldExpression><![CDATA[$F{lastname}]]></textFieldExpression>
      </textField>
      <textField>
        <reportElement x="180" y="0" width="180" height="15"/>
        <textElement/>
        <textFieldExpression><![CDATA[$F{scheduleAppointment}]]></textFieldExpression>
      </textField>
      <textField>
        <reportElement x="270" y="0" width="180" height="15"/>
        <textElement/>
        <textFieldExpression><![CDATA[$F{doctor}]]></textFieldExpression>
      </textField>
      <textField>
        <reportElement x="360" y="0" width="180" height="15"/>
        <textElement/>
        <textFieldExpression><![CDATA[$F{comments}]]></textFieldExpression>
      </textField>
    </band>
  </detail>
  <columnFooter>
    <band/>
  </columnFooter>
  <pageFooter>
    <band height="15">
      <staticText>
        <reportElement x="0" y="0" width="40" height="15"/>
        <textElement/>
        <text><![CDATA[Page:]]></text>
      </staticText>
      <textField>
        <reportElement x="40" y="0" width="100" height="15"/>
        <textElement/>
        <textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
      </textField>
    </band>
  </pageFooter>
  <summary>
    <band/>
  </summary>
</jasperReport>

4. Compile .jrxml to .jasper on context initialization of web application. One time compilation is only needed : .jasper is used by jasper reported to convert in various format like HTML,PDF,XLS etc


try {
            JasperCompileManager.compileReportToFile(jrxmlFilePath,
                    contextFolder + "\\compiled_template.jasper");
        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }
 Action Class
package com.doctorAppointment.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JasperCompileManager;

import org.apache.struts2.ServletActionContext;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.docx4j.XmlUtils;
import org.docx4j.convert.in.xhtml.XHTMLImporter;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart;
import org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart;
import org.docx4j.wml.Style;

import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import com.opensymphony.xwork2.Action;

public class PrintDocumentAction implements Action {

    /*
     * private InputStream fileInputStream;
     *
     * public InputStream getFileInputStream() { return fileInputStream; }
     */
    /** List to use as our JasperReports dataSource. */
    private List<DoctorDetail> myList;

    public List<DoctorDetail> getMyList() {
        return myList;
    }

    @Override
    public String execute() throws Exception {
        System.out.println("PrintPDF start");

        HttpServletRequest request = ServletActionContext.getRequest();
        String contextFolder = request.getServletContext().getRealPath("");
        String jrxmlFilePath = contextFolder + "\\jasper_template.jrxml";

        myList = new ArrayList<DoctorDetail>();
        myList.add((DoctorDetail) request.getSession().getAttribute(
                "doctorDetail"));

     
        return "SUCCESS";
    }

}
 
5. Struts.xml
<package name="jasper" namespace="/" extends="jasperreports-default">
        <result-types>
            <result-type
                class="org.apache.struts2.views.jasperreports.JasperReportsResult"
                name="jasper">
            </result-type>
        </result-types>
        <action name="documentDownload" class="com.doctorAppointment.action.PrintDocumentAction">

            <result name="SUCCESS" type="jasper">
                <param name="contentType">application/pdf</param>
                <param name="location">compiled_template.jasper</param>
                <param name="dataSource">myList</param>
                <param name="format">PDF</param>
                    <param name="contentDisposition">attachment;filename="doctorAppointment.pdf"</param>
                <param name="bufferSize">1024</param>
            </result>
        </action>
    </package> 


Full Source : https://github.com/milandashara/struts2-jasper-yahp-demo.git

Thursday 12 September 2013

HTML to PDF using Java

1. Grab html source using javascript function

function getPageHTML(){ 
                return "<html>" + document.getElementsByTagName('html')[0].innerHTML + "</html>";
            }
2. Post this html source as parameter using jquery on click of pdfDownload.
printPDF is relative url i.e http:localhost:8080/Demo/printPDF

htmlString is post request parameter

$("#pdfDownload").click(function() {
                //alert("Handler for .click() called.");

                var fullHtml = getPageHTML();

                $.post("printPDF", {
                    htmlString : fullHtml
                   
                });

            });

3. Save html source to .html file and convert html to pdf using YAHP Converter. Here is example of action class of struts2.
package com.doctorAppointment.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.allcolor.yahp.converter.CYaHPConverter;
import org.allcolor.yahp.converter.IHtmlToPdfTransformer;
import org.apache.struts2.ServletActionContext;

public class PrintPDF {

    private InputStream fileInputStream;

    public InputStream getFileInputStream() {
        return fileInputStream;
    }

    // configure fopFactory as desired
    // private final FopFactory fopFactory = FopFactory.newInstance();

    /** xsl-fo namespace URI */
    protected static String foNS = "http://www.w3.org/1999/XSL/Format";

    public String execute() throws Exception {

        System.out.println("PrintPDF start");
        HttpServletRequest request = ServletActionContext.getRequest();
        String html = request.getParameter("htmlString");
        String contextFolder = request.getServletContext().getRealPath("");

        String htmlFileName = contextFolder + "\\download.html";
        String pdfFileName = contextFolder + "\\download.pdf";

        File htmlFile = new File(htmlFileName);
        if (htmlFile.exists()) {
            htmlFile.delete();
            htmlFile.createNewFile();
        } else {
            htmlFile.createNewFile();
        }
        // save html
        FileWriter htmlFileWriter = new FileWriter(htmlFile);
        htmlFileWriter.write(html);
        htmlFileWriter.flush();
        htmlFileWriter.close();

        // File pdfFile=new File(pdfFileName);

        // new converter
        CYaHPConverter converter = new CYaHPConverter();
        // save pdf in outfile
        File fout = new File(pdfFileName);
        FileOutputStream out = new FileOutputStream(fout);
        // contains configuration properties
        Map properties = new HashMap();
        // list containing header/footer
        List headerFooterList = new ArrayList();
        // add header/footer
        headerFooterList
                .add(new IHtmlToPdfTransformer.CHeaderFooter(
                        "<table width=\"100%\"><tbody><tr><td align=\"left\">"
                                + "Generated with YaHPConverter.</td><td align=\"right\">Page <pagenumber>/<"
                                + "pagecount></td></tr></tbody></table>",
                        IHtmlToPdfTransformer.CHeaderFooter.HEADER));
        headerFooterList.add(new IHtmlToPdfTransformer.CHeaderFooter(
                "© 2009 Quentin Anciaux",
                IHtmlToPdfTransformer.CHeaderFooter.FOOTER));
        properties.put(IHtmlToPdfTransformer.PDF_RENDERER_CLASS,
                IHtmlToPdfTransformer.FLYINGSAUCER_PDF_RENDERER);
        // properties.put(IHtmlToPdfTransformer.FOP_TTF_FONT_PATH, fontPath);

        converter.convertToPdf(htmlFile.toURI().toURL(),
                IHtmlToPdfTransformer.A4P, headerFooterList, out, properties);

        out.flush();
        out.close();

        fileInputStream = new FileInputStream(fout);
        return "SUCCESS";
    }

}

Required YAHP maven dependency
<dependency>
            <groupId>com.google.code.maven-play-plugin.org.allcolor.yahp</groupId>
            <artifactId>yahp</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.maven-play-plugin.org.allcolor.yahp</groupId>
            <artifactId>yahp-internal</artifactId>
            <version>1.3-patched-play-pdf-0.8</version>
        </dependency>

Source : https://github.com/milandashara/struts2-jasper-yahp-demo.git

Note : Download may not run from eclipse. It will work after deploying war in tomcat