Running Jasper Reports from Java

As a follow-up to my previous post about using iReport, I wanted to write some code that would run the report.  My goal is something that I can launch from PeopleTools.

Below is some Java that will execute the report and build a PDF output.  This class takes the XML data file and the report designed by iReport and produces a PDF out of it.

[sourcecode language=”java”]
package net.digitaleagle.psst0101;

import java.io.File;
import java.util.HashMap;
import java.util.Locale;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory;
import net.sf.jasperreports.engine.util.FileResolver;
import net.sf.jasperreports.engine.util.JRXmlUtils;

import org.w3c.dom.Document;

public class JasperInterface {
private String dataPath;
private String basePath;
private String reportName;
private String reportOutput;

public JasperInterface(String dataPath, String basePath, String reportName, String reportOutput) {
this.dataPath = dataPath;
this.basePath = basePath;
this.reportName = reportName;
this.reportOutput = reportOutput;
}

public void run() throws JRException {
Document data = JRXmlUtils.parse(dataPath);

HashMap parms = new HashMap();
parms.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, data);
parms.put(JRXPathQueryExecuterFactory.XML_DATE_PATTERN, "yyyy-MM-dd");
parms.put(JRXPathQueryExecuterFactory.XML_LOCALE, Locale.ENGLISH);
parms.put(JRParameter.REPORT_LOCALE, Locale.US);

FileResolver fileResolver = new FileResolver() {
@Override
public File resolveFile(String fileName) {
return new File(basePath, fileName);
}
};
parms.put(JRParameter.REPORT_FILE_RESOLVER, fileResolver);

JasperReport jr = JasperCompileManager.compileReport(basePath + reportName);
JasperPrint pr = JasperFillManager.fillReport(jr, parms);
JasperExportManager.exportReportToPdfFile(pr, reportOutput);
}
}
[/sourcecode]

Here’s some code that can launch the report without needing the JasperReports classes in the classpath.  I originally thought about just putting the jar files into the class directory in the PeopleSoft Home, but Jasper Reports has a number of Jar files.  So, I created a class that had no dependencies on JasperReports.  I tell it the location of the JasperReports installation, and it builds the necessary class path.

[sourcecode language=”java”]
package net.digitaleagle.psst0101;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;

public class JasperReportRunner {
private String jasperPath;
private String dataPath;
private String basePath;
private String reportName;
private String reportOutput;

/**
* @param args
*/
public static void main(String[] args) {
String jasperPath = args[0];
String dataPath = args[1];
String basePath = args[2];
String reportName = args[3];
String reportOutput = args[4];

JasperReportRunner jrr = new JasperReportRunner(jasperPath, dataPath, basePath, reportName, reportOutput);
jrr.run();
}

public JasperReportRunner(String jasperPath, String dataPath, String basePath, String reportName, String reportOutput) {
this.jasperPath = jasperPath;
this.dataPath = dataPath;
this.basePath = basePath;
this.reportName = reportName;
this.reportOutput = reportOutput;
}

public void run() {
ArrayList urls = new ArrayList();
File jasperDir = new File(jasperPath);
addJars(urls, new File(jasperDir, "dist"));
addJars(urls, new File(jasperDir, "lib"));
URLClassLoader ucl = new URLClassLoader(urls.toArray(new URL[0]));
Class jic;
try {
jic = ucl.loadClass(this.getClass().getPackage().getName() + ".JasperInterface");
} catch (ClassNotFoundException e) {
System.err.println("Could not access JasperInterface class");
e.printStackTrace();
return;
}
Constructor c = jic.getConstructors()[0];
Object ji;
try {
ji = c.newInstance(dataPath, basePath, reportName, reportOutput);
} catch (Exception e) {
System.err.println("Error creating new instance of JasperInterface");
e.printStackTrace();
return;
}
Method method;
try {
method = jic.getMethod("run");
} catch (Exception e) {
System.err.println("Could not get run method");
e.printStackTrace();
return;
}
try {
method.invoke(ji);
} catch (Exception e) {
System.err.println("Could not get execute run method");
e.printStackTrace();
return;
}
}

private void addJars(ArrayList urls, File jarDir) {
if(!jarDir.exists()) {
System.err.println("Could not find Jasper Jar files in directory: " + jarDir.getAbsolutePath());
System.err.println("Check installation directory");
return;
}
for(File jarFile : jarDir.listFiles()) {
if(jarFile.isFile() && jarFile.getName().toLowerCase().endsWith(".jar")) {
try {
urls.add(jarFile.toURI().toURL());
} catch (MalformedURLException e) {
System.err.println("Error loading jar for class path: " + jarFile.getAbsolutePath());
e.printStackTrace();
}
}
}
}

}
[/sourcecode]

Resources

One thought on “Running Jasper Reports from Java

Leave a Comment

Your email address will not be published. Required fields are marked *