JasperReports 交叉表crosstab
交叉表(cross-tabulation)报表是包含以表格形式跨行和列排列数据的表格的报表。交叉表对象用于在主报表中插入交叉表报表。交叉表可用于任何级别的数据(名义、有序、区间或比率),并且通常以动态表的形式显示包含在报表变量中的汇总数据。变量用于显示汇总数据,例如总和、计数、平均值。
交叉表属性
JRXML 元素<crosstab> 用于在报表中插入交叉表。
属性
以下是 <crosstab> 元素的属性列表:
-
isRepeatColumnHeaders : 指示是否应在分页符后重新打印列标题。默认值为true。
-
isRepeatRowHeaders : 指示是否应在交叉表分栏后重新打印行标题。默认值为true。
-
columnBreakOffset : 发生分栏时,表示在将后续交叉表块放置在同一页面上的前一个下方之前,以像素为单位测量的垂直空间量。默认值为 10。
-
runDirection : 指示应从左到右(LTR)还是从右到左(RTL)填充交叉表数据。默认值为 LTR。
-
ignoreWidth : 指示交叉表是否会超出初始交叉表宽度限制并且不生成分栏符。否则,它将停止呈现交叉表宽度限制内的列,并仅在所有行开始呈现后才继续呈现剩余的列。默认值为false。
子元素
<crosstab> 元素具有以下子元素 :
-
<reportElement> - 此元素定义其封闭内交叉表的位置、宽度和高度。此元素的属性包括所有标准的 <reportElement> 属性。
-
<crosstabParameter> - 此元素用于从交叉表中访问报告变量和参数。此元素的属性包括:
-
name : 这定义了参数名称。
-
class : 这表示参数类。
-
-
<parametersMapExpression> : 此元素用于传递包含java.util.Map实例的报告变量或参数,作为交叉表的一组参数。此元素不包含任何属性。
-
<crosstabDataset> : 此元素定义用于填充交叉表的数据集(有关详细说明,请参阅下一节)。此元素的属性包括 -
-
isDataPreSorted : 这表明数据集中的数据是否预先排序。默认值为false。
-
-
<crosstabHeaderCell> : 此元素定义在交叉表左上角找到的区域的内容,其中列标题和行标题相遇。该单元格的大小是根据定义的行和列的宽度和高度自动计算的。
-
<rowGroup> : 此元素定义用于将数据拆分为行的组。此元素的属性包括 -
-
name : 这定义了行组的名称。
-
width : 这定义了行组的宽度。
-
headerPosition : 这定义了标题内容的位置(顶部、中间、底部、拉伸)。
-
totalPosition : 这定义了整个列的位置(开始、结束、无)。
此元素包含以下子元素 :
-
<bucket>
-
<crosstabRowHeader>
-
<crosstabTotalRowHeader>
-
-
<columnGroup> : 此元素定义用于将数据拆分为列的组。此元素的属性包括 -
-
name : 这定义了列组名称。
-
height : 这定义了列组标题的高度。
-
headerPosition : 这定义了标题内容的位置(Right, Left, Center, Stretch)。
-
totalPosition : 这定义了整个列的位置(开始,结束,无)。
此元素包含以下子元素 :
-
<bucket>
-
<crosstabColumnHeader>
-
<crosstabTotalColumnHeader>
-
-
<measure> : 此元素定义要跨行和列执行的计算。此元素的属性包括 -
-
name : 这定义了度量名称。
-
class : 这表示度量类。
-
calculation : 这表示要在交叉表单元格值之间执行的计算。它的值可以是以下任何一个 - Nothing、Count、DistinctCount、Sum、Average、Lowest、Highest、StandardDeviation、Variance和First。默认值为Nothing。
-
-
<crosstabCell> : 此元素定义非标题单元格中的数据将如何布局。此元素的属性包括 -
-
columnTotalGroup : 这表示用于计算列总数的组。
-
height :这定义了单元格的高度。
-
rowTotalGroup : 这表示用于计算行总数的组。
-
width : 这定义了单元格的宽度。
-
-
<whenNoDataCell> : 此元素定义要在空交叉表单元格上显示的内容。此元素不包含任何属性。
交叉表中的数据分组
交叉表计算引擎通过迭代关联的数据集记录来聚合数据。为了聚合数据,首先需要对它们进行分组。在交叉表中,行和列基于特定的组项目,称为buckets。存储桶定义应包含 -
-
bucketExpression : 要评估的表达式以获得数据组项。
-
compareExpression : 在值的自然排序不是最佳选择的情况下需要。
-
orderByExpression : 表示用于对数据进行排序的值。
交叉表中的行和列组(如上定义)依赖于buckets。
内置交叉表总变量
以下是可通过根据以下方案命名的变量访问与单元格对应的不同级别的当前度量值和总计值列表 -
-
度量计算的当前值存储在与度量同名的变量中。
-
<Measure>_<Column Group>_ALL : 这会产生来自同一行的列组中所有条目的总数。
-
<Measure>_<Row Group>_ALL : 这会产生来自同一列的行组中所有条目的总数。
-
<Measure>_<Row Group>_<Column Group>_ALL : 这产生与行组和列组中的所有条目相对应的组合总数。
JasperReports 交叉表的示例
pom.xml文件
<dependencies>
<!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.17.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.7</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
</dependencies>
DataBean实体类:
package cn.xnip;
public class DataBean {
private String name;
private String country;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
DataBeanList类:
package cn.xnip;
import java.util.ArrayList;
public class DataBeanList {
public ArrayList<DataBean> getDataBeanList() {
ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();
dataBeanList.add(produce("Manisha", "India"));
dataBeanList.add(produce("Dennis Ritchie", "USA"));
dataBeanList.add(produce("V.Anand", "India"));
dataBeanList.add(produce("Shrinath", "California"));
return dataBeanList;
}
/**
* This method returns a DataBean object,
* with name and country set in it.
*/
private DataBean produce(String name, String country) {
DataBean dataBean = new DataBean();
dataBean.setName(name);
dataBean.setCountry(country);
return dataBean;
}
}
jasper_report_template.jrxml模板文件:
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN"
"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<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 = "jasper_report_template" language = "groovy" pageWidth = "595"
pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
topMargin = "20" bottomMargin = "20">
<parameter name = "ReportTitle" class = "java.lang.String"/>
<parameter name = "Author" class = "java.lang.String"/>
<field name = "name" class = "java.lang.String"/>
<field name = "country" class = "java.lang.String"/>
<title>
<band height = "70">
<line>
<reportElement x = "0" y = "0" width = "515" height = "1"/>
</line>
<textField isBlankWhenNull = "true" bookmarkLevel = "1">
<reportElement x = "0" y = "10" width = "515" height = "30"/>
<textElement textAlignment = "Center">
<font size = "22"/>
</textElement>
<textFieldExpression class = "java.lang.String">
<![CDATA[$P{ReportTitle}]]>
</textFieldExpression>
<anchorNameExpression>
<![CDATA["Title"]]>
</anchorNameExpression>
</textField>
<textField isBlankWhenNull = "true">
<reportElement x = "0" y = "40" width = "515" height = "20"/>
<textElement textAlignment = "Center">
<font size = "10"/>
</textElement>
<textFieldExpression class = "java.lang.String">
<![CDATA[$P{Author}]]>
</textFieldExpression>
</textField>
</band>
</title>
<summary>
<band height = "60">
<crosstab>
<reportElement width = "782" y = "0" x = "0" height = "60"/>
<rowGroup name = "nameGroup" width = "100">
<bucket>
<bucketExpression class = "java.lang.String">
<![CDATA[$F{name}]]>
</bucketExpression>
</bucket>
<crosstabRowHeader>
<cellContents>
<box border = "Thin" borderColor = "black"/>
<textField>
<reportElement width = "100" y = "0" x = "0" height = "20"/>
<textElement textAlignment = "Right"
verticalAlignment = "Middle"/>
<textFieldExpression>
<![CDATA[$V{nameGroup}]]>
</textFieldExpression>
</textField>
</cellContents>
</crosstabRowHeader>
</rowGroup>
<columnGroup name = "countryGroup" height = "20">
<bucket>
<bucketExpression class = "java.lang.String">
$F{country}
</bucketExpression>
</bucket>
<crosstabColumnHeader>
<cellContents>
<box border = "Thin" borderColor = "black"/>
<textField isStretchWithOverflow = "true">
<reportElement width = "60" y = "0" x = "0" height = "20"/>
<textElement verticalAlignment = "Bottom"/>
<textFieldExpression>
<![CDATA[$V{countryGroup}]]>
</textFieldExpression>
</textField>
</cellContents>
</crosstabColumnHeader>
</columnGroup>
<measure name = "tailNumCount" class = "java.lang.Integer"
calculation = "Count">
<measureExpression>$F{country}</measureExpression>
</measure>
<crosstabCell height = "20" width = "60">
<cellContents backcolor = "#FFFFFF">
<box borderColor = "black" border = "Thin"/>
<textField>
<reportElement x = "5" y = "0" width = "55" height = "20"/>
<textElement textAlignment = "Left"
verticalAlignment = "Bottom"/>
<textFieldExpression class = "java.lang.Integer">
$V{tailNumCount}
</textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
</crosstab>
</band>
</summary>
</jasperReport>
先编译报表文件:
package cn.xnip;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.view.JasperViewer;
public class JasperReportFill {
public static void main(String[] args) {
String filePath = "D:/idea_codes/jasper_reports/jasper_report_template.jrxml";
try {
JasperCompileManager.compileReportToFile(filePath,"d:/jasper_report_template.jasper");
System.out.println("编译成功");
} catch (JRException e) {
e.printStackTrace();
}
}
}
编译后在D:/盘根目录下生成jasper_report_template.jasper文件,然后再填充数据:
package cn.xnip;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class JasperReportFill {
public static void main(String[] args) {
String sourceFileName = "d:/jasper_report_template.jasper";
DataBeanList DataBeanList = new DataBeanList();
ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();
JRBeanCollectionDataSource beanColDataSource =
new JRBeanCollectionDataSource(dataList);
Map parameters = new HashMap();
/**
* Passing ReportTitle and Author as parameters
*/
parameters.put("ReportTitle", "List of Contacts");
parameters.put("Author", "Prepared By Manisha");
try {
JasperFillManager.fillReportToFile(
sourceFileName, parameters, beanColDataSource);
} catch (JRException e) {
e.printStackTrace();
}
}
}
填充数据完毕后,在D:/盘根目录下生成jasper_report_template.jrprint文件,最后使用预览程序预览:
package cn.xnip;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.view.JasperViewer;
public class JasperReportFill {
public static void main(String[] args) {
String filePath = "D:/jasper_report_template.jrprint";
try {
JasperViewer.viewReport(filePath,false);
} catch (JRException e) {
e.printStackTrace();
}
}
}
最后输出结果如下:
在这里,我们看到每个国家和名称都被列出。