Create Jasper Report PDF form from JSON Object or JSON String
Asked Answered
S

4

16

It is fine when create the Jasper report(PDF, Excel, Csv) by using JRBeanCollectionDataSource. It means that the .jrxml file accepts the collection of pojo as a input to process the report.

Now, I have been trying to create the jasper report with the same .jrxml but from JSON Object. I tried the following, but all values are null in pdf report

Resource resource = new ClassPathXmlApplicationContext().getResource("classpath:reports/project.jrxml");
JsonDataSource ds = new JsonDataSource(new File("c:\myjson.json"));
jasperDesign = JRXmlLoader.load(resource.getInputStream());
JasperReport jasperReport  = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,  parameters,  ds);
JasperExportManager.exportReportToPdfFile(jasperPrint, destination+fileName+".pdf");

Can any one help me?

Shedd answered 18/7, 2012 at 8:14 Comment(1)
Did you ever get this working? I'm trying the same thing nowStanstance
S
20

I've just been struggling with using JSON as the DataSource to a Jasper Report and with a lack of decent examples on the Net I thought I would post this here for future reference.

This example is how to use iReport Designer and a JSON DataSource.

Firstly, the input JSON:

{ 
    "userName": "Evil Raat",
    "details": {
        "email": "[email protected]"
    }
}

Then create a JSON DataSource in iReport Designer and point it at your file (leaving all the other details as their defaults)

Next you can use the following jrxml template to render the above JSON into a report:

<?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="sample" language="groovy" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="a894078a-929b-4aae-a1d0-46485f0f8835">
    <property name="ireport.zoom" value="1.0"/>
    <property name="ireport.x" value="0"/>
    <property name="ireport.y" value="0"/>
    <queryString language="json">
        <![CDATA[]]>
    </queryString>
    <field name="userName" class="java.lang.String">
        <fieldDescription><![CDATA[userName]]></fieldDescription>
    </field>
    <field name="userEmail" class="java.lang.String">
        <fieldDescription><![CDATA[details.email]]></fieldDescription>
    </field>
    <title>
        <band height="200" splitType="Stretch">
            <textField>
                <reportElement uuid="3b74775b-4555-43c3-bdf2-1677145c8660" x="0" y="31" width="555" height="20"/>
                <textElement textAlignment="Right">
                    <font fontName="Helvetica" size="12" isBold="true"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{userName}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement uuid="aa6cc7c8-2ca1-4f0f-92e2-c466083daba0" x="0" y="54" width="555" height="20"/>
                <textElement textAlignment="Right">
                    <font fontName="Helvetica" size="12" isBold="true"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{userEmail}]]></textFieldExpression>
            </textField>
        </band>
    </title>
</jasperReport>

NOTE: You must define the field elements first, before any they can be used. They should be the JSON path from the root of the JSON input file using standard dot notation. See the fieldDescription elements above for examples.

Once your field is defined you can use its computed value in a text field or whatever:

Hope that helps some people.

Schnapp answered 20/3, 2013 at 8:24 Comment(3)
What about arrays of object. How do you handle them. Especially to place them in details band?Clough
Sorry I stopped working with Jasper Reports not long after this post so I've no idea.Schnapp
Got the same question as @Clough and found the answer here #42822483Lingenfelter
D
7

This is how I handle json arrays in jasper

Lets say I want to report off the following array.

[
  {"name":"Jerry", "value":"Jesus"},
  {"name":"Gideon", "value": "Loves"},
  {"name":"Eva", "value": "You"}
]

When designing the report, make sure you name the fields the exact same name as your json field name. So in the designer I would add two fields called name and value. You can even add as many parameters to the report designer as needed. For this example, I will add a parameter called title in Jasper Studio.

Now here is the java code that will create the jasper report based off of this test array. I will hard code the json data in the code, but you can load from file or whatever you feel is best. I commented the code to explain what is happening.

import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.data.JsonDataSource;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperPrint;
import org.apache.commons.codec.binary.Base64;
import java.util.HashMap;
import java.util.Locale;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.io.*;

//Class Name. This must match the class name you put in your build.gradle file
public class JasperPDFExample {
 public static void main(String[] args) {
  try {
   try {
    //Our json object. This can be loaded from file
    String rawJsonData = "[{\"name\":\"Jerry\", \"value\":\"Jesus\"},"
                       + "{\"name\":\"Gideon\", \"value\": \"Loves\"},"
                       + "{\"name\":\"Eva\", \"value\": \"You\"}"
                       + "]";
    //Load compiled jasper report that we created on first section.
    JasperReport report = (JasperReport) JRLoader.loadObject(new File("/home/jerry/Sample.jasper"));
    //Convert json string to byte array.
    ByteArrayInputStream jsonDataStream = new ByteArrayInputStream(rawJsonData.getBytes());
    //Create json datasource from json stream
    JsonDataSource ds = new JsonDataSource(jsonDataStream);
    //Create HashMap to add report parameters
    Map parameters = new HashMap();
    //Add title parameter. Make sure the key is same name as what you named the parameter in jasper report.
    parameters.put("title", "Jasper PDF Example");
    //Create Jasper Print object passing report, parameter json data source.
    JasperPrint jasperPrint = JasperFillManager.fillReport(report, parameters, ds);
    //Export and save pdf to file
    JasperExportManager.exportReportToPdfFile(jasperPrint,"/home/jerry/jasperpdfexample.pdf");
   } catch (JRException ex) {
    ex.printStackTrace();
    throw new RuntimeException(ex);
   } catch (Exception ex) {
    ex.printStackTrace();
    throw new RuntimeException(ex);
   }
  } catch (Exception ex) {
   ex.printStackTrace();
   throw new RuntimeException(ex);
  }
 }
}

Thanks to https://mis.io/pub/how-to-create-a-jasper-pdf-report-from-a-json-datasource-in-java/ I was able to get this to work along with setting up java for jasper using gradle build tool.

Decent answered 20/9, 2017 at 5:36 Comment(1)
perfect solutionDenisdenise
H
0

You shoot yourself in the foot if you do it in Java.

A Groovy example is much more easy:

@Grab(group='net.sf.jasperreports', module='jasperreports', version='6.17.0')

import net.sf.jasperreports.engine.JasperCompileManager
import net.sf.jasperreports.engine.JasperFillManager
import net.sf.jasperreports.engine.JasperExportManager
import net.sf.jasperreports.engine.data.JsonDataSource

def xmlFile = "report.xml"
def jrReport = JasperCompileManager.compileReport(xmlFile)

def url = 'https://jsonplaceholder.typicode.com/users'
def is = new URL(url).openStream()
def ds = new JsonDataSource(is)

def params = [:]
def jrPrint = JasperFillManager.fillReport(jrReport, params, ds)

JasperExportManager.exportReportToPdfFile(jrPrint, "report.pdf")

Report template:

<?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="report" topMargin="20" bottomMargin="20">

    <queryString language="json">
        <![CDATA[]]>
    </queryString>

    <field name="id" class="java.lang.Long"/>
    <field name="name"/>
    <field name="username"/>

    <detail>
        <band height="15">

            <textField>
                <reportElement x="0" y="0" width="50" height="15"/>
                <textElement textAlignment="Right" verticalAlignment="Middle"/>
                <textFieldExpression class="java.lang.Long">
                    <![CDATA[$F{id}]]>
                </textFieldExpression>
            </textField>

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

                <textElement textAlignment="Left" verticalAlignment="Middle"/>
                <textFieldExpression>
                    <![CDATA[$F{name}]]>
                </textFieldExpression>
            </textField>

            <textField>
                <reportElement x="190" y="0" width="100" height="15" />
                <textElement textAlignment="Right" verticalAlignment="Middle"/>
                <textFieldExpression>
                    <![CDATA[$F{username}]]>
                </textFieldExpression>
            </textField>

        </band>
    </detail>

</jasperReport>

In the example, we get data from the popular API test website https://jsonplaceholder.typicode.com/users and pick three fields to be displayed in our report.

run with $ groovy report.gvy

Hormonal answered 7/12, 2021 at 17:41 Comment(0)
M
0

The rest of the answers are still correct, but there are some non-obvious changes in JasperReports Library 7.0 that can be confusing (see #458 and #459 issues).

Imagine that your *.jrxml-template is correct (or already successfully converted from 6.X to 7.X in Jaspersoft Studio using JasperReports -> Update JasperReports files menu) and you want to generate a PDF file using your own Java-application.

In 7.0 the basic net.sf.jasperreports.jasperreports library was separated into multiple sub-libraries. In order to get the templates with JSON Data Source work you must (at least) include these dependencies (this example using Maven syntax):

...
<dependencies>
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports</artifactId>
        <version>7.0.0</version>
    </dependency>
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports-json</artifactId>
        <version>7.0.0</version>
    </dependency>
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports-pdf</artifactId>
        <version>7.0.0</version>
    </dependency>
    ...
</dependencies>
...

Then in your Java code (notice the import lines):

import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.json.data.JsonDataSource;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws JRException, FileNotFoundException {
        JasperReport report = JasperCompileManager.compileReport("path/to/template.jrxml");
        JasperPrint jasperPrint = JasperFillManager.fillReport(report, new HashMap<>(), new JsonDataSource(new FileInputStream("path/to/datasource.json")));
        JasperExportManager.exportReportToPdfFile(jasperPrint, "exported.pdf");
    }
}

Depending on your template, you may also need jasperreports-functions, jasperreports-jdt and jasperreports-fonts sub-libraries. They are also located in Maven Central under net.sf.jasperreports groupId.

Myron answered 18/7, 2024 at 11:15 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.