gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 18:00:30 30 4
gpt4 key购买 nike

我正在使用 JSON 数据测试 JasperReports,并遇到一个问题:从 Java 应用程序内生成时显示空值。这是我到目前为止所做的:

在 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"
}
]
}

这是生成的 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>

然后编写了一个简单的控制台应用程序来生成 PDF 格式的报告,但我得到一行包含 NULL 值。您会注意到,我将 JSON 嵌入到类中以简化测试代码,直到它正确运行,并且我确实将 JSON 数据传递到“JasperFillManager.fillReport()”调用中。这是我的 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();
}
}
}

谁能帮忙指出这有什么问题以及为什么报告没有生成数据?

最佳答案

出了什么问题

您没有正确选择数据。这意味着 JR 引擎为报告准备了错误的输入数据。

如何修复

您所需要做的就是将表达式传递给 JsonDataSource 实例以选择正确的数据。

示例:

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);
}

所有的魔法都在这里:

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

在表达式employees的帮助下,我们选择所有节点。您正在 JSS 的模板或数据适配器上执行相同的操作。

我们可以查看JsonDataSource类的源代码。我们需要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();
}
}

如果使用employees表达式选择数据,我们会得到具有全名、employeeid和phone属性的“employee”实体列表。

借助调试工具我们可以查看这行代码的数据:JsonNode 结果 = getJsonData(jsonTree, selectExpression);

The data of JsonNode result

如果使用您的代码:ByteArrayInputStream jsonDataStream = new ByteArrayInputStream(jsonData.getBytes()); 数据将是:

The JsonNode result without using exression

关于java - JasperReports - JSON 数据报告在 Java 中运行时显示空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60642696/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com