DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report

Using Dynamically Generated JFreeChart Charts and JasperReports

Masoud Kalali user avatar by
Masoud Kalali
·
Sep. 22, 09 · Interview
Like (0)
Save
Tweet
Share
22.06K Views

Join the DZone community and get the full member experience.

Join For Free

If you are reading this blog it means you want to use JasperReport with dynamic programmatically generated images. An example of such use cases in generating complex charts using JFreeChart and then including these charts into reports.

Each report in JasperReport uses a datasource to populate the fields, we need to use JRBeanCollectionDataSource which can be considered as a simple collection of JavaBeans. Each object in the JRBeanCollectionDataSource can be used to populate one row of the report or it can be used to prepare calculated values and so on.

Each Report in JasperReport is basically an XML file which describe the report. in our case the report description document is like:

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="DataSourceReport" pageWidth="595" pageHeight="842" columnWidth="515" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50">
<style name="Sans_Normal" isDefault="true" fontName="DejaVu Sans" fontSize="12" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false"/>
<style name="Sans_Bold" isDefault="false" fontName="DejaVu Sans" fontSize="12" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false"/>
<style name="Sans_Italic" isDefault="false" fontName="DejaVu Sans" fontSize="12" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false"/>
<field name="image" class="java.awt.image.BufferedImage"/>
<field name="description" class="java.lang.String"/>
<detail>
<band height="180">
<image scaleImage="RetainShape" hAlign="Center" isUsingCache="true" isLazy="true">
<reportElement x="67" y="17" width="344" height="140"/>
<imageExpression class="java.awt.Image"><![CDATA[$F{image}]]></imageExpression>
</image>
<textField>
<reportElement x="83" y="157" width="311" height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{description}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>

As you can see I defined two fields named image and description which are two property of the ReportBean objects included in the data source. The report looks as follow in the IreportDesigner (I am using NetBeans plugin for developing reports).

report in the designer

Lets see what is the JavaBean class we want to use to carry the report fields from our Java code to the JasperReport engine.

public class ChartBean {

public ChartBean(BufferedImage image, String description) {
setImage(image);
setDescription(description);
}



private java.awt.image.BufferedImage image;
private String description;

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public BufferedImage getImage() {
return image;
}

public void setImage(BufferedImage image) {
this.image = image;
}


}

Now we need to prepare the datasource for the report, to prepare the datasource I wrote a method like the following snippet which uses another method to extract the BufferedImage from the JFreeChart items which we want to include in the report.

public JRBeanCollectionDataSource prepareDataSource() {


List charts = new ArrayList();

for (int i = 0; i < 5; i++) {
JFreeChart chart = createChart("This is chart number: " + i);
BufferedImage bi = extractImage(chart, 800, 600);
ChartBean chartBean = new ChartBean(bi, "This is description for Chart: " + i);
charts.add(chartBean);
}

return new JRBeanCollectionDataSource(charts);
}

The createChart method create some sample charts which we will include in the report. the method is simpley creating some dummy ring charts without any specific and meaningful data.


private JFreeChart createChart(String chartTitle) {


DefaultPieDataset piedataset = new DefaultPieDataset();
piedataset.setValue("One", new Double(43.200000000000003D));
piedataset.setValue("Two", new Double(10D));
piedataset.setValue("Three", new Double(27.5D));
piedataset.setValue("Four", new Double(17.5D));
piedataset.setValue("Five", new Double(11D));
piedataset.setValue("Six", new Double(19.399999999999999D));


JFreeChart jfreechart = ChartFactory.createRingChart(chartTitle, piedataset, false, true, false);

RingPlot ringplot = (RingPlot) jfreechart.getPlot();
ringplot.setLabelFont(new Font("SansSerif", 0, 12));
ringplot.setNoDataMessage("No data available");
ringplot.setSectionDepth(0.34999999999999998D);
ringplot.setCircular(false);
ringplot.setLabelGap(0.02D);
return jfreechart;
}

The other method which need to be explained is extractImage which simply create a BufferedImage from a given JfreeChart object.


 public BufferedImage extractImage(JFreeChart chart, int width, int height) {
BufferedImage img =
new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);

Graphics2D g2 = img.createGraphics();
chart.draw(g2, new Rectangle2D.Double(0, 0, width, height));

g2.dispose();
return img;

}

Finally I have a method named showReport which uses the created datasource to prepare a report and then uses JRViewer to show the report. The code snippet is as follow:


  public void showReport(JRBeanCollectionDataSource dataSource) {

try {
Map parameters = new HashMap();
JasperDesign jasperDesign = JRXmlLoader.load(this.getClass().getResourceAsStream("/jasperdynamic/report.jrxml"));
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
JRViewer viewer = new JRViewer(jasperPrint);
viewer.setSize(850, 500);
viewer.setMinimumSize(new Dimension(850, 510));
viewer.setPreferredSize(new Dimension(850, 510));

this.setLayout(new BorderLayout(10, 10));

this.setSize(850, 500);

this.getContentPane().add(viewer);
this.setVisible(true);

} catch (Exception ex) {
ex.printStackTrace();
}
}

And the complete code for the application application class is as follow:


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jasperdynamic;

import javax.swing.JFrame;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import net.sf.jasperreports.view.JRViewer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.RingPlot;
import org.jfree.data.general.DefaultPieDataset;

/**
*
* @author masoud
*/
public class Main extends JFrame {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Main m = new Main();

m.showReport(m.prepareDataSource());

}

public JRBeanCollectionDataSource prepareDataSource() {


List charts = new ArrayList();

for (int i = 0; i < 5; i++) {
JFreeChart chart = createChart("This is chart number: " + i);
BufferedImage bi = extractImage(chart, 800, 600);
ChartBean chartBean = new ChartBean(bi, "This is description for Chart: " + i);
charts.add(chartBean);
}

return new JRBeanCollectionDataSource(charts);
}

public BufferedImage extractImage(JFreeChart chart, int width, int height) {
BufferedImage img =
new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);

Graphics2D g2 = img.createGraphics();
chart.draw(g2, new Rectangle2D.Double(0, 0, width, height));

g2.dispose();
return img;

}

public void showReport(JRBeanCollectionDataSource dataSource) {

try {
Map parameters = new HashMap();
JasperDesign jasperDesign = JRXmlLoader.load(this.getClass().getResourceAsStream("/jasperdynamic/report.jrxml"));
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
JRViewer viewer = new JRViewer(jasperPrint);
viewer.setSize(850, 500);
viewer.setMinimumSize(new Dimension(850, 510));
viewer.setPreferredSize(new Dimension(850, 510));

this.setLayout(new BorderLayout(10, 10));

this.setSize(850, 500);

this.getContentPane().add(viewer);
this.setVisible(true);

} catch (Exception ex) {
ex.printStackTrace();
}
}

private JFreeChart createChart(String chartTitle) {


DefaultPieDataset piedataset = new DefaultPieDataset();
piedataset.setValue("One", new Double(43.200000000000003D));
piedataset.setValue("Two", new Double(10D));
piedataset.setValue("Three", new Double(27.5D));
piedataset.setValue("Four", new Double(17.5D));
piedataset.setValue("Five", new Double(11D));
piedataset.setValue("Six", new Double(19.399999999999999D));


JFreeChart jfreechart = ChartFactory.createRingChart(chartTitle, piedataset, false, true, false);

RingPlot ringplot = (RingPlot) jfreechart.getPlot();
ringplot.setLabelFont(new Font("SansSerif", 0, 12));
ringplot.setNoDataMessage("No data available");
ringplot.setSectionDepth(0.34999999999999998D);
ringplot.setCircular(false);
ringplot.setLabelGap(0.02D);
return jfreechart;
}
}

Following image shows how the report will look like after we run the program. and the complete source code can be downloaded from Here

report in the designer

From http://weblogs.java.net/blog/kalali
Chart JFreeChart

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Documentation 101: How to Properly Document Your Cloud Infrastructure Project
  • Introduction Garbage Collection Java
  • Orchestration Pattern: Managing Distributed Transactions
  • Detecting Network Anomalies Using Apache Spark

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: