Tushar,
IMHO Jasper Reports and iReport are great tools.
I have built a system with rails 1.1.x and some days ago I’ve
successfully ported it on Rails 2.3.2, all works well (the only gotcha
is a little memory leak calling IO.popen (not destructive memory leak),
I think the problem is due to Passenger 2.1.3 but the system is very
stable).
Using jasper reports (and iReport for design) I’m able to print some
good moderate complex reports from different db (IBM AS/400, MySQL,
Firebird and MS-SQL) (some reports are lables images (linked from web
site…) printed on thermal printer).
I was able to print the reports calling a bash script passing parameters
ex.:
lib/document.rb
class Document
def self.generate_report(report_design, output_type, jdbc_driver,
jdbc_url, jdbc_user, jdbc_password, report_parameters)
# params:
# report_design: the name of jasper file containing the report
design
# output_type: one of the following: pdf, xml, rtf, xls, csv, html
# jdbc_driver: ex. org.firebirdsql.jdbc.FBDriver for FireBird db
# jdbc_url: ex. jdbc:firebirdsql:localhost:mydb for FireBird db
# jdbc_user: ex. sysdba for FireBird db
# jdbc_password: ex. masterkey for FireBird db
# report_prarameters: param_name@@param_type@@param_value ex.
filter_by_name@@String@@goofy
# accepted param types:
# java.util.Date (string formatted with dd/MM/yyyy)
# java.lang.Boolean (string: “true”, “1”, “-1” are considered
true)
# boolean (same as above)
# java.lang.String (string)
# string (same as above)
# java.lang.Integer (integer)
# int (same as above)
# java.lang.Double (double)
# double (same as above)
# For more info see XmlJasperInterface.java
report_design << ‘.jasper’ if !report_design.match(/.jasper$/)
params = “”
if report_parameters != nil
report_parameters.each {|p| params <<
“-r”#{p.name}@@#{p.java_type}@@#{p.value}" “}
end
pipe = IO.popen
“#{APP_PATH}jasper/XmlJasperInterface-#{RAILS_ENV}.sh -o#{output_type}
-f”#{APP_PATH}reports/#{report_design}” -d"#{jdbc_driver}"
-u"#{jdbc_url}" -n"#{jdbc_user}" -p"#{jdbc_password}" #{params}",
“r”
result = pipe.read
pipe.close
result
end
end
Shell script:
jasper/XmlJasperInterface-production.sh
#!/bin/sh
INTERFACE_CLASSPATH=…/path_to_jar/XmlJasperInterface.jar
Here put all jdbc libraries (jars) into classpath
for i in path_to_application/jasper/lib/*.jar; do
INTERFACE_CLASSPATH=$INTERFACE_CLASSPATH:$i; done
java -cp “$INTERFACE_CLASSPATH” XmlJasperInterface “$@”
This is the source for XmlJasperInterface.java
/*
- Inspired by the xmldatasource sample application provided with
- jasperreports-1.1.0
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.text.ParseException;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import java.util.Map;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.HashMap;
/**
-
@author Jonas Schwertfeger (jonas at schwertfeger dot ch)
-
@version $Id: XmlJasperInterface.java,v 1.4 2006/06/06 11:59:48 tex
Exp $
-
extended by Tex 2006
*/
public class XmlJasperInterface {
private static final String TYPE_PDF = “pdf”;
private static final String TYPE_XML = “xml”;
private static final String TYPE_RTF = “rtf”;
private static final String TYPE_XLS = “xls”;
private static final String TYPE_CSV = “csv”;
private static final String TYPE_HTML = “html”;
private String outputType;
private String compiledDesign;
private String jdbcDriver;
private String jdbcUrl;
private String jdbcUser;
private String jdbcPassword;
private Map parameters = new HashMap();
public static void main(String[] args) throws Exception {
String outputType = null;
String compiledDesign = null;
String jdbcDriver = null;
String jdbcUrl = null;;
String jdbcUser = null;;
String jdbcPassword = null;
Map parameters = new HashMap();
if (args.length < 6) {
printUsage();
return;
}
for (int k = 0; k < args.length; ++k) {
if (args[k].startsWith("-o")) {
outputType = args[k].substring(2);
} else if (args[k].startsWith("-f")) {
compiledDesign = args[k].substring(2);
} else if (args[k].startsWith("-d")) {
jdbcDriver = args[k].substring(2);
} else if (args[k].startsWith("-u")) {
jdbcUrl = args[k].substring(2);
} else if (args[k].startsWith("-n")) {
jdbcUser = args[k].substring(2);
} else if (args[k].startsWith("-p")) {
jdbcPassword = args[k].substring(2);
} else if (args[k].startsWith("-r")) {
String[] params = args[k].substring(2).split("@@");
if (params.length == 3) {
String paramName = params[0];
String paramType = params[1];
String paramValue = params[2];
if (paramName != null && paramName.trim().length() >
0 &&
paramType != null &&
paramType.trim().length() > 0 &&
paramValue != null &&
paramValue.trim().length() > 0) {
if
(paramType.equalsIgnoreCase(“java.util.Date”)) {
Date paramDate = null;
SimpleDateFormat sdf = new
SimpleDateFormat(“dd/MM/yyyy”);
try {
paramDate = sdf.parse(paramValue);
parameters.put(paramName, paramDate);
} catch (ParseException ex) {
ex.printStackTrace();
}
}
if
(paramType.equalsIgnoreCase(“java.lang.Boolean”)) {
if (paramValue.equalsIgnoreCase(“true”) ||
paramValue.equalsIgnoreCase(“1”) || paramValue.equalsIgnoreCase("-1")) {
parameters.put(paramName, new
Boolean(Boolean.TRUE));
} else {
parameters.put(paramName, new
Boolean(Boolean.FALSE));
}
}
if (paramType.equalsIgnoreCase(“boolean”)) {
if (paramValue.equalsIgnoreCase(“true”) ||
paramValue.equalsIgnoreCase(“1”) || paramValue.equalsIgnoreCase("-1")) {
parameters.put(paramName, new
Boolean(Boolean.TRUE).booleanValue());
} else {
parameters.put(paramName, new
Boolean(Boolean.FALSE).booleanValue());
}
}
if
(paramType.equalsIgnoreCase(“java.lang.String”) ||
paramType.equalsIgnoreCase(“String”)) {
parameters.put(paramName, paramValue);
}
if
(paramType.equalsIgnoreCase(“java.lang.Integer”)) {
try {
parameters.put(paramName, new
Integer(paramValue));
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
}
if (paramType.equalsIgnoreCase(“int”)) {
try {
parameters.put(paramName, new
Integer(paramValue).intValue());
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
}
if
(paramType.equalsIgnoreCase(“java.lang.Double”)) {
try {
parameters.put(paramName, new
Double(paramValue));
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
}
if (paramType.equalsIgnoreCase(“double”)) {
try {
parameters.put(paramName, new
Double(paramValue).doubleValue());
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
}
}
}
}
}
XmlJasperInterface jasperInterface = new
XmlJasperInterface(outputType,
compiledDesign,
jdbcDriver,
jdbcUrl,
jdbcUser,
jdbcPassword,
parameters);
if (!jasperInterface.report()) {
System.exit(1);
}
}
public XmlJasperInterface(String outputType,
String compiledDesign,
String jdbcDriver,
String jdbcUrl,
String jdbcUser,
String jdbcPassword,
Map parameters) {
this.outputType = outputType;
this.compiledDesign = compiledDesign;
this.jdbcDriver = jdbcDriver;
this.jdbcUrl = jdbcUrl;
this.jdbcUser = jdbcUser;
this.jdbcPassword = jdbcPassword;
this.parameters = parameters;
}
public boolean report() {
try {
Class.forName(jdbcDriver);
Connection cn = DriverManager.getConnection(jdbcUrl,
jdbcUser, jdbcPassword);
JasperPrint jasperPrint =
JasperFillManager.fillReport(compiledDesign, parameters, cn);
if (TYPE_PDF.equals(outputType)) {
JasperExportManager.exportReportToPdfStream(jasperPrint,
System.out);
} else if (TYPE_XML.equals(outputType)) {
JasperExportManager.exportReportToXmlStream(jasperPrint,
System.out);
} else if (TYPE_RTF.equals(outputType)) {
JRRtfExporter rtfExporter = new JRRtfExporter();
rtfExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
rtfExporter.setParameter(JRExporterParameter.OUTPUT_STREAM, System.out);
rtfExporter.exportReport();
} else if (TYPE_XLS.equals(outputType)) {
JRXlsExporter xlsExporter = new JRXlsExporter();
xlsExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
xlsExporter.setParameter(JRExporterParameter.OUTPUT_STREAM, System.out);
xlsExporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,
Boolean.TRUE);
xlsExporter.exportReport();
} else if (TYPE_CSV.equals(outputType)) {
JRCsvExporter csvExporter = new JRCsvExporter();
csvExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
csvExporter.setParameter(JRExporterParameter.OUTPUT_STREAM, System.out);
csvExporter.exportReport();
} else if (TYPE_HTML.equals(outputType)) {
JRHtmlExporter htmlExporter = new JRHtmlExporter();
htmlExporter.setParameter(JRHtmlExporterParameter.JASPER_PRINT,
jasperPrint);
htmlExporter.setParameter(JRHtmlExporterParameter.OUTPUT_STREAM,
System.out);
htmlExporter.exportReport();
} else {
printUsage();
}
} catch (JRException e) {
e.printStackTrace();
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
private static void printUsage() {
System.out.println("XmlJasperInterface usage:");
System.out.println("\tjava XmlJasperInterface -oOutputType
-fCompiledDesign -dJdbcDriver -uJdbcUrl -nJdbcUser -pJdbcPassword
-rReportParameters\n");
System.out.println("\tOutput types:\t\thtml | pdf | xml | rtf |
xls | csv");
System.out.println("\tCompiled design:\tFilename of the compiled
Jasper design");
System.out.println("\tJDBC Driver:\tJdbc driver class name (jdbc
jar/zip must be in lib folder)");
System.out.println("\tJDBC Url:\tJdbc connection URL");
System.out.println("\tJDBC User Name:\tJdbc connection user
name");
System.out.println("\tJDBC Password:\tJdbc connection
password");
System.out.println("\tReport parameters:\treport parameters (ex.
-rOrderId@@java.lang.Integer@@10)");
System.out.println("\tReport parameters types
allowed:\tjava.lang.String (or String), java.lang.Integer (or int),
java.lang.Double (or double), java.lang.Boolean (or boolean),
java.util.Date");
System.out.println("\tStandard output:\tReport generated by
Jasper");
}
}
Remember that java must be installed and be visible from rails, the jdbc
database drivers (.jar / .zip) must go into jasper/lib under the
application root.
Hope this helps !