JasperReports - Crosstabs
Báo cáo bảng chéo (lập bảng chéo) là báo cáo chứa các bảng sắp xếp dữ liệu trên các hàng và cột theo dạng bảng. Đối tượng chéo bảng được sử dụng để chèn báo cáo bảng chéo trong báo cáo chính. Crosstabs có thể được sử dụng với bất kỳ mức dữ liệu nào (danh nghĩa, thứ tự, khoảng thời gian hoặc tỷ lệ) và thường hiển thị dữ liệu tóm tắt, có trong các biến báo cáo, ở dạng bảng động. Các biến được sử dụng để hiển thị dữ liệu tổng hợp như tổng, số lượng, giá trị trung bình.
Thuộc tính Crosstab
Phần tử JRXML <crosstab> được sử dụng để chèn bảng chéo vào báo cáo.
Thuộc tính
Sau đây là danh sách các thuộc tính của một <crosstab> phần tử -
isRepeatColumnHeaders- Cho biết liệu tiêu đề cột có nên được in lại sau khi ngắt trang hay không. Giá trị mặc định là true .
isRepeatRowHeaders- Cho biết liệu tiêu đề hàng có nên được in lại sau khi ngắt cột bảng chéo hay không. Giá trị mặc định là true .
columnBreakOffset- Khi xảy ra ngắt cột, cho biết lượng không gian theo chiều dọc, được đo bằng pixel, trước phần bảng chéo tiếp theo được đặt bên dưới phần trước trên cùng một trang. Giá trị mặc định là 10.
runDirection- Cho biết liệu dữ liệu chéo bảng nên được điền từ trái sang phải (LTR) hay từ phải sang trái (RTL). Giá trị mặc định là LTR.
ignoreWidth- Cho biết liệu bảng chéo có kéo dài quá giới hạn chiều rộng bảng chéo ban đầu hay không và không tạo ngắt cột. Nếu không, nó sẽ dừng hiển thị các cột trong giới hạn chiều rộng bảng chéo và chỉ tiếp tục với các cột còn lại sau khi tất cả các hàng đã bắt đầu hiển thị. Giá trị mặc định là sai .
Yếu tố phụ
Phần tử <crosstab> có các phần tử con sau:
<reportElement>- Phần tử này xác định vị trí, chiều rộng và chiều cao của bảng chữ cái trong phạm vi bao quanh của nó. Các thuộc tính cho phần tử này bao gồm tất cả các thuộc tính <reportElement> chuẩn.
<crosstabParameter>- Phần tử này được sử dụng để truy cập các biến và tham số báo cáo từ bên trong bảng chéo. Các thuộc tính cho phần tử này bao gồm:
name - Điều này xác định tên tham số.
class - Điều này chỉ ra lớp tham số.
<parametersMapExpression>- Phần tử này được sử dụng để chuyển một biến báo cáo hoặc tham số có chứa một phiên bản của java.util.Map , như một tập hợp các tham số cho bảng chéo. Phần tử này không chứa thuộc tính.
<crosstabDataset>- Phần tử này xác định tập dữ liệu sẽ sử dụng để điền bảng biểu (xem phần tiếp theo để biết giải thích chi tiết). Các thuộc tính cho phần tử này bao gồm:
isDataPreSorted - Điều này cho biết liệu dữ liệu trong tập dữ liệu có được sắp xếp trước hay không. Giá trị mặc định là sai .
<crosstabHeaderCell>- Phần tử này xác định nội dung của vùng được tìm thấy ở góc trên bên trái của bảng chéo nơi giao nhau giữa tiêu đề cột và tiêu đề hàng. Kích thước của ô này được tính toán tự động dựa trên chiều rộng và chiều cao của hàng và cột được xác định.
<rowGroup>- Phần tử này xác định một nhóm dùng để chia dữ liệu thành các hàng. Các thuộc tính cho phần tử này bao gồm:
name - Điều này xác định tên của nhóm hàng.
width - Điều này xác định chiều rộng của nhóm hàng.
headerPosition - Vị trí này xác định vị trí của nội dung tiêu đề (Trên cùng, Giữa, Dưới cùng, Kéo dài).
TotalPosition - Vị trí này xác định vị trí của toàn bộ cột (Bắt đầu, Kết thúc, Không có).
Phần tử này chứa các phần tử phụ sau:
<bucket>
<crosstabRowHeader>
<crosstabTotalRowHeader>
<columnGroup>- Phần tử này định nghĩa một nhóm dùng để chia dữ liệu thành các cột. Các thuộc tính cho phần tử này bao gồm:
name - Điều này xác định tên nhóm cột.
height - Điều này xác định chiều cao của tiêu đề nhóm cột.
headerPosition - Vị trí này xác định vị trí của nội dung tiêu đề ( Phải, Trái, Giữa , Kéo dài ).
TotalPosition - Vị trí này xác định vị trí của toàn bộ cột ( Bắt đầu, Kết thúc, Không có ).
Phần tử này chứa các phần tử phụ sau:
<bucket>
<crosstabColumnHeader>
<crosstabTotalColumnHeader>
<measure>- Phần tử này xác định phép tính được thực hiện trên các hàng và cột. Các thuộc tính cho phần tử này bao gồm:
name - Điều này xác định tên biện pháp.
class - Điều này cho biết lớp đo lường.
tính toán - Điều này cho biết phép tính được thực hiện giữa các giá trị ô bảng chéo. Giá trị của nó có thể là bất kỳ giá trị nào trong số này - Không có gì, Đếm, Số lượng riêng biệt, Tổng, Trung bình, Thấp nhất, Cao nhất, Độ lệch chuẩn, Phương sai và Đầu tiên . Giá trị mặc định làNothing.
<crosstabCell>- Phần tử này xác định cách sắp xếp dữ liệu trong các ô không có tiêu đề. Các thuộc tính cho phần tử này bao gồm:
columnTotalGroup - Điều này cho biết nhóm sẽ sử dụng để tính tổng cột.
height - Điều này xác định chiều cao của ô.
rowTotalGroup - Điều này cho biết nhóm sẽ sử dụng để tính tổng hàng.
width - Điều này xác định chiều rộng của ô.
<whenNoDataCell>- Phần tử này xác định những gì sẽ hiển thị trên một ô bảng chéo trống. Phần tử này không chứa thuộc tính.
Nhóm dữ liệu trong Crosstab
Công cụ tính toán bảng chéo tổng hợp dữ liệu bằng cách lặp qua các bản ghi tập dữ liệu được liên kết. Để tổng hợp dữ liệu, trước tiên người ta cần nhóm chúng lại. Trong bảng chéo bảng, các hàng và cột dựa trên các mục nhóm cụ thể, được gọi làbuckets. Định nghĩa nhóm phải chứa -
bucketExpression - Biểu thức được đánh giá để có được các mục của nhóm dữ liệu.
comparatorExpression - Cần thiết trong trường hợp thứ tự tự nhiên của các giá trị không phải là lựa chọn tốt nhất.
orderByExpression - Cho biết giá trị được sử dụng để sắp xếp dữ liệu.
Nhóm hàng và cột (được định nghĩa ở trên) trong bảng chéo dựa vào buckets.
Tổng số biến trên bảng chéo tích hợp
Dưới đây là danh sách giá trị hiện tại của thước đo và tổng các mức khác nhau tương ứng với ô có thể được truy cập thông qua các biến được đặt tên theo sơ đồ sau:
Giá trị hiện tại của phép tính số đo được lưu trữ trong một biến có cùng tên với số đo.
<Measure> _ <Column Group> _ALL - Điều này mang lại tổng số cho tất cả các mục nhập trong nhóm cột từ cùng một hàng.
<Measure> _ <Row Group> _ALL - Điều này mang lại tổng số cho tất cả các mục nhập trong nhóm hàng từ cùng một cột.
<Số đo> _ <Nhóm hàng> _ <Nhóm cột> _ALL - Điều này mang lại tổng kết hợp tương ứng với tất cả các mục nhập trong cả nhóm hàng và cột.
Thí dụ
Để chứng minh các dấu gạch ngang, hãy viết một mẫu báo cáo mới (jasper_report_template.jrxml). Ở đây, chúng tôi sẽ thêm bảng chéo vào phần tóm tắt. Lưu nó vào thư mụcC:\tools\jasperreports-5.0.1\test. Nội dung của tệp như dưới đây:
<?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>
Nội dung chi tiết của tập tin trên như sau:
Bảng chéo được định nghĩa bởi phần tử <crosstab>.
Phần tử <rowGroup> xác định một nhóm để chia dữ liệu thành các hàng. Tại đây, mỗi hàng sẽ hiển thị dữ liệu cho một tên khác nhau.
Các phần tử <bucket> và <bucketExpression> xác định biểu thức báo cáo nào sẽ sử dụng làm dấu phân cách nhóm cho <rowGroup>. Ở đây, chúng tôi đã sử dụng trường tên làm dấu phân cách, để tách các hàng theo tên.
Phần tử <crosstabRowHeader> xác định biểu thức sẽ được sử dụng làm tiêu đề hàng. Nó chứa một phần tử con duy nhất, cụ thể là <cellContents>, hoạt động giống như một dải bên trong bảng chữ cái. Thay vì xác định tên biến cho trường văn bản bên trong <crosstabRowHeader>, chúng tôi đã gán tên cho <rowGroup> (thông qua thuộc tính name của nó), do đó nó tạo ra một biến ngầm định. Phần tử <crosstabRowHeader> xác định nội dung của ô tiêu đề cho toàn bộ hàng. Nó nhận một phần tử <cellContents> làm phần tử con duy nhất của nó.
Phần tử <columnGroup> cũng như các phần tử con của nó tương tự với phần tử <rowGroup>, ngoại trừ việc nó ảnh hưởng đến các cột thay vì hàng.
Phần tử <measure> xác định phép tính được thực hiện trên các hàng và cột. Các tính thuộc tính được thiết lập để đếm .
Phần tử <crosstabCell> xác định cách sắp xếp dữ liệu trong các ô không có tiêu đề. Phần tử này cũng chứa một phần tử <crosstabCell> là phần tử con duy nhất của nó.
Các mã java để điền báo cáo vẫn không thay đổi. Nội dung của tệpC:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java như được đưa ra dưới đây -
package com.tutorialspoint;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
public class JasperReportFill {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
String sourceFileName =
"C://tools/jasperreports-5.0.1/test/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();
}
}
}
Nội dung của tệp POJO C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java như sau -
package com.tutorialspoint;
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;
}
}
Nội dung của tệp C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java như sau -
package com.tutorialspoint;
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;
}
}
Tạo báo cáo
Tiếp theo, hãy biên dịch và thực thi các tệp trên bằng quy trình xây dựng ANT thông thường của chúng tôi. Nội dung của tệp build.xml (được lưu trong thư mục C: \ tools \ jasperreports-5.0.1 \ test) như dưới đây.
Tệp nhập - baseBuild.xml được chọn từ chương Thiết lập môi trường và phải được đặt trong cùng thư mục với build.xml.
<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
<import file = "baseBuild.xml" />
<target name = "viewFillReport" depends = "compile,compilereportdesing,run"
description = "Launches the report viewer to preview the
report stored in the .JRprint file.">
<java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
<arg value = "-F${file.name}.JRprint" />
<classpath refid = "classpath" />
</java>
</target>
<target name = "compilereportdesing" description = "Compiles the JXML file and
produces the .jasper file.">
<taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
<classpath refid = "classpath" />
</taskdef>
<jrc destdir = ".">
<src>
<fileset dir = ".">
<include name = "*.jrxml" />
</fileset>
</src>
<classpath refid = "classpath" />
</jrc>
</target>
</project>
Tiếp theo, hãy mở cửa sổ dòng lệnh và đi đến thư mục nơi build.xml được đặt. Cuối cùng, thực hiện lệnhant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport là mục tiêu mặc định) như sau:
C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=com.tutorialspoint.JasperReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml
clean-sample:
[delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
[delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
compile:
[mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
[javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
warning: 'includeantruntime' was not set, defaulting to
[javac] Compiling 3 source files to C:\tools\jasperreports-5.0.1\test\classes
compilereportdesing:
[jrc] Compiling 1 report design files.
[jrc] log4j:WARN No appenders could be found for logger
(net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
[jrc] log4j:WARN Please initialize the log4j system properly.
[jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig
for more info.
[jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.
run:
[echo] Runnin class : com.tutorialspoint.JasperReportFill
[java] log4j:WARN No appenders could be found for logger
(net.sf.jasperreports.extensions.ExtensionsEnvironment).
[java] log4j:WARN Please initialize the log4j system properly.
viewFillReport:
[java] log4j:WARN No appenders could be found for logger (
net.sf.jasperreports.extensions.ExtensionsEnvironment).
[java] log4j:WARN Please initialize the log4j system properly.
BUILD SUCCESSFUL
Total time: 20 minutes 53 seconds
Kết quả của quá trình biên dịch ở trên, một cửa sổ JasperViewer mở ra như được hiển thị trong màn hình dưới đây:
Ở đây, chúng tôi thấy rằng mỗi quốc gia và tên được lập bảng.