Friday, May 15, 2009

Ruby meet Groovy. Groovy,Ruby meet Jasper

I had a longstanding user request to produce a JasperReport that was tied to an old as400 datasource.  When rails came on the scene the report was no longer valid, but was needed for ongoing operations.  Short term I decided to retool the report, query, and parameters using iReport. The user would let me know when she needed the report which I would run directly from iReport locally and email to her. However, I was not happy and more importantly the user was very dissatisfied.  So my first reaction was to create a pdf using prawn which worked but did not look near as good as the old report.  My next thought was to reformat the prawn code but this would take considerable time and I already had a very nice looking report but required java, jasperreports, and some groovy.  Soon visions of queues, schema changes, new models, jruby deployment started stirring along with the realization that I did not have the time to make it happen.  So I continued the clunky way until today when I realized that I could web enable the report simply my uploading the relevant jrxml to the java app server, making small changes to the groovlet, and a simple redirect from a rails controller.  In less than 15 minutes I created the following rails code:

class ScodesController < ApplicationController
  def create
    scodes_url = "#{BASE_SCODES_URL}?startDate=#{start_date}&endDate=#{end_date}"
    redirect_to scodes_url
  end
end



and groovy code:

import groovy.sql.Sql
import java.sql.ResultSet
import java.sql.SQLException
import net.sf.jasperreports.engine.*
import net.sf.jasperreports.engine.design.JasperDesign
import net.sf.jasperreports.engine.xml.JRXmlLoader
import com.baldwinmutual.BmicJasper

String path = context.getRealPath("forms") + "/sCodeListForLegacy.jrxml"
reportParameters = new HashMap()
def startDate = params.startDate
def endDate   = params.endDate
db = Sql.newInstance('jdbc:mysql://legacy.bmic/legacy_bmic_production',
                     'user','pass',
                     'com.mysql.jdbc.Driver')
reportParameters.put("EFFDA",startDate)
reportParameters.put("EXPDA",endDate)
inputFile = new File(path);
baos = new ByteArrayOutputStream()
jasperizer = new BmicJasper(db.getConnection())
baos = jasperizer.setParameters( reportParameters )
                 .compileReport( inputFile )
                 .fillReport()
                 .createReportStream()
response.setHeader("Expires", "30")
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0")
response.setHeader("Pragma", "public")
// setting the content type
response.setContentType("application/pdf")
// the contentlength is needed for MSIE!!!
response.setContentLength(baos.size());
// write ByteArrayOutputStream to the ServletOutputStream
ot = response.getOutputStream()
baos.writeTo(ot)
ot.flush()