How to fill report using JSON datasource without g

2019-01-19 23:46发布

I'm using Jasper Reports to build a simple report pdf. I have a JSON file that looks like this:

{"employees": [
    {"firstName" : "John", "lastName" : "Doe"},
    {"firstName" : "Anna", "lastName" : "Smith"},
    {"firstName" : "Peter", "lastName" : "Jones"}
]}

And I'm trying to read it in like this:

File file = new File("E:/Workspaces/jasperPDFreport/src/main/resources/emp.json");
JsonDataSource datasource = new JsonDataSource(file);

JasperDesign jasperDesign = JRXmlLoader.load("E:/Workspaces/jasperPDFreport/src/main/resources/jsonTemplate.jrxml");
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
Map parameters = new HashMap();
JasperPrint jasperPrint;
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, datasource);
JasperExportManager.exportReportToPdfFile(jasperPrint, "BasicReport.pdf");
JasperViewer.viewReport(jasperPrint);

However my the values from the JSON file are not passed to my pdf.

This is my Template:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.1.1.final using JasperReports Library version 6.1.1  -->
<!-- 2015-10-22T13:45:32 -->
<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="Blank_A4_2" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="9e494ebe-c1fb-4448-bcee-38994e9720f7">
    <!--property name="net.sf.jasperreports.json.source" value="emp.json"/-->
    <queryString language="json">
        <![CDATA[employees]]>
    </queryString>  
    <field name="firstName" class="java.lang.String">
        <fieldDescription><![CDATA[firstName]]></fieldDescription>
    </field>
    <field name="lastName" class="java.lang.String">
        <fieldDescription><![CDATA[lastName]]></fieldDescription>
    </field>
    <background>
        <band splitType="Stretch"/>
    </background>
    <detail>
        <band height="125" splitType="Stretch">
            <textField>
                <reportElement x="100" y="0" width="100" height="30" uuid="02b279da-3795-4655-8571-5a36a3ef378c"/>
                <textFieldExpression><![CDATA[$F{firstName}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="0" y="0" width="100" height="30" uuid="671e61ad-8d8f-48cb-969f-78c05a516398"/>
                <text><![CDATA[firstName]]></text>
            </staticText>
            <textField>
                <reportElement x="100" y="30" width="100" height="30" uuid="9d53f46f-a252-48b3-9213-8c3092c29f49"/>
                <textFieldExpression><![CDATA[$F{lastName}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="0" y="30" width="100" height="30" uuid="3b49affb-685a-4df2-a872-c0e6fdcab94b"/>
                <text><![CDATA[lastName]]></text>
            </staticText>
        </band>
    </detail>
</jasperReport>

Now you see the commented out line

property name="net.sf.jasperreports.json.source" value="emp.json"

If I comment this in, everything works as intended, I don't want to hard code my JSON values into the template, because later on I want to get them from a rest service, that's not ready yet. I do not understand, why the values are not getting parsed into the report, instead i just get two null values.

3条回答
贼婆χ
2楼-- · 2019-01-19 23:56

From JasperReports - JSON Data Source Sample (version 6.4.3)

The built-in JSON query executer (see the JsonQueryExecuter class) is a tool that uses the query string to produce a JsonDataSource instance, based on specific built-in parameters (or equivalent report properties). This query executer is registered via JsonQueryExecuterFactory factory class. In order to prepare the data source, the JSON query executer looks for the JSON_INPUT_STREAM parameter that contains the JSON source objects in the form of an java.io.InputStream. If no JSON_INPUT_STREAM parameter is provided, then the query executer looks for the alternate net.sf.jasperreports.json.source String parameter or report property that stores the path to the location of the JSON source file. JsonQueryExecuter runs the query over the input source and stores the result in an in-memory JsonDataSource object.

So if you do not want to use:

<property name="net.sf.jasperreports.json.source" value="emp.json"/>

You need to pass the file as java.io.InputStream in the parameter JSON_INPUT_STREAM

Hence you are currently passing it as datasource you should try something like this

params.put(JsonQueryExecuterFactory.JSON_INPUT_STREAM, new FileInputStream(file));
JasperFillManager.fillReportToFile(jasperReport, params);

If you instead like to use the new JsonQLQueryExecuterFactory JSONQL Data Source

params.put(JsonQLQueryExecuterFactory.JSON_INPUT_STREAM, new FileInputStream(file));
JasperFillManager.fillReportToFile(jasperReport, params);
查看更多
Bombasti
3楼-- · 2019-01-20 00:01

Take a look here for data source implementation that wraps a collection of JavaBean objects.

List<YourClass> yourBeanCollection = queryDataFromJSON();

JRDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(yourBeanCollection);

JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,
                reportParams, beanCollectionDataSource);

and in the report template import java.util and declare the collection which you "injected" in the report

<import value="java.util.*"/>
<field name="yourBeanCollection" class="java.util.List"/>

also take a look here for an example

查看更多
女痞
4楼-- · 2019-01-20 00:14

If you pass your json string as InputStream then it will works.

String reportContents = "{}" //your json
InputStream is = new ByteArrayInputStream(reportContent.getBytes());
Map params = new HashMap();
params.put(JsonQueryExecuterFactory.JSON_INPUT_STREAM, is);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params);
查看更多
登录 后发表回答