主报表在 Jaspersoft Studio 中不显示带有 Java 个 Beans 的基本子报表
The master report does not show basic subreport with Java Beans at Jaspersoft Studio
我在 Jaspersoft Studio 中使用 JavaBeans 生成基本报告 (master/subreport) 时遇到问题。
我创建了 TestMainReport.jrxml 和 TestSubreport.jrxml.
TestMainReport.jrxml 包含两个静态文本字段,在标题栏中标记为 "A Title"
,在摘要栏中标记为 "A Summary"
。
TestSubreport.jrxml 包含两个静态文本字段,标题 "Subreport Title"
和摘要带 "Subreport Summary"
。
我已经为它们分配了 JavaBeans 数据适配器,它们没有被使用(尽管 JavaBean 字段被映射到主报表中。我只是碰巧没有将它们映射到子报表中,因为它们没有被使用)。
已将子报表元素添加到摘要带中的主报表。
当我尝试生成每一份报告时,这两份报告都能很好地单独生成。但是,子报表静态文本不会出现在主报表中。
我原以为子报表的静态文本会出现在主报表中。
我做错了什么?
TestMainReport.jrxml
<?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="TestMainReport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="0d969cfb-66d2-442f-b7a4-5a9e1a40c3ae">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Customer Info Data Adapter"/>
<field name="birthday" class="java.time.LocalDate">
<fieldDescription><![CDATA[birthday]]></fieldDescription>
</field>
<field name="observacao" class="java.lang.String">
<fieldDescription><![CDATA[observacao]]></fieldDescription>
</field>
<field name="orderNumber" class="java.lang.Integer">
<fieldDescription><![CDATA[orderNumber]]></fieldDescription>
</field>
<field name="phone" class="java.lang.String">
<fieldDescription><![CDATA[phone]]></fieldDescription>
</field>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="email" class="java.lang.String">
<fieldDescription><![CDATA[email]]></fieldDescription>
</field>
<title>
<band height="79" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="db07ac65-15f6-4190-b1db-9d445456f306"/>
<text><![CDATA[A Title]]></text>
</staticText>
</band>
</title>
<summary>
<band height="215" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="08c03e87-2b15-4eb1-b404-b7dce6dfb890"/>
<text><![CDATA[A Summary]]></text>
</staticText>
<subreport>
<reportElement x="0" y="30" width="560" height="150" uuid="c292246e-1ffa-4f08-a783-a0b05b28be76"/>
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
<subreportExpression><![CDATA["TestSubreport.jasper"]]></subreportExpression>
</subreport>
</band>
</summary>
</jasperReport>
TestSubreport.jrxml
<?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="TestSubreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="d5dd9821-786d-4312-81c9-fd77f1abfb8a">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Customer Addresses Data Adapter"/>
<title>
<band height="79" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="4c9fdc83-4039-4eed-b593-448898853071"/>
<text><![CDATA[Subreport Title]]></text>
</staticText>
</band>
</title>
<summary>
<band height="42" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="4bb9ba45-548a-4e87-a543-472b0f960487"/>
<text><![CDATA[Subreport Summary]]></text>
</staticText>
</band>
</summary>
</jasperReport>
CustomerInfoDataSource.java
package testdatasource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class CustomerInfoDataSource {
public static Collection<CustomerInfo> getCustomerInfo() {
List<CustomerInfo> info = new ArrayList<>();
info.add(new CustomerInfo(1, "Mario", "mario@mario.com.br", LocalDate.now(), "14 912345678", "Observação Mario"));
return info;
}
}
CustomerInfo.java
package testdatasource;
import java.time.LocalDate;
public class CustomerInfo {
private final int orderNumber;
private final String name;
private final String email;
private final LocalDate birthday;
private final String phone;
private final String observacao;
public CustomerInfo(int orderNumber, String name, String email, LocalDate birthday, String phone, String observacao) {
this.orderNumber = orderNumber;
this.name = name;
this.email = email;
this.birthday = birthday;
this.phone = phone;
this.observacao = observacao;
}
public int getOrderNumber() {
return orderNumber;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public LocalDate getBirthday() {
return birthday;
}
public String getPhone() {
return phone;
}
public String getObservacao() {
return observacao;
}
}
CustomerAddressDataSource.java
package testdatasource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class CustomerAddressDataSource {
public static Collection<CustomerAddress> getCustomerAddresses() {
List<CustomerAddress> addresses = new ArrayList<>();
addresses.add(new CustomerAddress("Casa 1", "Rua Tal", "123", null, "Jardim Márcia", "Agudos", "17400-000", "Perto da caixa d'água"));
addresses.add(new CustomerAddress("Casa 2", "Rua Tal", "456", null, "Jardim Márcia", "Agudos", "17400-000", "Perto da caixa d'água"));
return addresses;
}
}
CustomerAddress.java
package testdatasource;
public class CustomerAddress {
private final String title;
private final String street;
private final String number;
private final String complement;
private final String bairro;
private final String city;
private final String cep;
private final String referencePoint;
public CustomerAddress(String title, String street, String number, String complement, String bairro, String city,
String cep, String referencePoint) {
this.title = title;
this.street = street;
this.number = number;
this.complement = complement;
this.bairro = bairro;
this.city = city;
this.cep = cep;
this.referencePoint = referencePoint;
}
public String getTitle() {
return title;
}
public String getStreet() {
return street;
}
public String getNumber() {
return number;
}
public String getComplement() {
return complement;
}
public String getBairro() {
return bairro;
}
public String getCity() {
return city;
}
public String getCep() {
return cep;
}
public String getReferencePoint() {
return referencePoint;
}
}
来自TestMainReport.jrxml的输出:
来自TestSubreport.jrxml的输出:
怎么了?
您没有为子报表指定数据源。您设置了 connectionExpression (<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
) 而不是这个。该连接可以在基于 jdbc 的数据源(报告)的情况下为您提供帮助,但对您的情况没有帮助。
解决方案 1 - 使用 dataSourceExpression
您应该为子报表指定数据源。您可以这样声明子报表元素:
<subreport>
<reportElement x="0" y="30" width="560" height="150"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource(testdatasource.CustomerAddressDataSource.getCustomerAddresses())]]></dataSourceExpression>
<subreportExpression><![CDATA["TestSubreport.jasper"]]></subreportExpression>
</subreport>
在这种情况下,CustomerAddressDataSource class 将用于填充子报表。
解决方案 2 - 使用数据适配器的外部定义
您可以将子报表的数据适配器导出到文件中,并将其保存到与模板相同的文件夹中(如果您不想指定数据适配器文件的路径)。
您可以在上下文菜单的帮助下导出 数据适配器 定义 JSS (Jaspersoft Studio):
在您的情况下 - 它将是 CustomerAddressesDataAdapter.xml,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<beanDataAdapter class="net.sf.jasperreports.data.bean.BeanDataAdapterImpl"><name>Customer Addresses Data Adapter</name><factoryClass>testdatasource.CustomerAddressDataSource</factoryClass><methodName>getCustomerAddresses</methodName><useFieldDescription>false</useFieldDescription><classpath>C:\somepath\library_with_beans.jar</classpath></beanDataAdapter>
您应该在 net.sf.jasperreports.data.adapter 属性 的帮助下在子报表中指定此适配器。在这个 属性 的帮助下,您应该使用 数据适配器 定义(描述)指定文件名,它可以是带路径的名称。就我而言,它将是:CustomerAddressesDataAdapter.xml
.
子报表模板将为:
<?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="TestSubreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="net.sf.jasperreports.data.adapter" value="CustomerAddressesDataAdapter.xml"/>
<title>
<band height="79" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30"/>
<text><![CDATA[Subreport Title]]></text>
</staticText>
</band>
</title>
<summary>
<band height="42" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30"/>
<text><![CDATA[Subreport Summary]]></text>
</staticText>
</band>
</summary>
</jasperReport>
在主报告中,包含子报告的部分将是:
<subreport>
<reportElement x="0" y="30" width="560" height="150"/>
<subreportExpression><![CDATA["TestSubreport.jasper"]]></subreportExpression>
</subreport>
- 与之前的情况一样,您不需要指定连接。
对于第一个解决方案,JSS 的输出结果将是:
更多信息
我在 Jaspersoft Studio 中使用 JavaBeans 生成基本报告 (master/subreport) 时遇到问题。
我创建了 TestMainReport.jrxml 和 TestSubreport.jrxml.
TestMainReport.jrxml 包含两个静态文本字段,在标题栏中标记为 "A Title"
,在摘要栏中标记为 "A Summary"
。
TestSubreport.jrxml 包含两个静态文本字段,标题 "Subreport Title"
和摘要带 "Subreport Summary"
。
我已经为它们分配了 JavaBeans 数据适配器,它们没有被使用(尽管 JavaBean 字段被映射到主报表中。我只是碰巧没有将它们映射到子报表中,因为它们没有被使用)。
已将子报表元素添加到摘要带中的主报表。
当我尝试生成每一份报告时,这两份报告都能很好地单独生成。但是,子报表静态文本不会出现在主报表中。
我原以为子报表的静态文本会出现在主报表中。
我做错了什么?
TestMainReport.jrxml
<?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="TestMainReport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="0d969cfb-66d2-442f-b7a4-5a9e1a40c3ae">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Customer Info Data Adapter"/>
<field name="birthday" class="java.time.LocalDate">
<fieldDescription><![CDATA[birthday]]></fieldDescription>
</field>
<field name="observacao" class="java.lang.String">
<fieldDescription><![CDATA[observacao]]></fieldDescription>
</field>
<field name="orderNumber" class="java.lang.Integer">
<fieldDescription><![CDATA[orderNumber]]></fieldDescription>
</field>
<field name="phone" class="java.lang.String">
<fieldDescription><![CDATA[phone]]></fieldDescription>
</field>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="email" class="java.lang.String">
<fieldDescription><![CDATA[email]]></fieldDescription>
</field>
<title>
<band height="79" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="db07ac65-15f6-4190-b1db-9d445456f306"/>
<text><![CDATA[A Title]]></text>
</staticText>
</band>
</title>
<summary>
<band height="215" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="08c03e87-2b15-4eb1-b404-b7dce6dfb890"/>
<text><![CDATA[A Summary]]></text>
</staticText>
<subreport>
<reportElement x="0" y="30" width="560" height="150" uuid="c292246e-1ffa-4f08-a783-a0b05b28be76"/>
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
<subreportExpression><![CDATA["TestSubreport.jasper"]]></subreportExpression>
</subreport>
</band>
</summary>
</jasperReport>
TestSubreport.jrxml
<?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="TestSubreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="d5dd9821-786d-4312-81c9-fd77f1abfb8a">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Customer Addresses Data Adapter"/>
<title>
<band height="79" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="4c9fdc83-4039-4eed-b593-448898853071"/>
<text><![CDATA[Subreport Title]]></text>
</staticText>
</band>
</title>
<summary>
<band height="42" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="4bb9ba45-548a-4e87-a543-472b0f960487"/>
<text><![CDATA[Subreport Summary]]></text>
</staticText>
</band>
</summary>
</jasperReport>
CustomerInfoDataSource.java
package testdatasource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class CustomerInfoDataSource {
public static Collection<CustomerInfo> getCustomerInfo() {
List<CustomerInfo> info = new ArrayList<>();
info.add(new CustomerInfo(1, "Mario", "mario@mario.com.br", LocalDate.now(), "14 912345678", "Observação Mario"));
return info;
}
}
CustomerInfo.java
package testdatasource;
import java.time.LocalDate;
public class CustomerInfo {
private final int orderNumber;
private final String name;
private final String email;
private final LocalDate birthday;
private final String phone;
private final String observacao;
public CustomerInfo(int orderNumber, String name, String email, LocalDate birthday, String phone, String observacao) {
this.orderNumber = orderNumber;
this.name = name;
this.email = email;
this.birthday = birthday;
this.phone = phone;
this.observacao = observacao;
}
public int getOrderNumber() {
return orderNumber;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public LocalDate getBirthday() {
return birthday;
}
public String getPhone() {
return phone;
}
public String getObservacao() {
return observacao;
}
}
CustomerAddressDataSource.java
package testdatasource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class CustomerAddressDataSource {
public static Collection<CustomerAddress> getCustomerAddresses() {
List<CustomerAddress> addresses = new ArrayList<>();
addresses.add(new CustomerAddress("Casa 1", "Rua Tal", "123", null, "Jardim Márcia", "Agudos", "17400-000", "Perto da caixa d'água"));
addresses.add(new CustomerAddress("Casa 2", "Rua Tal", "456", null, "Jardim Márcia", "Agudos", "17400-000", "Perto da caixa d'água"));
return addresses;
}
}
CustomerAddress.java
package testdatasource;
public class CustomerAddress {
private final String title;
private final String street;
private final String number;
private final String complement;
private final String bairro;
private final String city;
private final String cep;
private final String referencePoint;
public CustomerAddress(String title, String street, String number, String complement, String bairro, String city,
String cep, String referencePoint) {
this.title = title;
this.street = street;
this.number = number;
this.complement = complement;
this.bairro = bairro;
this.city = city;
this.cep = cep;
this.referencePoint = referencePoint;
}
public String getTitle() {
return title;
}
public String getStreet() {
return street;
}
public String getNumber() {
return number;
}
public String getComplement() {
return complement;
}
public String getBairro() {
return bairro;
}
public String getCity() {
return city;
}
public String getCep() {
return cep;
}
public String getReferencePoint() {
return referencePoint;
}
}
来自TestMainReport.jrxml的输出:
来自TestSubreport.jrxml的输出:
怎么了?
您没有为子报表指定数据源。您设置了 connectionExpression (<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
) 而不是这个。该连接可以在基于 jdbc 的数据源(报告)的情况下为您提供帮助,但对您的情况没有帮助。
解决方案 1 - 使用 dataSourceExpression
您应该为子报表指定数据源。您可以这样声明子报表元素:
<subreport>
<reportElement x="0" y="30" width="560" height="150"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource(testdatasource.CustomerAddressDataSource.getCustomerAddresses())]]></dataSourceExpression>
<subreportExpression><![CDATA["TestSubreport.jasper"]]></subreportExpression>
</subreport>
在这种情况下,CustomerAddressDataSource class 将用于填充子报表。
解决方案 2 - 使用数据适配器的外部定义
您可以将子报表的数据适配器导出到文件中,并将其保存到与模板相同的文件夹中(如果您不想指定数据适配器文件的路径)。
您可以在上下文菜单的帮助下导出 数据适配器 定义 JSS (Jaspersoft Studio):
在您的情况下 - 它将是 CustomerAddressesDataAdapter.xml,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<beanDataAdapter class="net.sf.jasperreports.data.bean.BeanDataAdapterImpl"><name>Customer Addresses Data Adapter</name><factoryClass>testdatasource.CustomerAddressDataSource</factoryClass><methodName>getCustomerAddresses</methodName><useFieldDescription>false</useFieldDescription><classpath>C:\somepath\library_with_beans.jar</classpath></beanDataAdapter>
您应该在 net.sf.jasperreports.data.adapter 属性 的帮助下在子报表中指定此适配器。在这个 属性 的帮助下,您应该使用 数据适配器 定义(描述)指定文件名,它可以是带路径的名称。就我而言,它将是:CustomerAddressesDataAdapter.xml
.
子报表模板将为:
<?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="TestSubreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="net.sf.jasperreports.data.adapter" value="CustomerAddressesDataAdapter.xml"/>
<title>
<band height="79" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30"/>
<text><![CDATA[Subreport Title]]></text>
</staticText>
</band>
</title>
<summary>
<band height="42" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30"/>
<text><![CDATA[Subreport Summary]]></text>
</staticText>
</band>
</summary>
</jasperReport>
在主报告中,包含子报告的部分将是:
<subreport>
<reportElement x="0" y="30" width="560" height="150"/>
<subreportExpression><![CDATA["TestSubreport.jasper"]]></subreportExpression>
</subreport>
- 与之前的情况一样,您不需要指定连接。
对于第一个解决方案,JSS 的输出结果将是: