JasperReports - Crosstabs
Os relatórios de tabela de referência cruzada (tabulação cruzada) são os relatórios que contêm tabelas que organizam dados em linhas e colunas em um formato tabular. O objeto crosstab é usado para inserir um relatório de crosstab dentro do relatório principal. As tabelas cruzadas podem ser usadas com qualquer nível de dados (nominal, ordinal, intervalo ou proporção) e geralmente exibem os dados resumidos, contidos nas variáveis do relatório, na forma de uma tabela dinâmica. As variáveis são usadas para exibir dados agregados, como somas, contagens, valores médios.
Propriedades de Crosstab
Elemento JRXML <crosstab> é usado para inserir uma crosstab em um relatório.
Atributo
A seguir está uma lista de atributos de um <crosstab> elemento -
isRepeatColumnHeaders- indica se os cabeçalhos das colunas devem ser reimpressos após uma quebra de página. O valor padrão é verdadeiro .
isRepeatRowHeaders- Indica se os cabeçalhos de linha devem ser reimpressos após uma quebra de coluna de crosstab. O valor padrão é verdadeiro .
columnBreakOffset- Quando ocorre uma quebra de coluna, indica a quantidade de espaço vertical, medido em pixels, antes da peça de crosstab subsequente a ser colocada abaixo da anterior na mesma página. O valor padrão é 10.
runDirection- Indica se os dados de crosstab devem ser preenchidos da esquerda para a direita (LTR) ou da direita para a esquerda (RTL). O valor padrão é LTR.
ignoreWidth- Indica se a crosstab se estenderá além do limite inicial de largura da crosstab e não gerará quebras de coluna. Caso contrário, ele irá parar de renderizar colunas dentro do limite de largura da crosstab e continuará com as colunas restantes somente depois que todas as linhas tiverem iniciado a renderização. O valor padrão é falso .
Subelementos
Um elemento <crosstab> possui os seguintes subelementos -
<reportElement>- Este elemento define a posição, largura e altura da crosstab dentro de sua delimitação. Os atributos para este elemento incluem todos os atributos <reportElement> padrão.
<crosstabParameter>- Este elemento é usado para acessar variáveis e parâmetros de relatório de dentro da crosstab. Os atributos deste elemento incluem -
nome - define o nome do parâmetro.
classe - Isso indica a classe do parâmetro.
<parametersMapExpression>- Este elemento é usado para passar uma variável de relatório ou parâmetro contendo uma instância de java.util.Map , como um conjunto de parâmetros para a crosstab. Este elemento não contém atributos.
<crosstabDataset>- Este elemento define o conjunto de dados a ser usado para preencher a crosstab (consulte a próxima seção para uma explicação detalhada). Os atributos deste elemento incluem -
isDataPreSorted - Isso indica se os dados no conjunto de dados são pré-classificados. O valor padrão é falso .
<crosstabHeaderCell>- Este elemento define o conteúdo da região encontrada no canto superior esquerdo da crosstab onde os cabeçalhos das colunas e das linhas se encontram. O tamanho desta célula é calculado automaticamente com base nas larguras e alturas de linha e coluna definidas.
<rowGroup>- Este elemento define um grupo usado para dividir os dados em linhas. Os atributos deste elemento incluem -
nome - define o nome do grupo de linhas.
largura - define a largura do grupo de linhas.
headerPosition - Isso define a posição do conteúdo do cabeçalho (Top, Middle, Bottom, Stretch).
totalPosition - define a posição de toda a coluna (início, fim, nenhum).
Este elemento contém os seguintes subelementos -
<bucket>
<crosstabRowHeader>
<crosstabTotalRowHeader>
<columnGroup>- Este elemento define um grupo usado para dividir os dados em colunas. Os atributos deste elemento incluem -
nome - define o nome do grupo de colunas.
altura - define a altura do cabeçalho do grupo de colunas.
headerPosition - Isso define a posição do conteúdo do cabeçalho ( Right, Left, Center, Stretch ).
totalPosition - define a posição de toda a coluna ( início, fim, nenhum ).
Este elemento contém os seguintes subelementos -
<bucket>
<crosstabColumnHeader>
<crosstabTotalColumnHeader>
<measure>- Este elemento define o cálculo a ser executado em linhas e colunas. Os atributos deste elemento incluem -
nome - define o nome da medida.
classe - Isso indica a classe de medida.
cálculo - indica o cálculo a ser executado entre os valores das células da crosstab. Seus valores podem ser qualquer um destes - Nada, Contagem, ContagemDistinta, Soma, Média, Mais baixo, Mais alto, Desvio padrão, Variância e Primeiro . O valor padrão éNothing.
<crosstabCell>- Este elemento define como os dados em células sem cabeçalho serão dispostos. Os atributos deste elemento incluem -
columnTotalGroup - Isso indica o grupo a ser usado para calcular o total da coluna.
altura - define a altura da célula.
rowTotalGroup - indica o grupo a ser usado para calcular o total de linhas.
largura - define a largura da célula.
<whenNoDataCell>- Este elemento define o que exibir em uma célula de crosstab vazia. Este elemento não contém atributos.
Agrupamento de dados em crosstab
O mecanismo de cálculo de crosstab agrega dados iterando por meio dos registros de conjunto de dados associados. Para agregar dados, é necessário agrupá-los primeiro. Em uma crosstab, as linhas e colunas são baseadas em itens de grupos específicos, chamadosbuckets. Uma definição de intervalo deve conter -
bucketExpression - A expressão a ser avaliada para obter itens do grupo de dados.
comparatorExpression - Necessário no caso de a ordem natural dos valores não ser a melhor escolha.
orderByExpression - indica o valor usado para classificar os dados.
Os grupos de linhas e colunas (definidos acima) em uma crosstab dependem de buckets.
Variáveis totais integradas de tabela cruzada
Abaixo está uma lista do valor atual da medida e os totais dos diferentes níveis correspondentes à célula podem ser acessados através de variáveis nomeadas de acordo com o seguinte esquema -
O valor atual de um cálculo de medida é armazenado em uma variável com o mesmo nome da medida.
<Medida> _ <Grupo de Colunas> _ALL - Isso produz o total de todas as entradas no grupo de colunas da mesma linha.
<Medida> _ <Grupo de linhas> _ALL - Isso produz o total de todas as entradas no grupo de linhas da mesma coluna.
<Medida> _ <Grupo de Linhas> _ <Grupo de Colunas> _ALL - Isso produz o total combinado correspondente a todas as entradas em grupos de linhas e colunas.
Exemplo
Para demonstrar os crosstabs, vamos escrever um novo modelo de relatório (jasper_report_template.jrxml). Aqui, adicionaremos a crosstab à seção de resumo. Salve-o no diretórioC:\tools\jasperreports-5.0.1\test. O conteúdo do arquivo é o seguinte -
<?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>
Os detalhes do arquivo acima são os seguintes -
A crosstab é definida pelo elemento <crosstab>.
O elemento <rowGroup> define um grupo para dividir os dados em linhas. Aqui, cada linha exibirá dados para um nome diferente.
Os elementos <bucket> e <bucketExpression> definem qual expressão de relatório usar como um delimitador de grupo para <rowGroup>. Aqui, usamos o campo de nome como um delimitador, a fim de dividir as linhas por nome.
O elemento <crosstabRowHeader> define a expressão a ser usada como cabeçalho de linha. Ele contém um único subelemento, a saber <cellContents>, que atua como uma faixa interna dentro da crosstab. Em vez de definir o nome da variável para o campo de texto dentro de <crosstabRowHeader>, atribuímos o nome a <rowGroup> (por meio de seu atributo name), portanto, ele cria uma variável implícita. O elemento <crosstabRowHeader> define o conteúdo da célula do cabeçalho para a linha inteira. Leva um único elemento <cellContents> como seu único subelemento.
O elemento <columnGroup>, bem como seus subelementos, são análogos ao elemento <rowGroup>, exceto que ele influencia colunas em vez de linhas.
O elemento <measure> define o cálculo a ser executado em linhas e colunas. O atributo de cálculo é definido como Contagem .
O elemento <crosstabCell> define como os dados em células sem cabeçalho serão dispostos. Este elemento também contém um único elemento <crosstabCell> como seu único subelemento.
Os códigos java para preenchimento de relatório permanecem inalterados. O conteúdo do arquivoC:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\JasperReportFill.java são os dados abaixo -
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();
}
}
}
O conteúdo do arquivo POJO C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBean.java são os seguintes -
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;
}
}
O conteúdo do arquivo C:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\DataBeanList.java são os seguintes -
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;
}
}
Geração de relatório
A seguir, vamos compilar e executar os arquivos acima usando nosso processo normal de construção ANT. O conteúdo do arquivo build.xml (salvo no diretório C: \ tools \ jasperreports-5.0.1 \ test) é fornecido a seguir.
O arquivo de importação - baseBuild.xml é obtido no capítulo Configuração do ambiente e deve ser colocado no mesmo diretório do 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>
A seguir, vamos abrir a janela da linha de comando e ir para o diretório onde build.xml está colocado. Finalmente, execute o comandoant -Dmain-class=com.tutorialspoint.JasperReportFill (viewFullReport é o destino padrão) da seguinte forma -
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
Como resultado da compilação acima, uma janela JasperViewer é aberta conforme mostrado na tela abaixo -
Aqui, vemos que cada país e nome são tabulados.