上一回我在博客中发了一个关于在Struts2中制作带参数报表的例子,昨天又刚做完在Struts2中制作带查询的报表的例子,现在把这个例子一起放进我的博客里。该例子也是参考李刚老师的《struts2权威指南》做出来的。
定义带查询的报表需要在报表设计文件中增加一个查询定义,增加查询定义使用<query .../>元素,每个<query .../>元素定义一个查询,下面是本应用中所使用的查询定义:
<!-- 使用query元素定义一个查询 -->
<queryString><![CDATA[select * from book_table where book_id>$P{id}]]></queryString>
在上面的查询定义中包含了一个名为id的参数,因此,我们还必须定义一个名为id的参数,定义参数还是使用<parameter .../>元素,下面是本应用中定义id参数的代码:
<!-- 定义一个名为id的参数。 -->
<parameter name="id" isForPrompting="true" class="java.lang.Integer"/>
为了在报表中输出查询的结果,JasperReports还提供了一个Field来访问这种动态数据,每个Field就对应表格的一个字段。
book_table表中包含了三列数据:book_id、book_name和book_author,这意味着,我们可以在报表设计文件中增加这三个Field定义,Field定义使用<field .../>元素来完成,每个<field .../>元素定义一个Field。增加Field定义的格式如下所示。
<!-- 定义一个Field -->
<field name="book_id" class="java.lang.Integer"/>
定义了Field之后,可以使用$F{FieldName}来访问Field的值。
下面是本示例应用所使用的报表设计文件的代码:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Created with iReport - A designer for JasperReports -->
<!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport
name="simpleQuery"
columnCount="1"
printOrder="Vertical"
orientation="Portrait"
pageWidth="595"
pageHeight="842"
columnWidth="535"
columnSpacing="0"
leftMargin="30"
rightMargin="30"
topMargin="20"
bottomMargin="20"
whenNoDataType="NoPages"
isTitleNewPage="false"
isSummaryNewPage="false">
<property name="ireport.scriptlethandling" value="0" />
<property name="ireport.encoding" value="UTF-8" />
<import value="java.util.*" />
<import value="net.sf.jasperreports.engine.*" />
<import value="net.sf.jasperreports.engine.data.*" />
<style
name="zh"
isDefault="false"
fontName="宋体"
fontSize="18"
isBold="true"
pdfFontName="STSong-Light"
pdfEncoding="UniGB-UCS2-H"
/>
<!-- 定义了一个参数,参数名为id -->
<parameter name="id" isForPrompting="true" class="java.lang.Integer"/>
<!-- 定义了一个查询 -->
<queryString><![CDATA[select * from book_table where book_id>$P{id}]]></queryString>
<!-- 将查询的三个字段定义成三个Field -->
<field name="book_id" class="java.lang.Integer"/>
<field name="book_name" class="java.lang.String"/>
<field name="book_author" class="java.lang.String"/>
<background>
<band height="0" isSplitAllowed="true" >
</band>
</background>
<title>
<band height="50" isSplitAllowed="true" >
</band>
</title>
<pageHeader>
<band height="50" isSplitAllowed="true" >
</band>
</pageHeader>
<columnHeader>
<band height="39" isSplitAllowed="true" >
<staticText>
<reportElement
style="zh"
x="93"
y="0"
width="62"
height="31"
key="staticText-2"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<text><![CDATA[图书ID]]></text>
</staticText>
<staticText>
<reportElement
style="zh"
x="170"
y="0"
width="83"
height="31"
key="staticText-3"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<text><![CDATA[图书作者]]></text>
</staticText>
<staticText>
<reportElement
style="zh"
x="261"
y="0"
width="191"
height="31"
key="staticText-4"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<text><![CDATA[图书书名]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="45" isSplitAllowed="true" >
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
style="zh"
x="93"
y="12"
width="62"
height="33"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<!-- 输出book_id的Field -->
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{book_id}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
style="zh"
x="261"
y="12"
width="231"
height="33"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<!-- 输出book_ name的Field -->
<textFieldExpression class="java.lang.String"><![CDATA[$F{book_name}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
style="zh"
x="170"
y="12"
width="83"
height="33"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<!-- 输出book_ author的Field -->
<textFieldExpression class="java.lang.String"><![CDATA[$F{book_author}]]></textFieldExpression>
</textField>
</band>
</detail>
<columnFooter>
<band height="30" isSplitAllowed="true" >
<staticText>
<reportElement
style="zh"
x="226"
y="5"
width="103"
height="23"
key="staticText-5"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<text><![CDATA[当前页码:]]></text>
</staticText>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
style="zh"
x="339"
y="5"
width="140"
height="23"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<!-- 输出变量PAGE_COUNT -->
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_COUNT}]]></textFieldExpression>
</textField>
</band>
</columnFooter>
<pageFooter>
<band height="50" isSplitAllowed="true" >
</band>
</pageFooter>
<lastPageFooter>
<band height="50" isSplitAllowed="true" >
</band>
</lastPageFooter>
<summary>
<band height="50" isSplitAllowed="true" >
</band>
</summary>
</jasperReport>
通过上面代码,我们不难发现创建报表设计文件时有如下几种引用动态数据的方式:
$V{variablesName}:访问变量。
$P{parameterName}:访问参数,通过填充报表时使用Map对象传入。
$F{filedsName}:访问字段,通常对应查询字段,或者集合元素的属性等。
上面报表设计文件中包含了上面三种方式的动态数据。
同样,上面的报表设计文件也需要经过编译,填充两个步骤。其中编译与前面的2个报表的编译没有任何区别,但填充则稍有不同:因此填充此报表时应为其指定执行查询的数据库连接。
下面是填充该报表的Java代码:
public class MyFill
{
public static void main(String[] args) throws Exception
{
//设置填充报表时使用Map对象作为参数
Map params = new HashMap();
params.put("id" , 1);
//填充时,直接指定一个Connection作为数据连接
JasperFillManager.fillReportToFile("simpleQuery.jasper" , params , getConnection());
System.out.println("成功填充了一个报表文件(*.jrprint)");
System.exit(0);
}
//定义用于获取数据库连接的方法
private static Connection getConnection() throws ClassNotFoundException, SQLException
{
String driver = "com.mysql.jdbc.Driver";
String connectString = "jdbc:mysql://localhost/j2ee";
String user = "root";
String password = "32147";
//加载驱动
Class.forName(driver);
//获得数据连接
Connection conn = DriverManager.getConnection(connectString, user, password);
return conn;
}
}
因为本应用使用的是MySQL数据库,因此使用的是MySQL的驱动,因此我们还必须将MySQL的驱动程序放到系统的CLASSPATH路径下。
将该报表导出成PDF文档,将会生成一个名为simpleQuery.pdf的文件。