如何在报表中使用多个XML数据源

时间:2016-10-11 07:49:02

标签: java xml jasper-reports datasource

我想知道是否可以在JasperReports中有两个XML数据源,一个用于报告,另一个用于子报告。

1 个答案:

答案 0 :(得分:1)

是的,您可以使用多个XML数据源。借助 dataSourceExpression ,您可以将第二个(另一个)数据源传递到子报告。

我将在 Java 的帮助下展示如何做到这一点。如果使用 Java 代码,我们不需要在报告的 queryString的帮助下在报告(主报告和子报告)中指定查询( XPath 表达式) 属性。

工作样本

主报告和子报告将使用不同的 XML 文件。

数据源

customers.xml 文件是主报告的数据源:

<?xml version="1.0" encoding="UTF-8"?>
<Customers>
    <id>ANTON</id>
    <id>AROUT</id>
    <id>BERGS</id>
    <id>BLAUS</id>
</Customers>

customers_details.xml 文件是子报表的数据源:

<?xml version="1.0" encoding="UTF-8"?>
<Customers>
    <Customer>
        <CustomerID>ANTON</CustomerID>
        <CompanyName>Antonio Moreno Taquería</CompanyName>
        <ContactName>Antonio Moreno</ContactName>
        <ContactTitle>Owner</ContactTitle>
        <City>México D.F.</City>
        <Country>Mexico</Country>
    </Customer>
    <Customer>
        <CustomerID>AROUT</CustomerID>
        <CompanyName>Around the Horn</CompanyName>
        <ContactName>Thomas Hardy</ContactName>
        <ContactTitle>Sales Representative</ContactTitle>
        <City>London</City>
        <Country>UK</Country>
    </Customer>
    <Customer>
        <CustomerID>BERGS</CustomerID>
        <CompanyName>Berglunds snabbköp</CompanyName>
        <ContactName>Christina Berglund</ContactName>
        <ContactTitle>Order Administrator</ContactTitle>
        <City>Luleå</City>
        <Country>Sweden</Country>
    </Customer>
    <Customer>
        <CustomerID>BLAUS</CustomerID>
        <CompanyName>Blauer See Delikatessen</CompanyName>
        <ContactName>Hanna Moos</ContactName>
        <ContactTitle>Sales Representative</ContactTitle>
        <City>Mannheim</City>
        <Country>Germany</Country>
    </Customer>
</Customers>

来自Id( Customers.id = Customers.Customer.CustomerID )相关的两个文件中的数据。

此文件包含与 JasperReports 库一起分发的示例 northwind.xml 文件中的某种编译。

主报告的模板

我使用 JRXmlDataSource(String, String) 构造函数将 XML 数据源传递给子报表。子报表取决于此示例中的主报表数据。

用于在子报表中获取数据的 XPath 表达式为:/Customers/Customer[CustomerID=<id>],其中 <id> 的值为 id 来自 customers.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="master_with_xml" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
    <field name="id" class="java.lang.String">
        <fieldDescription><![CDATA[child::text()]]></fieldDescription>
    </field>
    <variable name="expression" class="java.lang.String">
        <variableExpression><![CDATA["/Customers/Customer[CustomerID='" + $F{id} + "']"]]></variableExpression>
    </variable>
    <detail>
        <band height="70" splitType="Stretch">
            <textField>
                <reportElement x="100" y="0" width="100" height="15"/>
                <textFieldExpression><![CDATA[$F{id}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="0" y="0" width="100" height="15"/>
                <text><![CDATA[Id:]]></text>
            </staticText>
            <subreport>
                <reportElement x="54" y="15" width="380" height="45"/>
                <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRXmlDataSource("customers_details.xml", $V{expression})]]></dataSourceExpression>
                <subreportExpression><![CDATA["subreport_with_xml.jasper"]]></subreportExpression>
            </subreport>
        </band>
    </detail>
</jasperReport>

子报告的模板

子报告显示主报告中的客户ID数据(针对每条记录)。

<?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="subreport_with_xml" pageWidth="595" pageHeight="842" columnWidth="595" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
    <field name="CompanyName" class="java.lang.String">
        <fieldDescription><![CDATA[CompanyName]]></fieldDescription>
    </field>
    <field name="ContactName" class="java.lang.String">
        <fieldDescription><![CDATA[ContactName]]></fieldDescription>
    </field>
    <field name="ContactTitle" class="java.lang.String">
        <fieldDescription><![CDATA[ContactTitle]]></fieldDescription>
    </field>
    <field name="City" class="java.lang.String">
        <fieldDescription><![CDATA[City]]></fieldDescription>
    </field>
    <field name="Country" class="java.lang.String">
        <fieldDescription><![CDATA[Country]]></fieldDescription>
    </field>
    <detail>
        <band height="75" splitType="Stretch">
            <staticText>
                <reportElement x="0" y="0" width="100" height="15"/>
                <text><![CDATA[Company name:]]></text>
            </staticText>
            <textField>
                <reportElement x="100" y="0" width="200" height="15"/>
                <textFieldExpression><![CDATA[$F{CompanyName}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="0" y="15" width="100" height="15"/>
                <text><![CDATA[Contact name:]]></text>
            </staticText>
            <textField>
                <reportElement x="100" y="15" width="200" height="15"/>
                <textFieldExpression><![CDATA[$F{ContactName}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="0" y="30" width="100" height="15"/>
                <text><![CDATA[Contact title:]]></text>
            </staticText>
            <textField>
                <reportElement x="100" y="30" width="200" height="15"/>
                <textFieldExpression><![CDATA[$F{ContactTitle}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="0" y="45" width="100" height="15"/>
                <text><![CDATA[Country:]]></text>
            </staticText>
            <textField>
                <reportElement x="100" y="45" width="200" height="15"/>
                <textFieldExpression><![CDATA[$F{Country}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="0" y="60" width="100" height="15"/>
                <text><![CDATA[City:]]></text>
            </staticText>
            <textField>
                <reportElement x="100" y="60" width="200" height="15"/>
                <textFieldExpression><![CDATA[$F{City}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
</jasperReport>

Java代码

用于在主报告中获取数据的 XPath 表达式为:/Customers/*

JasperReport jasperReport;
try (InputStream inputStream = JRLoader.getResourceInputStream("master_with_xml.jrxml")) {
    jasperReport = JasperCompileManager.compileReport(JRXmlLoader.load(inputStream));
}

Map<String, Object> params = new HashMap<>();
params.put(JRParameter.REPORT_LOCALE, Locale.US);

JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, new JRXmlDataSource("customers.xml", "/Customers/*")); // select all customers with XPath

我已将 xalan 库添加到类路径中。

输出结果

我已使用 PDFExporter 生成此 pdf 文件:

The generated pdf file

<强> 注意:

  1. 使用 XML 数据源的绝佳示例: XML Data Source Sample 。可以在 JasperReports库分发的 demo / samples / xmldatasource / src 文件夹中找到此示例的完整代码。
  2. 可以在以下帖子中找到有关功能的详细说明: Looking for a working example of JasperStudio xml subdatasource JasperReports: JRDataSource.subDataSource shows undefined
  3. 您可以通过主报告的参数传递子报告的数据源。