简体   繁体   English

JasperReports - JSON 数据报告在 Java 中运行时显示空值

[英]JasperReports - JSON Data Report Shows Null Values when run in Java

I am testing JasperReports with JSON data and running into a problem where null values are being displayed when generated from within a Java application.我正在使用 JSON 数据测试 JasperReports,但遇到了从 Java 应用程序生成时显示空值的问题。 Here is what I have done so far:这是我到目前为止所做的:

In Studio, I created a report that uses the JSON File data provider using a file containing the following JSON:在 Studio 中,我使用包含以下 JSON 的文件创建了一个使用 JSON 文件数据提供程序的报告:

{
    "employees": [
        {
            "fullname":"John Stark",
            "employeeid":"29388282773",
            "phone":"415-293-2928"
        },
        {
            "fullname":"Mike Goodmann",
            "employeeid":"2938828282",
            "phone":"415-293-2726"
        },
        {
            "fullname":"David Simpson",
            "employeeid":"2938822837",
            "phone":"415-293-9826"
        },
        {
            "fullname":"Chris Humpty",
            "employeeid":"2938275452",
            "phone":"415-293-1122"
        }
    ]
}

Here is the resulting jrxml file:这是生成的 jrxml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 7.1.0.final using JasperReports Library version 6.4.3  -->
<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="testreport" pageWidth="792" pageHeight="612" orientation="Landscape" columnWidth="752" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" >
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="testdata"/>
    <queryString language="json">
        <![CDATA[employees]]>
    </queryString>
    <field name="fullname" class="java.lang.String">
        <property name="net.sf.jasperreports.json.field.expression" value="fullname"/>
        <fieldDescription><![CDATA[fullname]]></fieldDescription>
    </field>
    <field name="employeeid" class="java.lang.Long">
        <property name="net.sf.jasperreports.json.field.expression" value="employeeid"/>
        <fieldDescription><![CDATA[employeeid]]></fieldDescription>
    </field>
    <field name="phone" class="java.lang.String">
        <property name="net.sf.jasperreports.json.field.expression" value="phone"/>
        <fieldDescription><![CDATA[phone]]></fieldDescription>
    </field>
    <title>
        <band height="79" splitType="Stretch">
            <staticText>
                <reportElement x="240" y="24" width="280" height="30" />
                <text><![CDATA[Employee List]]></text>
            </staticText>
        </band>
    </title>
    <columnHeader>
        <band height="65" splitType="Stretch">
            <staticText>
                <reportElement x="30" y="30" width="180" height="30" />
                <text><![CDATA[Full Name]]></text>
            </staticText>
            <staticText>
                <reportElement x="240" y="30" width="160" height="30" />
                <text><![CDATA[Employee Id]]></text>
            </staticText>
            <staticText>
                <reportElement x="430" y="30" width="180" height="30" />
                <text><![CDATA[Phone Number]]></text>
            </staticText>
            <staticText>
                <reportElement x="299" y="0" width="100" height="30" />
                <text><![CDATA[employeeid]]></text>
            </staticText>
            <staticText>
                <reportElement x="468" y="0" width="100" height="30" />
                <text><![CDATA[phone]]></text>
            </staticText>
        </band>
    </columnHeader>
    <detail>
        <band height="24" splitType="Stretch">
            <textField>
                <reportElement x="30" y="0" width="180" height="20" />
                <textFieldExpression><![CDATA[$F{fullname}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="241" y="0" width="159" height="20" />
                <textFieldExpression><![CDATA[$F{employeeid}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="430" y="0" width="180" height="20" />
                <textFieldExpression><![CDATA[$F{phone}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
</jasperReport>

Then wrote a simple console app to generate the report in PDF but I get one row with NULL values.然后编写了一个简单的控制台应用程序来生成 PDF 格式的报告,但我得到一行 NULL 值。 You will notice that I embedded the JSON into the class to simplify the test code until I get it to run correctly, and that I am indeed passing the JSON data into the "JasperFillManager.fillReport()" call.您会注意到我将 JSON 嵌入到类中以简化测试代码,直到我让它正确运行,并且我确实将 JSON 数据传递到“JasperFillManager.fillReport()”调用中。 Here is my Java code:这是我的Java代码:

public class ReportTester {
    String jsonData = "{\n" +
            "    \"employees\": [\n" +
            "        {\n" +
            "            \"fullname\":\"John Stark\",\n" +
            "            \"employeeid\":\"29388282773\",\n" +
            "            \"phone\":\"415-293-2928\"\n" +
            "        },\n" +
            "        {\n" +
            "            \"fullname\":\"Mike Goodmann\",\n" +
            "            \"employeeid\":\"2938828282\",\n" +
            "            \"phone\":\"415-293-2726\"\n" +
            "        },\n" +
            "        {\n" +
            "            \"fullname\":\"David Simpson\",\n" +
            "            \"employeeid\":\"2938822837\",\n" +
            "            \"phone\":\"415-293-9826\"\n" +
            "        },\n" +
            "        {\n" +
            "            \"fullname\":\"Chris Humpty\",\n" +
            "            \"employeeid\":\"2938275452\",\n" +
            "            \"phone\":\"415-293-1122\"\n" +
            "        }\n" +
            "    ]\n" +
            "}";
    String reportFile = "/testreport.jrxml";
    String outputPdf = "testreport.pdf";
    JasperReport jasperReport;

    public void printme() {
        try {
            InputStream employeeReportStream = getClass().getResourceAsStream(reportFile);
            jasperReport = JasperCompileManager.compileReport(employeeReportStream);

            ByteArrayInputStream jsonDataStream = new ByteArrayInputStream(jsonData.getBytes());
            JsonDataSource ds = new JsonDataSource(jsonDataStream);
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<String, Object>(), ds);

            JRPdfExporter exporter = new JRPdfExporter();
            exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
            exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(outputPdf));
            SimplePdfReportConfiguration reportConfig = new SimplePdfReportConfiguration();
            reportConfig.setSizePageToContent(true);
            reportConfig.setForceLineBreakPolicy(false);
            exporter.setConfiguration(reportConfig);

            exporter.exportReport();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Can anyone help point out what is wrong with this and why the report does not generate with data?任何人都可以帮助指出这有什么问题以及为什么报告没有生成数据?

What is wrong怎么了

You did not select data right.您没有正确选择数据。 It means that JR engine prepared wrong input data for the report.这意味着JR引擎为报告准备了错误的输入数据。

How to fix怎么修

All you need is to pass expression to the JsonDataSource instance for selecting right data.您只需要将表达式传递给JsonDataSource实例以选择正确的数据。

Example:例子:

JasperReport jasperReport;
try {
    try (InputStream inputStream = getClass().getResourceAsStream(reportTemplate)) {
        jasperReport = JasperCompileManager.compileReport(inputStream);
    }

    File outputFile = new File(outputFileName);
    SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
    ByteArrayInputStream jsonDataStream = new ByteArrayInputStream(jsonData.getBytes());
    JsonDataSource ds = new JsonDataSource(jsonDataStream, "employees");
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, Maps.newHashMap(), ds);

    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
         OutputStream fileOutputStream = new FileOutputStream(outputFile)) {
        JRPdfExporter exporter = new JRPdfExporter();

        exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
        exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(byteArrayOutputStream));
        exporter.setConfiguration(configuration);
        exporter.exportReport();
        byteArrayOutputStream.writeTo(fileOutputStream);
    }
} catch (IOException | JRException e) {
    throw new RuntimeException("Failed to build report", e);
}

All magic is here:所有的魔法都在这里:

JsonDataSource ds = new JsonDataSource(jsonDataStream, "employees");

With help of expression employees we are selecting all nodes.在表达式employees帮助下,我们选择了所有节点。 You are doing the same at template or at data adapter at JSS .您在JSS 的模板或数据适配器上做同样的事情。

We can view the source code of JsonDataSource class.我们可以查看JsonDataSource类的源码。 We need moveFirst method.我们需要moveFirst方法。

@Override
public void moveFirst() throws JRException {
    if (jsonTree == null || jsonTree.isMissingNode()) {
        throw 
            new JRException(
                EXCEPTION_MESSAGE_KEY_NO_DATA,
                (Object[])null);
    }

    currentJsonNode = null;
    JsonNode result = getJsonData(jsonTree, selectExpression);
    if (result != null && result.isObject()) {
        final List<JsonNode> list = new ArrayList<JsonNode>();
        list.add(result);
        jsonNodesIterator = new Iterator<JsonNode>() {
            private int count = -1;
            @Override
            public void remove() {
                list.remove(count);
            }

            @Override
            public JsonNode next() {
                count ++;
                return list.get(count);
            }

            @Override
            public boolean hasNext() {
                return count < list.size()-1;
            }
        };
    } else if (result != null && result.isArray()) {
        jsonNodesIterator = result.elements();
    }
}

In case selecting data with employees expression we have list of "employee" entities having fullname, employeeid and phone attributes.如果选择带有employees表达式的数据,我们有具有全名、雇员 ID 和电话属性的“雇员”实体列表。

With help of debugging tool we can view the data at this line of code: JsonNode result = getJsonData(jsonTree, selectExpression);在调试工具的帮助下,我们可以在这行代码中查看数据: JsonNode result = getJsonData(jsonTree, selectExpression);

JsonNode 结果的数据

In case using your code: ByteArrayInputStream jsonDataStream = new ByteArrayInputStream(jsonData.getBytes());如果使用您的代码: ByteArrayInputStream jsonDataStream = new ByteArrayInputStream(jsonData.getBytes()); the data will be:数据将是:

不使用表达式的 JsonNode 结果

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JasperReports - 如何在 Java 中使用远程 JSON 数据报告运行报告 - JasperReports - How to run a report using Remote JSON Data Report in Java 使用JasperReports API生成报告时获取空值 - Getting null values when generating report using JasperReports API Jasper 报告预览显示字段中的数据,但在通过 java 生成报告时它会打印 NULL - Jasper report preview shows data in field but while generating report through java it prints NULL Java:arraylist用于显示空值时显示为空 - Java : arraylist shows empty when it used to show null values 解析 JSON 数据时处理空值 - Handling null values when parsing JSON data 使用JavaBean数据源时在报表中获取空值 - Getting null values in report when using JavaBean Data Source 尝试使用Java打印JasperReports报告时,尝试再次查看该报告时,Tomcat Apache Server关闭 - On trying to print JasperReports report using Java, the Tomcat Apache Server is shutting down when trying to view the report again 如何使用Java代码中的子报表运行JasperReports的报表。 找不到子报表 - How to run JasperReports's report with subreport in java code. Not found subreport JasperReports API。 在报告中使用图像时出现错误:net.sf.jasperreports.engine.JRException:在以下位置找不到字节数据 - JasperReports API. Getting error when using Image in report: net.sf.jasperreports.engine.JRException: Byte data not found at 通过Java代码使用JasperReports创建PDF报告时出现Unicode问题 - Unicode issue when creating PDF report using JasperReports via Java code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM