Showing posts with label Reporting. Show all posts
Showing posts with label Reporting. Show all posts

Wednesday, January 07, 2009

Read this first when you install BIRT

BIRT is great, but there is just one... annoying... thing... that no one seems to talk about.

You install BIRT, open the report perspective, create an element... and then HOW THE $!()#$ DO YOU EDIT IT'S PROPERTIES?

It's not the properties tab-- BIRT has a special properties tab. Here's how to load it up (and why oh why is this missing from the default report perspective?)

Window->Show View->Other...->Report Design>Property Editor

Now all of a sudden you have control over each element including adding hyperlinks. Whew!

Using styles from a CSS stylesheet in BIRT 2.3+

In BIRT 2.2, I would import a stylesheet and then apply the styles to my report. Unfortunately, this isn't very maintainable. Luckily Ben has found a solution to load styles from an external CSS file though there are contraints:
  • You must use BIRT 2.3+
  • Tag styling won't work-- for example, tr { color:red } will throw an error-- you have to give the style a name like .myrow { color:red }
  • The stylesheet must be in the same Eclipse project (project references are not good enough) at design time-- you can load from another location after deploying the report
  • Your style names must be all lowercase-- BIRT saves the names in your report as lower case even if they have uppercase characters and then they won't work once deployed
Here is the procedure:

  1. Upgrade Eclipse BIRT report designer to version 2.3.1
  2. If fixing an existing report, delete all currently used styles
  3. Right-click on "styles" in the outline, and choose "Use CSS file..."
  4. Choose your css file
  5. Check the box for "Include CSS file at view time" and enter
    /path/when/deployed/your.css as the URI (note: this option is missing in BIRT 2.2; if you tried to upgrade 2.2 to 2.3 read my other blog entry about how this is basically impossible)
  6. There will be some errors if your css defines styles for tag names because BIRT doesn't like that. It only accepts class names. Just ignore it.
  7. Format the report by right-clicking and applying styles from your css
  8. Deploy the report

Tuesday, January 06, 2009

Upgrading BIRT 2.2 to 2.3

Or let's be honest, reinstalling Eclipse.

It should be possible, using Eclipse Help>Software Updates>Find and Install to update BIRT. However, it never works.

If you try to update, it will look like it worked, but when you go to Help>About>Plugin Details BIRT will still be at 2.2.

You can go and delete BIRT out of the plugins directory and then try to install it, but then I found one of two things happens:
  1. Eclipse spins forever
  2. Eclipse throws the error "Eclipse BIRT Chart Runtime Feature (2.3.1...) requires feature 'org.eclipse.datatools.enablement.oda.feature (1.6.0)', or later version." The latter can be fixed by updating the Data Tools Platform. Then you can update BIRT. But it will still be at 2.2 after you restart.
It's easier to just start with a fresh install of Eclipse. Thank's BIRT!

Thursday, December 18, 2008

Changing the default styling of Birt

This is actually quite easy. Birt uses some JSP fragments for the loading bar and other stuff. You can find these in
birt.war/webcontent/birt/pages/control

And the associated styles are in styles.css in
birt.war/webcontent/birt/styles

There is also an images directory where you can change things such as the progress bar image.

Monday, May 19, 2008

BIRT deployment

BIRT is an Eclipse reporting project. It comes packaged as a war file you can deploy and with an Eclipse plug in for designing reports. The plug in has some quirks that I will document in another post.

The web application is fairly straightforward to deploy. I extracted it to birt.war and moved the directory into the deploy directory of JBoss.

You can begin using the application by copying your reports into birt.war in the deploy directory and then use included servlets for display. The following link covers the various servlets (frameset, run, preview, output):

http://www.eclipse.org/birt/phoenix/deploy/viewerUsage2.2.php

That covers linking to reports or running them crudely inside IFrames. If you want tighter integration with your application, BIRT includes a tag library for running reports inside JSPs. It includes two main tags, one which inserts the ajax viewer application and one which inserts the report. Unfortunately, neither passes XHTML validation. The report tag COULD but it has a bug that makes the Javascript free option crash the whole page.

In case you don't need XHTML compliance, just copy the birt.tld file into your application's WEB-INF/tld directory. For example:
liferay-portal.ear/portal-web.war/WEB-INF/tld

If you want XHTML compliance... it gets tougher. The trouble is that you can't put JavaScript inline in an XHTML file because various logic characters are interpreted as XML. What you need then is a JavaScript file you can include that can then work its magic on designed static elements. Rather than rehash the details of the whole file, here it is, birt.js, in all its glory. To use it, just place a div in your XHTML, give it a unique id, and call registerViewer with the ID and report name. Parameters should be included as hidden inputs inside the div. Note, all the hackery you see inside this file is because the IE people can't seem to get anything right, so I had to throw all sorts of hacks in to make it work (like resizing an IFrame doesn't work unless its inside a table):


/* BIRT report loader for XHTML
Loads BIRT reports into IE and FF using XHTML compliant code.
Create a DIV with an ID. Inside the DIU, place a script tag that calls registerReportViewer
*/

if(document.all)
window.attachEvent('onload',loadViewers);
else
window.addEventListener("load",loadViewers,false);

var reportViewers = new Array();

function registerReportViewer(divId, reportFileName) {
if(divId==null || reportFileName==null)
alert('registerReportViewer: A required parameter was null');
else
reportViewers[reportViewers.length]=new Array(divId, reportFileName);
//loadViewer('birtViewer','nr');
}

function loadViewers() {
for(i=0; i<reportViewers.length; i++) {
loadViewer(reportViewers[i][0], reportViewers[i][1]);
}
}

function loadViewer(viewerId, reportfile){
var divObj = document.createElement( "DIV" );
var bodyObj = document.body;
if( !bodyObj )
bodyObj = document.createElement("BODY");
bodyObj.appendChild( divObj );
divObj.style.display = "none";
var formObj = document.createElement( "FORM" );
divObj.appendChild( formObj );
var paramContainer = document.getElementById(viewerId);
if(paramContainer==null)
alert('Couldnt find element with id '+viewerId);
var oParams = paramContainer.getElementsByTagName('input');
if( oParams )
{
for( var i=0;i<oParams.length;i++ )
{
var param = document.createElement( "INPUT" );
formObj.appendChild( param );
param.TYPE = "HIDDEN";
param.name= oParams[i].name;
param.value= oParams[i].value;
}
}
var reportTable = document.createElement( "TABLE" );
reportTable.name=viewerId+"_iframe_table";
reportTable.id=reportTable.name;
reportTable.width="100%";
reportTable.style.border="0px";
var reportTBody = document.createElement ("TBODY"); // required by IE only, doesn't hurt FF
var reportRow = document.createElement( "TR" );
var reportCell = document.createElement( "TD" );
reportRow.appendChild(reportCell);
reportTBody.appendChild(reportRow);
reportTable.appendChild(reportTBody);

var reportIFrame = document.createElement("IFRAME");
reportIFrame.name = viewerId+"_iframe";
reportIFrame.id = reportIFrame.name;
reportIFrame.scrolling="no";
reportIFrame.frameBorder="0";
reportIFrame.style.height = "100%";
reportIFrame.style.width = "100%";
reportIFrame.style.border="0px";
reportIFrame.parentName = reportTable.name;
reportCell.appendChild(reportIFrame);
paramContainer.appendChild(reportTable);

// Resize the iframe to be the same size as the content, attach onload events for each browser
if(window.addEventListener) // Mozilla, FF, NS
reportIFrame.addEventListener('load', resizeEvent, false) ;
else // IE
reportIFrame.attachEvent("onreadystatechange", resizeEvent );

// Submit the form
formObj.action = "/birt/preview?__format=html&__report="+reportfile+".rptdesign&__masterpage=true";
formObj.method = "post";
formObj.target = reportIFrame.name;

// Bug fix for IE: IFrames created by JavaScript don't actually have a "name" in IE's internals
if(document.all) {
if(self.frames[reportIFrame.id].name!=reportIFrame.name) /* THIS IS A BUG FIX FOR IE: TARGET DOESNT WORK WITH JAVASCRIPT CREATED IFRAMES */
self.frames[reportIFrame.id].name = reportIFrame.name;
}
formObj.submit( );
}

function resizeEvent(evt) {
var ieKey = "srcElement";
var mozKey = "currentTarget";
var IFrameObj;
evt[mozKey] ? IFrameObj = evt[mozKey] : IFrameObj = evt[ieKey];
fitIframe(IFrameObj);
}

function fitIframe(IFrameObj) {
var IFrameDoc;
if (IFrameObj.contentDocument) {
// For NS6
IFrameDoc = IFrameObj.contentDocument;
IFrameObj.style.height=IFrameDoc.height+"px";
//alert('detected NS6');
} else if (IFrameObj.contentWindow) {
// For IE5.5 and IE6
IFrameDoc = IFrameObj.contentWindow.document;
if(IFrameDoc.body!=null) { // the IE event fires too often, and fires before IFrame is loaded, in which case doc==null. It fires AGAIN once it loads fully, so ignore the first time
try {
var table = document.getElementById(IFrameObj.parentName);
} catch (e) { alert('IE5.5+: Unable to located IFrames parent table: '+IFrameObj.parentName ); }
try {
var height=parseInt(IFrameDoc.body.clientHeight)+20;
table.style.height=height;//-IFrameDoc.body.offsetHeight;//+"px"; //IFrameDoc.body.scrollHeight-IFrameDoc.body.offsetHeight;
} catch (e) { alert('IE5.5+: Unable to get size of IFrame: '+IFrameObj.name ); }
} // if IFrameDoc!=null

} else if (IFrameObj.document) {
// For IE5
IFrameDoc = IFrameObj.document;
// document.getElementById("birtViewer_div").style.height=IFrameDoc.height;
try {
document.getElementById(IFrameObj.parentName).style.height=IFrameDoc.body.scrollHeight-IFrameDoc.body.offsetHeight;
} catch (e) { alert('IE 5.0: Unable to located IFrames parent table or get size of IFrame: '+IFrameObj.parentName ); }
//alert('detected ie5. IFrame body height:'+IFrameDoc.body.offsetHeight);
//IFrameObj.height="600"; //IFrameDoc.body.scrollHeight; //offsetheight works too
} else {
alert('fitIframe was unable to detect the browser version');
return true;
}
}


Tuesday, April 11, 2006

Using Subreports with JasperReports/JasperAssistant

Create Report
Add subreport element
Right click subreport
properties
look through properties.

Put the following:
Connection Expression $P{REPORT_CONNECTION}
DataSource Expression (blank)
Expression click the + and put, in quotes, the name of the jasper file to use as the subreport
make sure the type is set to java.lang.String
Parameter Expression Map: $P{REPORT_PARAMETERS_MAP} (optional)
Using cache: false

In the outline view, click the + next to the subreport
Add parameters for each parameter to pass to the subreport. Set the key to your parameter name. Set the value to a field or parameter.


Create new Report (the sub report)
Add parameters passed in from master
Add fields
Add query



One note, I haven't yet figured out how to load the subreport in a JSP... The simplest way is to dump it in the web apps classpath, such as WEB-INF/classes. Report back later on this...

Monday, February 27, 2006

Silently Print a PDF When It Loads (Automatically Print)

Spent a long time searching for this feature... it's called Silent Print. PDFs can have javascript embedded to print. Here's how to do it in a JSP:

Note tha the secret sauce is to get a writer and then add javascript to it like so: writer.addJavaScript("this.print(false);", false);


<%@page import="java.io.ByteArrayOutputStream,
java.io.IOException,
java.io.*,
javax.servlet.ServletException,
javax.servlet.ServletOutputStream,
javax.servlet.http.HttpServlet,
javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse,
com.lowagie.text.Chunk,
com.lowagie.text.Document,
com.lowagie.text.DocumentException,
com.lowagie.text.pdf.PdfWriter"%><%

Document document = new Document();
ByteArrayOutputStream baos = new ByteArrayOutputStream();

try {
PdfWriter writer = PdfWriter.getInstance(document, baos);
document.open();
writer.addJavaScript("this.print(false);", false);
document.add(new Chunk("Silent Auto Print"));
document.close();
} catch (DocumentException e) {
e.printStackTrace();
}

response.setContentType("application/pdf");
response.setContentLength(baos.size());
File f = new File(application.getRealPath("/js.pdf"));
OutputStream pout = new BufferedOutputStream(new FileOutputStream(f));

baos.writeTo(pout);
%>

Concatenate Two PDFs in a JSP using iText

This is an adaptation of the stand alone java file on the iText website to JSP:


<%@page import="java.io.FileOutputStream,
java.util.ArrayList,
java.util.List,

com.lowagie.text.Document,
com.lowagie.text.pdf.PRAcroForm,
com.lowagie.text.pdf.PdfCopy,
com.lowagie.text.pdf.PdfImportedPage,
com.lowagie.text.pdf.PdfReader,
com.lowagie.text.pdf.SimpleBookmark" %><%
try {
int pageOffset = 0;
ArrayList master = new ArrayList();
int f = 0;
String outFile = "/tmp/ouputPDF.pdf";
Document document = null;
PdfCopy writer = null;
while (f < 2) {
// we create a reader for a certain document
PdfReader reader = null;
if( f == 0) reader = new PdfReader(application.getRealPath("/Page1.pdf"));
else
reader = new PdfReader(application.getRealPath("/Page2.pdf"));
reader.consolidateNamedDestinations();
// we retrieve the total number of pages
int n = reader.getNumberOfPages();
List bookmarks = SimpleBookmark.getBookmark(reader);
if (bookmarks != null) {
if (pageOffset != 0)
SimpleBookmark.shiftPageNumbers(bookmarks, pageOffset, null);
master.addAll(bookmarks);
}
pageOffset += n;

if (f == 0) {
// step 1: creation of a document-object
document = new Document(reader.getPageSizeWithRotation(1));
// step 2: we create a writer that listens to the document
writer = new PdfCopy(document, new FileOutputStream(outFile));
// step 3: we open the document
document.open();
}
// step 4: we add content
PdfImportedPage ppage;
for (int i = 0; i < n; ) {
++i;
ppage = writer.getImportedPage(reader, i);
writer.addPage(ppage);
}
PRAcroForm form = reader.getAcroForm();
if (form != null)
writer.copyAcroForm(reader);
f++;
}
if (master.size() > 0)
writer.setOutlines(master);
// step 5: we close the document
document.close();
}
catch(Exception e) {
e.printStackTrace();
}
%>

Saving JasperReport Output to a Temporary PDF

JasperReports PDF Exporter does not support adding JavaScript to a PDF, so I need to use the iText PDF library to add the JavaScript and do some other processing. My previous examples showed how to push the PDF to the browser-- here's how to get it on the file system:


<%@page import="javax.sql.DataSource" %>
<%@page import="java.sql.Connection" %>
<%@page import="java.sql.CallableStatement" %>
<%@page import="java.sql.Statement" %>
<%@page import="java.sql.ResultSet" %>
<%@page import="java.util.Date" %>
<%@page import="javax.naming.InitialContext" %>
<%@page import="java.util.ArrayList" %>
<%@page import="java.lang.Integer" %>

<%@ page errorPage="error.jsp" %>
<%@ page import="net.sf.jasperreports.engine.*" %>
<%@ page import="net.sf.jasperreports.engine.util.*" %>
<%@ page import="net.sf.jasperreports.engine.export.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>

<%
InitialContext context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/myConnection/myOracleConnection");
Connection connection = dataSource.getConnection();
// Gets the .jasper file from the application location/reports/MyReport.jasper
File reportFile = new File(application.getRealPath("/reports/MyReport.jasper"));

JasperReport jasperReport = (JasperReport)JRLoader.loadObject(reportFile.getPath());

Map parameters = new HashMap();
parameters.put("ReportTitle", "My Report");
parameters.put("BaseDir", reportFile.getParentFile());

JasperPrint jasperPrint =
JasperFillManager.fillReport(
jasperReport,
parameters,
connection
);
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);

JRPdfExporter exporter = new JRPdfExporter();

// Get a pointer to the directory /tmp on the file system
File d = new File("/tmp");

// Now create a file with the prefix MyReport and suffix .pdf in /tmp.
// The filename will be something like MyReport19309.pdf
File f = File.createTempFile("MyReport", ".pdf", d) ;

// Create an outputstream to pass to the JasperReports exporter
OutputStream pout = new BufferedOutputStream(new FileOutputStream(f));
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, pout);

exporter.exportReport();
pout.flush(); // write any data left in the buffer
%>
Done outputting file.

Wednesday, February 01, 2006

Comparing Integers for JasperReports

Sometimes, you might want to display a different band depending on the record count. As usual, the solution is slightly convoluted because JasperReports doesn't use primitives anywhere (I feel so bad for the non-Java programmers who have to write reports with it). I set the following "Print when expression" for the text field:
new Boolean( ($V{REPORT_COUNT}).equals(new Integer(0)) )
Note that the evaluation time Of course, if the JP developers used primitives, it would just be $V{REPORT_COUNT} == 0 but why make it that easy!?!
This works too:
new Boolean( 0 == ($V{REPORT_COUNT}.intValue()) )

Note that the Evaluation time must be set correctly. For example, if you put the above in the title bar, and set evaluation to now, REPORT_COUNT will always be zero.

Friday, January 27, 2006

Images in JasperReports

If you are going to use images in JasperReports, use a relative path. For example, in iReports, you add an image, in its properties, in the image tab, make sure the path is like:

images/mikesNaughtyImage.gif

Then, to actually have your report access it, you need to place the image inside the classpath of the webapp the report is being run in. For example, this is MyReports, and WEB-INF/classes is in the classpath. So, the path for the image should be:

WEB-INF/classes/images/mikesNaughtyImage.gif

When the app is deployed, this will become:

appserver_webapp_path/MyReports/WEB-INF/classes/images/mikesNaughtyImage.gif

I remember having issues with this months ago, good to come up with a simple way to do it! (if not pretty).

Thursday, August 04, 2005

Exporting to Excel from JasperReports

Use the following Exporter code in your JSP:

JRXlsExporter exporter = new JRXlsExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "/myfile.xls");
ServletOutputStream pout = response.getOutputStream();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "inline;filename=\"myfile.xls\"");
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, pout);

exporter.exportReport();


When I loaded the JSP I got an error

JasperReports encountered this error :

java.lang.NoClassDefFoundError: org/apache/poi/hssf/util/HSSFColor$WHITE


The solution is to download poi-2.5.1.jar.
  • Search Google for the file and you will find a download link in a few seconds
  • Place the file in your webapps/$YOURAPPNAME/WEB-INF/lib directory and
  • restart Tomcat

You should be good now.

Two notes:

  • To test your files in iReports, you will need to go to iReports and the Tools>Options menu, then click the External Programs tab and for Excel, click the find button and navigate to Excel.exe on your hard drive.
  • If you want your excel file to be clean looking, you will have to be careful with the sizing and placement of your fields, etc. The exporter will create a grid based on your elements EXACTLY. So if you leave little spaces between text fields those will be cells. I try to have all my text fields line up exactly side by side and with those above them and leave no white space in the bands.

Friday, July 15, 2005

Styled Text in JasperReports

You can have formatted text inside a text field by setting its isStyledText property to true, then using JasperReports style tags to format the text. Here is an example of how bold text can be achieved:

<style isBold="true" pdfFontName="Helvetica-Bold">
More examples are at

http://jasperreports.sourceforge.net/samples/

Under the 'styled text' example.

Monday, June 27, 2005

More JasperReports

Images
paths to images are standard Java paths. The field
Image Expression:
should look like "images//checked.gif"

Set
Scale Image: RetainShape

Printing only when the image matches a field, set the 'Print when when expression' field to:
new Boolean($F{LASTNAME}.equalsIgnoreCase("Vader"))

You can use this to draw checkboxes-- just have an empty checkbox next to each item, then create an image with a filled checkbox only when a field has the right value.

Invisible pageFooter
My pageFooter doesn't show up! Solution is go to View>bands
Print when when expression:
new Boolean(true)

Pretty dumb, but there you go.

Concat Strings

You can concatenate fields like so
$F!{field1} + ", " + $F!{field2}

Multiple Pages for Reports
The reports I am writing are electronic copies of paper forms, and these forms are two pages long. Because they are medical documents and thus legal documents, they've got to look exactly like the paper forms. How do you get these two page reports to print out?

Hmm when I figure this out I'll post it :)

Tuesday, June 21, 2005

Passing in a parameter to JasperReports

First, I created an html file with the following (> and < style="font-size:85%;">form name=testForm id=testForm action="/jsp/test.jsp"

Enter user number: br
input type=field name="usernumber" br
input type=submit value="Retrieve Info" br

/form

Now, in /jsp/test.jsp

<%@page import="javax.sql.DataSource" %>
<%@page import="java.sql.Connection" %>
<%@page import="java.sql.CallableStatement" %>
<%@page import="java.sql.Statement" %>
<%@page import="java.sql.ResultSet" %>
<%@page import="java.util.Date" %>
<%@page import="javax.naming.InitialContext" %>
<%@page import="java.util.ArrayList" %>
<%@page import="java.lang.Integer" %>


<%@ page errorPage="error.jsp" %>
<%@ page import="net.sf.jasperreports.engine.*" %>
<%@ page import="net.sf.jasperreports.engine.util.*" %>
<%@ page import="net.sf.jasperreports.engine.export.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>

<%

InitialContext context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/test/testDB");
Connection connection = dataSource.getConnection();

File reportFile = new File(application.getRealPath("/reports/JasperTest.jasper"));

JasperReport jasperReport = (JasperReport)JRLoader.loadObject(reportFile.getPath());

Map parameters = new HashMap();
parameters.put("ReportTitle", "User Report");
parameters.put("BaseDir", reportFile.getParentFile());
Integer usernumber = null;
if( request.getParameter("usernumber") != null )
{
usernumber = new Integer(Integer.parseInt( request.getParameter("usernumber")));
parameters.put("usernumber", usernumber);
}
else
parameters.put("usernumber", new Integer(0));


JasperPrint jasperPrint =
JasperFillManager.fillReport(
jasperReport,
parameters,
connection
);

JRHtmlExporter exporter = new JRHtmlExporter();

StringBuffer sbuffer = new StringBuffer();

Map imagesMap = new HashMap();
session.setAttribute("IMAGES_MAP", imagesMap);

exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap);
exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "image.jsp?image=");

exporter.exportReport();
%>

All this does is pass usernumber=somethinghere into the JSP. The JSP then pulls that value of the request object and adds it to the parameters that will be used when calling the JasperReport.

Ok, now in JasperReport I just use the wizard and slap together a report as detailed in previous posts, with a fixed number in the SQL query where I want usernumber to be. The report gets some data from the database base on this parameter. Now go to objects tab & then parameters in the lower left, and add usernumber as an integer parameter. I put a default value expression of new Integer(0). Go to View> Report Query and change the fixed number to "$P!{usernumber}" without the quotes.

Save the report as JasperTest.jrxml-- if you get a warning about the project name and file name not matching just hit yes. Compile it using the button in the top right. Place the .jasper file in your webapps /reports/ directory and it should work now.

Getting Started with iReports

  • Download ireports from ireport.sourceforge.net
  • Unzipped to c:\iReports
  • Ran ireport.bat
  • Went to Tools> Classpath> Add JAR/folder
  • Added ojdbc14.jar which for me is located in
    C:\oracle\product\10.1.0\client_2\jdbc\lib
    The correct jar file will depend on your database
  • Then I went to Data sources and added a new datasource with the following parameters:
Blockquote
Type of Connection: Database JDBC Connection
Name: ORACLE
JDBC Driver: oracle.jdbc.driver.OracleDriver
JDBC URL: jdbc:oracle:thin:@{hostname}:{PORT}:{SUID in lower case}
server address: {hostname goes here}
Database: {SUID in all caps}
username/password: {your username}/{your password}


  • I clicked the test button and a prompt came up saying the connection was successful.
  • copy tools.jar from $Oracle_Home/jdk/lib into $ireports_home/lib
  • When creating a new report, the numeric fields did not work for me-- there were errors casting from Double to String. The numbers in the db are integers (the actual type is just number). What I did was go to
  • view > report fields
  • And change all fields that were 'Double' to long, and then:
  • Double click on the text boxes that will contain the values, click the text area tab, and change the display type to one that the original type can be cast to. I changed them to long as well. Voila! works.

JasperReports with Tomcat

Installed JRE & JDK 1.4.2_08 on server and a Windows PC.

Unzipped iReports-0.5.0 to the hard drive.

Copied tools.jar from the JRE to iReports-0.5.0/lib

Set up Tomcat 4.1.29 as usual on the server. Edited Catalina.conf to use the right JDK by setting JAVA_HOME then exporting it. Also added -Djava.awt.headless=true to JAVA_OPTS.

I created an application called reports

Went to webapps/reports/WEB-INF/lib

Copied the following files from iReports/lib

bsh-1.3.0.jar
commons-collections.jar
commons-logging-api.jar
itext-1.02b.jar
commons-beanutils.jar
commons-digester.jar
commons-logging.jar
jasperreports-0.6.7.jartools.jar

Looking at an old install, I also copied oracle.jar. Not sure where this came from but I assume it was needed to access our Oracle DB.

So now I create an index.html in /reports that has a link to /jsp/myreport.jsp

reports/jsp/myreport.jsp looks like this:

<%@page import="javax.sql.DataSource" %>
<%@page import="java.sql.Connection" %>
<%@page import="java.sql.CallableStatement" %>
<%@page import="java.sql.Statement" %>
<%@page import="java.sql.ResultSet" %>
<%@page import="java.util.Date" %>
<%@page import="javax.naming.InitialContext" %>
<%@page import="java.util.ArrayList" %>
<%@page import="java.lang.Integer" %>


<%@ page errorPage="error.jsp" %>
<%@ page import="net.sf.jasperreports.engine.*" %>
<%@ page import="net.sf.jasperreports.engine.util.*" %>
<%@ page import="net.sf.jasperreports.engine.export.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>

<% InitialContext context = new InitialContext(); DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/test/testDB"); Connection connection = dataSource.getConnection(); File reportFile = new File(application.getRealPath("/reports/JasperTest.jasper")); JasperReport jasperReport = (JasperReport)JRLoader.loadObject(reportFile.getPath()); Map parameters = new HashMap(); parameters.put("ReportTitle", "Address Report"); parameters.put("BaseDir", reportFile.getParentFile()); Integer userpatientid = new Integer(25394); parameters.put("PatientId", userpatientid); JasperPrint jasperPrint = JasperFillManager.fillReport( jasperReport, parameters, connection ); JRHtmlExporter exporter = new JRHtmlExporter(); StringBuffer sbuffer = new StringBuffer(); Map imagesMap = new HashMap(); session.setAttribute("IMAGES_MAP", imagesMap);
// for PDF output, use exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE);
// I know I know it says XLS, but it works! Otherwise there is whitespace between rows
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out); exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap); exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "image.jsp?image="); exporter.exportReport(); %>



Restart Tomcat and it works!

Monday, June 20, 2005

Jasper Reports X11 error

When running a Jasper Report, get the following error once, then a ClassDefNotFound error:

java.lang.InternalError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable

My original solution was to load dtlogin as a daemon, or xfvb if no dtlogin. However, this stopped working a few weeks later for unknown reasons.

A better solution, if using JDK 1.4+, is to edit start.sh in $CATALINA_HOME/bin and add the following to JAVA_OPTS variable:

-Djava.awt.headless=true

The necessary X libraries are then loaded by the JDK. Should take less system resources than running X itself, and be more reliable.

Labels

Blog Archive

Contributors