Added by David Kincade, last edited by Thomas Morgner on Oct 19, 2007  (view change)

Labels:

Enter labels to add to this page:
Wait Image 
Looking for a label? Just start typing.

JFreeReport Classic - Getting Started Developer's Guide

This document will help the new JFreeReport developer get started working with the JFreeReport Classic engine. It will outline how to setup a development environment, how to run through some sample reports, and describe (some of) the architecture of the classic engine.

NOTE: I am creating this document as I learn this myself ... so some of the information may be incorrect until I am corrected or I learn my lessons

Setting Up the Development Environment

When I setup my development environment, I used the Eclipse IDE and connected to the JFreeReport repository to get the classic engine code. The step-by-step instructions have already been documented elsewhere in the Wiki.

Running the Reporting Demo Application 

Using the already documented procedures for getting a project out of the "classic" branch of the source code repository, you should check out the project jfreereport-demo and set it up in the development environment and make sure it compiles cleanly. Once that is completed, run (as a Java Application) the org.jfree.report.ancient.demo.DemoFrontend class.

A window will be displayed that has a list of reports on the left side (organized in folders) and a description of the report on the right side. Below the report description is the dataset that the report will use.

Select the "Color and Letter Group Demo" ... then (after reading the description and reviewing the source data), clock the "Print Preview" button on the bottom of the window. After a few seconds, the report will be displayed in a new window. Page through the report and notice the report heading, page headings, details.

After being amazed at the crispness of the report, open the report description XML document ( .../source/org/jfree/report/ancient/demo/groups/data-groups.xml ) and see how this report is defined.

To help reading the XML document, review the document: Pentaho Advanced Reporting Guide - Understanding the Pentaho File Report Definition

Exe-Wrappers and Jar-File-Optimizers

Pentaho Reporting's architecture relies heavily on dynamic classloading. Tools which try to find unused classes to remove them from the final deployment jar-file cannot handle such cases and will not generate runnable applications with their efforts.

If you want to use such tools, make sure that all such size-optimizations are disabled for the Pentaho Reporting classes.

How and where to start with the engine

Right now the documentation we have can be considered ... improvable. So usually it is a good idea to get started by looking at the demos. (In the pentaho-reporting-classic-demo package.)

For the Java side of the reporting, I now assume that there is a a report definition file somewhere. To parse a report, you first need the URL to the report-definition (or a file-object, whatever you prefer), and then you feed that into the parser.

// from http://wiki.pentaho.org/display/Reporting/Pentaho+Reporting+XML+Definition+formats
private JFreeReport parseReport(URL in) throws ReportDefinitionException
{
    if (in == null)
    {
      throw new ReportDefinitionException("ReportDefinition Source is invalid");
    }

    try
    {
      ResourceManager manager = new ResourceManager();
      manager.registerDefaults();
      Resource res = manager.createDirectly(in, JFreeReport.class);
      return (JFreeReport) res.getResource();
    }
    catch(Exception e)
    {
      throw new ReportDefinitionException("Parsing failed", e);
    }
}

If your report-definition contained a data-source definition as well, this JFreeReport object can now be used for reporting.

To show the swing-preview-dialog:

JFreeReport report; // created elsewhere ..

      final PreviewDialog frame = new PreviewDialog(report);
      frame.pack();
      RefineryUtilities.positionFrameRandomly(frame);
      frame.setVisible(true);

or (you mentioned PDF) you can use this object to generate the desired content directly, for instance:

PdfReportUtl.createPdf(report, "/tmp/report.pdf");

*ReportUtil classes are available for all export types; if they do not provide enough flexibility, you can instantiate and configure the report processors manually as well. To send the data directly to the HttpResponse, simply use the createPdf(..) method that accepts an output-stream. Cleaning temporary files is just ugly, so we better dont create them in the first place.

How the data comes to the report

Since version 0.8.9, we provide several data-source-factory implementations to allow the reports to query the data for the reporting by themself. The two most interesting options are the "SQLDataFactory" and the "NamedStaticDataFactory". The SQL-datafactory uses JDBC to query a database, while the NamedStaticDataFactory uses Java-reflection to call a method in your code to return a dataset. For both data-factories you have the choice of whether you define them in XML or with Java-code.

Each report and sub-report has a "query" property that contains the name of a query defined in the data-source. Queries can be parametrized by simply inlining the parameter-name into the SQL-query.

Examples for XML-Definitions that use XML to define a SQL-DataSource can be found in the demo (package org.jfree.report.demo.features.datasource and org.jfree.report.demo.features.subreport).

(More on the format of SQL-DataSources: http://wiki.pentaho.org/display/Reporting/JFR9DataProcessing
Although this is part of the flow-engine documentation, the data-sources are the same on both systems. Why reinvent the wheel?)

Data-Source definitions can either be embedded in the report-definition xml file or can be stored in a separate file (which is referenced by the report-definition).

Examples:

Extended-XML with embedded data-source

<?xml version="1.0" encoding="ISO-8859-1"?>
<report-definition xmlns="http://jfreereport.sourceforge.net/namespaces/reports/legacy/ext" name="Quadrant For Region" query="default">
..
   <report-config>
..
    <data:sql-datasource xmlns:data="http://jfreereport.sourceforge.net/namespaces/datasources/sql">
      <data:config label-mapping="true"/>
      <data:connection>
        <data:driver>org.hsqldb.jdbcDriver</data:driver>
        <data:url>jdbc:hsqldb:./sql/sampledata</data:url>
        <data:properties>
          <data:property name="user">sa</data:property>
          <data:property name="pass"></data:property>
        </data:properties>
      </data:connection>
      <data:query name="actuals-by-region">
      SELECT
           QUADRANT_ACTUALS.REGION,
           QUADRANT_ACTUALS.DEPARTMENT,
           QUADRANT_ACTUALS.POSITIONTITLE,
           QUADRANT_ACTUALS.ACTUAL,
           QUADRANT_ACTUALS.BUDGET,
           QUADRANT_ACTUALS.VARIANCE
      FROM
           QUADRANT_ACTUALS
      WHERE
          REGION = ${REGION}
      ORDER BY
          REGION, DEPARTMENT, POSITIONTITLE
  </data:query>
      <data:query name="default">
      SELECT DISTINCT
           QUADRANT_ACTUALS.REGION
      FROM
           QUADRANT_ACTUALS
      ORDER BY
          REGION
  </data:query>
    </data:sql-datasource>
..
  </report-config>
..
</report-definition>

Extended-XML with external data-source:

<?xml version="1.0" encoding="ISO-8859-1"?>
<report-definition xmlns="http://jfreereport.sourceforge.net/namespaces/reports/legacy/ext" name="Quadrant For Region" query="default">
..
   <report-config>
    <data-factory href="sql-subreport.sqlds"/>
..
  </report-config>
..
</report-definition>

How to approach your reporting case

For your case, I would use a master-details report. A master-detail report uses sub-queries to retrieve additional information from the database based on parameter values given in the master report.

The master-report would simply query the employee-table. The employee-id is then passed as parameter to all detail reports, which query the employees education and children and so on.

For the picture, you could use a Image-URL-Field. This one accepts an URL and tries to load the image from there. The URL most likely comes from your database or you can use a expression to compute a suitable URL based on the data given in the employee-record.

How to get the report-definition

You can use the report-designer for that task. Design the report as usual, and when finished, publish the report into a directory. The publish generates a .xaction (which you can ignore) and a .xml file (which is the report-definition that can be used by our parser). As the report-designer still cant write a decent data-source definition, you have to add one manually afterwards.

Step-by-Step instructions do not work. i.e. cannot connect to SVN using the information provided on the page.

Posted by Anonymous at Jan 02, 2008 14:48

I used svn://source.pentaho.org/pentaho-reporting, the same URL in the instructions, and connected to SVN anonymously just fine. Please post details about your problem in the forums, where you can get help.

I have the same problem, impossible to get connected to the SVN. That is the error report:

"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 
svn: Can't connect to host 'source.pentaho.org': A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."

If you can help us, it would be great.

Thanks beforehand.

Posted by Anonymous at Jan 10, 2008 06:19

I used example in wiki and in jfreerepot-demo, but every try to parse report I have an:

org.jfree.resourceloader.ResourceCreationException: Unable to parse the document and

org.xml.sax.SAXException: No suitable root handler known for this document:

but i used the xml file by demo...

If you can help us, it would be great.

Luca 

Posted by Anonymous at Apr 03, 2008 11:25

When I select "Color and Letter Group Demo" and hit "Print Preview" in the demo, I get the following exception:ERROR: Unable to create the report; report definition contained errors.org.jfree.report.demo.util.ReportDefinitionException: Parsing failed
at org.jfree.report.demo.util.AbstractXmlDemoHandler.parseReport(AbstractXmlDemoHandler.java:68)at org.jfree.report.ancient.demo.groups.GroupsDemo.createReport(GroupsDemo.java:68)
at org.jfree.report.demo.util.DefaultPreviewHandler.attemptPreview(DefaultPreviewHandler.java:60)at org.jfree.report.demo.util.CompoundDemoFrame.attemptPreview(CompoundDemoFrame.java:255)
at org.jfree.report.demo.util.AbstractDemoFrame$PreviewAction.actionPerformed(AbstractDemoFrame.java:140)at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:231)at java.awt.Component.processMouseEvent(Component.java:5501)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3135)at java.awt.Component.processEvent(Component.java:5266)
at java.awt.Container.processEvent(Container.java:1966)at java.awt.Component.dispatchEventImpl(Component.java:3968)
at java.awt.Container.dispatchEventImpl(Container.java:2024)at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)at java.awt.Container.dispatchEventImpl(Container.java:2010)
at java.awt.Window.dispatchEventImpl(Window.java:1778)at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)ParentException: org.jfree.resourceloader.ContentNotRecognizedException: None of the selected factories was able to handle the given data: ResourceKey{schema=org.jfree.resourceloader.loader.URLResourceLoader, identifier=file:/C:/Compiere/CompiereEUL/pentaho/org/jfree/report/ancient/demo/groups/data-groups.xml, factoryParameters={}, parent=null}
at org.jfree.resourceloader.ResourceManager.create(ResourceManager.java:405)at org.jfree.resourceloader.ResourceManager.create(ResourceManager.java:329)
at org.jfree.resourceloader.ResourceManager.createDirectly(ResourceManager.java:315)at org.jfree.report.demo.util.AbstractXmlDemoHandler.parseReport(AbstractXmlDemoHandler.java:63)
at org.jfree.report.ancient.demo.groups.GroupsDemo.createReport(GroupsDemo.java:68)at org.jfree.report.demo.util.DefaultPreviewHandler.attemptPreview(DefaultPreviewHandler.java:60)
at org.jfree.report.demo.util.CompoundDemoFrame.attemptPreview(CompoundDemoFrame.java:255)at org.jfree.report.demo.util.AbstractDemoFrame$PreviewAction.actionPerformed(AbstractDemoFrame.java:140)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:231)
at java.awt.Component.processMouseEvent(Component.java:5501)at javax.swing.JComponent.processMouseEvent(JComponent.java:3135)
at java.awt.Component.processEvent(Component.java:5266)at java.awt.Container.processEvent(Container.java:1966)
at java.awt.Component.dispatchEventImpl(Component.java:3968)at java.awt.Container.dispatchEventImpl(Container.java:2024)
at java.awt.Component.dispatchEvent(Component.java:3803)at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892)at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)
at java.awt.Container.dispatchEventImpl(Container.java:2010)at java.awt.Window.dispatchEventImpl(Window.java:1778)
at java.awt.Component.dispatchEvent(Component.java:3803)at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
ERROR: ExceptionDialog.ERROR_0001 - UserErrororg.jfree.report.demo.util.ReportDefinitionException: Parsing failed
at org.jfree.report.demo.util.AbstractXmlDemoHandler.parseReport(AbstractXmlDemoHandler.java:68)at org.jfree.report.ancient.demo.groups.GroupsDemo.createReport(GroupsDemo.java:68)
at org.jfree.report.demo.util.DefaultPreviewHandler.attemptPreview(DefaultPreviewHandler.java:60)at org.jfree.report.demo.util.CompoundDemoFrame.attemptPreview(CompoundDemoFrame.java:255)
at org.jfree.report.demo.util.AbstractDemoFrame$PreviewAction.actionPerformed(AbstractDemoFrame.java:140)at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:231)at java.awt.Component.processMouseEvent(Component.java:5501)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3135)at java.awt.Component.processEvent(Component.java:5266)
at java.awt.Container.processEvent(Container.java:1966)at java.awt.Component.dispatchEventImpl(Component.java:3968)
at java.awt.Container.dispatchEventImpl(Container.java:2024)at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)at java.awt.Container.dispatchEventImpl(Container.java:2010)
at java.awt.Window.dispatchEventImpl(Window.java:1778)at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)ParentException: org.jfree.resourceloader.ContentNotRecognizedException: None of the selected factories was able to handle the given data: ResourceKey{schema=org.jfree.resourceloader.loader.URLResourceLoader, identifier=file:/C:/Compiere/CompiereEUL/pentaho/org/jfree/report/ancient/demo/groups/data-groups.xml, factoryParameters={}, parent=null}
at org.jfree.resourceloader.ResourceManager.create(ResourceManager.java:405)at org.jfree.resourceloader.ResourceManager.create(ResourceManager.java:329)
at org.jfree.resourceloader.ResourceManager.createDirectly(ResourceManager.java:315)at org.jfree.report.demo.util.AbstractXmlDemoHandler.parseReport(AbstractXmlDemoHandler.java:63)
at org.jfree.report.ancient.demo.groups.GroupsDemo.createReport(GroupsDemo.java:68)at org.jfree.report.demo.util.DefaultPreviewHandler.attemptPreview(DefaultPreviewHandler.java:60)
at org.jfree.report.demo.util.CompoundDemoFrame.attemptPreview(CompoundDemoFrame.java:255)at org.jfree.report.demo.util.AbstractDemoFrame$PreviewAction.actionPerformed(AbstractDemoFrame.java:140)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849)at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:231)
at java.awt.Component.processMouseEvent(Component.java:5501)at javax.swing.JComponent.processMouseEvent(JComponent.java:3135)
at java.awt.Component.processEvent(Component.java:5266)at java.awt.Container.processEvent(Container.java:1966)
at java.awt.Component.dispatchEventImpl(Component.java:3968)at java.awt.Container.dispatchEventImpl(Container.java:2024)
at java.awt.Component.dispatchEvent(Component.java:3803)at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892)at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822)
at java.awt.Container.dispatchEventImpl(Container.java:2010)at java.awt.Window.dispatchEventImpl(Window.java:1778)
at java.awt.Component.dispatchEvent(Component.java:3803)at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

Posted by Anonymous at Apr 25, 2008 18:08

I am also having this problem, Not able to connect to SVN. below is the error report:

"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 
svn: Can't connect to host 'source.pentaho.org': A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."

Please help

Posted by Anonymous at May 07, 2008 04:36

Hi,

I am getting the same problem , while connecting to SVN. Please help me .
Thanks,Raja,  raj786_bangalore@yahoo.co.in

Getting the below message:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. svn: Can't connect to host 'source.pentaho.org': A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. svn: Can't connect to host 'source.pentaho.org': A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. svn: Can't connect to host 'source.pentaho.org': A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

Posted by Anonymous at Jul 03, 2008 16:41