[英]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?任何人都可以帮助指出这有什么问题以及为什么报告没有生成数据?
You did not select data right.您没有正确选择数据。 It means that JR engine prepared wrong input data for the report.
这意味着JR引擎为报告准备了错误的输入数据。
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);
In case using your code: ByteArrayInputStream jsonDataStream = new ByteArrayInputStream(jsonData.getBytes());
如果使用您的代码:
ByteArrayInputStream jsonDataStream = new ByteArrayInputStream(jsonData.getBytes());
the data will be:数据将是:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.