Creating a report from CSV with JasperReports

In this tutorial, we show how to create a report with JasperReports from a CSV data source.

JasperReports is a open-source reporting library. It can create reports in various formats including PDF, HTML, XLS, or CSV. JRCsvDataSource is a datasource implementation that reads a CSV stream.

The following application creates a report from from a CSV file with JasperReports library. The report is a PDF file.

$ tree
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── zetcode
    │   │           └── main
    │   │               ├── CommandLineRunner.java
    │   │               └── JasperCSVDataSource.java
    │   └── resources
    │       ├── items.csv
    │       └── report2.xml
    └── test
        └── java

This is the project structure.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zetcode</groupId>
    <artifactId>JasperCSVDataSource</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <dependencies>
        
        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>6.4.0</version>
        </dependency>
        
    </dependencies>    
    
</project>

The Maven pom.xml file contains the jasperreports dependency.

items.csv
pens, 23
bottles, 5
spoons, 6
chairs, 5
books, 12

The items.csv contains the data to be used in our report.

report2.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN"
   "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">

<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="report2" pageWidth="595" pageHeight="842" 
              columnWidth="555" leftMargin="20" rightMargin="20"
              topMargin="20" bottomMargin="20">
  
    <field name="Name" class="java.lang.String">
        <fieldDescription><![CDATA[name]]></fieldDescription>
    </field>
    
    <field name="Quantity" class="java.lang.Integer">
        <fieldDescription><![CDATA[quantity]]></fieldDescription>
    </field>
    
    <detail>
        <band height="15">
          
            <textField>
                <reportElement x="0" y="0" width="80" height="15" />
            
                <textElement textAlignment="Left" verticalAlignment="Middle"/>
            
                <textFieldExpression class="java.lang.String">
                    <![CDATA[$F{Name}]]>
                </textFieldExpression>
            </textField>          
          
            <textField>
                <reportElement x="90" y="0" width="80" height="15" />
                <textElement textAlignment="Right" verticalAlignment="Middle" />
            
                <textFieldExpression class="java.lang.Integer">
                    <![CDATA[$F{Quantity}]]>
                </textFieldExpression>
            </textField>          

        </band>
    </detail>
    
</jasperReport>

This is the report template file. The template contains two bands: columnHeader and detail.

<field name="Name" class="java.lang.String">
    <fieldDescription><![CDATA[name]]></fieldDescription>
</field>

<field name="Quantity" class="java.lang.Integer">
    <fieldDescription><![CDATA[quantity]]></fieldDescription>
</field>

There are two fields in the template. Fields are mapped to the elements of the data source. In our case, fields are mapped to the CSV column names.

<textField>
    <reportElement x="0" y="0" width="80" height="15" />

    <textElement textAlignment="Left" verticalAlignment="Middle"/>

    <textFieldExpression class="java.lang.String">
    <![CDATA[$F{Name}]]>
    </textFieldExpression>
</textField> 

A text field is an element that has an associated expression, which is evaluated with every iteration in the data source to obtain the text content. This text field displays the name of the item. A text field in a detail band is evaluated for each record in the data source. Since we have five records in the CSV file, the text field is evaluated five times.

JasperCSVDataSource.java
package com.zetcode.main;

import java.util.HashMap;
import java.util.Map;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRCsvDataSource;

public class JasperCSVDataSource {

    public void start() throws JRException {
        
        String xmlFile = "src/main/resources/report2.xml";
        JasperReport report = JasperCompileManager.compileReport(xmlFile);

        String[] columnNames = new String[] {"Name", "Quantity"};

        String fileName = "src/main/resources/items.csv";
        JRCsvDataSource ds = new JRCsvDataSource(fileName);
        ds.setColumnNames(columnNames);

        Map parameters = new HashMap();

        JasperPrint jprint = JasperFillManager.fillReport(report, parameters, ds);

        JasperExportManager.exportReportToPdfFile(jprint,
                "src/main/resources/report2.pdf");
    }
}

The JasperCSVDataSource creates a JasperPrint file from the CSV data source. JasperPrint represents a page-oriented document that can be viewed, printed, or exported to other formats. In our case, it is going to exported into PDF file.

String xmlFile = "src/main/resources/report2.xml";
JasperReport report = JasperCompileManager.compileReport(xmlFile);

The XML template file is compiled into a JasperReport. JasperReport is a compiled template ready to be filled with data.

String[] columnNames = new String[]{"Name", "Quantity"};

These are CSV column names. These column names are mapped into report field names.

JRCsvDataSource ds = new JRCsvDataSource(fileName);
ds.setColumnNames(columnNames);

JRCsvDataSource is a data source implementation that reads data from a CSV file.

JasperPrint jprint = JasperFillManager.fillReport(report, parameters, ds);

With the JasperFillManager.fillReport() method, we create a JasperPrint object; an object that can be viewed, printed or exported to other formats.

JasperExportManager.exportReportToPdfFile(jprint,
        "src/main/resources/report2.pdf");

The JasperExportManager.exportReportToPdfFile() method transforms the JasperPrint object into a PDF file.

CommandLineRunner.java
package com.zetcode.main;

public class CommandLineRunner {

    public static void main(String[] args) throws Exception {

        JasperCSVDataSource app = new JasperCSVDataSource();
        app.start();
    }
}

The CommandLineRunner sets up the application.

In this tutorial, we have created a report with JasperReports library from a CSV file. You might also be interested in these related tutorials: Creating a report with JapserReports API, Creating a table with JasperReports library, Using JasperReports' JRViewer to display report, and Java tutorial.