I’m guessing you already have basic knowledge in iReport. You didn’t put your object models, so I’m going to imagine one as per your description (In fact, you should use the same objects from your application’s domain; some people have some difficulty working this way, and often do a de/para of the data before sending a Java object to Jasper to render). I based on Jrbeancollectiondatasource but it is easily adaptable to other types of Datasources (XML, Connection, Resultset ...).
Problem solving
As you may already know, the best way to "iterate" over a list is through a sub-report. Still not leaving this concept, to have an easy-to-maintain report/file that consequently supports evolution, you should imagine your iReport layout in a modular way that is cohesive with your business model. Observe the image described by you, starting with the model Table:
Again, knowing that it is already known that the band "Detail" in the ireport will repeat for each object in the Datasource (or each object sent in the Jasperreport list) I pass to the sub-report of Vigencia the provisions of Table current, layout:
The same concept will be applied to the items of Sash:
The call in java looks something like this:
Tabela tabela = new Tabela();
tabela.setDescricao("Taxa 1%");
tabela.setStatus("Ativa");
Vigencia vigencia = new Vigencia();
vigencia.setDescricao("Vigencia a partir de 31/07/2014");
tabela.getVigencias().add(vigencia); // forçando repetir
tabela.getVigencias().add(vigencia);
Faixa faixa = new Faixa();
faixa.setPrazo("37");
faixa.setTaxaDeJuros("1.00%");
faixa.setTaxaParaBanco("0.50%");
faixa.setComissao("4.55%");
faixa.setComplemento("6.00%");
vigencia.getFaixas().add(faixa); // forçando repetir
vigencia.getFaixas().add(faixa);
vigencia.getFaixas().add(faixa);
List<Tabela> tabelas = Arrays.asList(tabela);
Map<String, Object> parameters = new HashMap<String, Object>();
/**
* isto é como eu resolvo os subreports, mas existem outras maneiras
* mais elegantes sem usar FileResolver
*/
parameters.put(JRParameter.REPORT_FILE_RESOLVER, new FileResolver() {
public File resolveFile(String fileName) {
return new File(Main.class.getResource("/jasper/" + fileName).getFile());
}
});
JasperPrint jasperPrint = JasperFillManager.fillReport(Main.class.getResourceAsStream("/jasper/tabela.jasper"), parameters, new JRBeanCollectionDataSource(tabelas));
...
What generates the output:
And given its complexity (which in fact is not complex):
Source of the Archives
table.jrxml:
<?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="tabela" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<style name="borda">
<box topPadding="0" leftPadding="0" rightPadding="0">
<pen lineWidth="1.0" lineColor="#666666"/>
<topPen lineWidth="1.0" lineColor="#666666"/>
<leftPen lineWidth="1.0" lineColor="#666666"/>
<bottomPen lineWidth="1.0" lineColor="#666666"/>
<rightPen lineWidth="1.0" lineColor="#666666"/>
</box>
</style>
<queryString>
<![CDATA[]]>
</queryString>
<field name="descricao" class="java.lang.String">
<fieldDescription><![CDATA[descricao]]></fieldDescription>
</field>
<field name="status" class="java.lang.String">
<fieldDescription><![CDATA[status]]></fieldDescription>
</field>
<field name="vigencias" class="java.util.List">
<fieldDescription><![CDATA[vigencias]]></fieldDescription>
</field>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="50" splitType="Stretch">
<staticText>
<reportElement style="borda" x="0" y="0" width="75" height="50"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Tabela]]></text>
</staticText>
<staticText>
<reportElement style="borda" x="75" y="0" width="75" height="50"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Vigência]]></text>
</staticText>
<staticText>
<reportElement style="borda" x="150" y="0" width="405" height="25"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Taxa e comissões por prazo]]></text>
</staticText>
<staticText>
<reportElement style="borda" x="150" y="25" width="81" height="25"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Prazo (em meses)]]></text>
</staticText>
<staticText>
<reportElement style="borda" x="231" y="25" width="81" height="25"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Taxa de juros]]></text>
</staticText>
<staticText>
<reportElement style="borda" x="312" y="25" width="81" height="25"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Taxa para banco]]></text>
</staticText>
<staticText>
<reportElement style="borda" x="393" y="25" width="81" height="25"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Comissão]]></text>
</staticText>
<staticText>
<reportElement style="borda" x="474" y="25" width="81" height="25"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Complemento]]></text>
</staticText>
</band>
</title>
<detail>
<band height="25" splitType="Stretch">
<textField>
<reportElement style="borda" stretchType="RelativeToBandHeight" x="0" y="0" width="75" height="25"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{descricao} + "\n" + "(" + $F{status} + ")"]]></textFieldExpression>
</textField>
<subreport>
<reportElement x="75" y="0" width="480" height="25"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{vigencias})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA["vigencia.jasper"]]></subreportExpression>
</subreport>
</band>
</detail>
</jasperReport>
vigencia.jrxml:
<?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="vigencia" pageWidth="480" pageHeight="842" columnWidth="480" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<style name="borda">
<box topPadding="0" leftPadding="0" rightPadding="0">
<pen lineWidth="1.0" lineColor="#666666"/>
<topPen lineWidth="1.0" lineColor="#666666"/>
<leftPen lineWidth="1.0" lineColor="#666666"/>
<bottomPen lineWidth="1.0" lineColor="#666666"/>
<rightPen lineWidth="1.0" lineColor="#666666"/>
</box>
</style>
<queryString>
<![CDATA[]]>
</queryString>
<field name="descricao" class="java.lang.String">
<fieldDescription><![CDATA[descricao]]></fieldDescription>
</field>
<field name="faixas" class="java.util.List">
<fieldDescription><![CDATA[faixas]]></fieldDescription>
</field>
<background>
<band splitType="Stretch"/>
</background>
<detail>
<band height="25" splitType="Stretch">
<textField isStretchWithOverflow="true">
<reportElement style="borda" stretchType="RelativeToBandHeight" x="0" y="0" width="75" height="25"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{descricao}]]></textFieldExpression>
</textField>
<subreport>
<reportElement x="75" y="0" width="405" height="25"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{faixas})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA["faixa.jasper"]]></subreportExpression>
</subreport>
</band>
</detail>
</jasperReport>
range.jrxml (81px * 5 = 405px):
<?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="faixa" pageWidth="405" pageHeight="842" columnWidth="405" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<style name="borda">
<box topPadding="0" leftPadding="0" rightPadding="0">
<pen lineWidth="1.0" lineColor="#666666"/>
<topPen lineWidth="1.0" lineColor="#666666"/>
<leftPen lineWidth="1.0" lineColor="#666666"/>
<bottomPen lineWidth="1.0" lineColor="#666666"/>
<rightPen lineWidth="1.0" lineColor="#666666"/>
</box>
</style>
<queryString>
<![CDATA[]]>
</queryString>
<field name="comissao" class="java.lang.String">
<fieldDescription><![CDATA[comissao]]></fieldDescription>
</field>
<field name="complemento" class="java.lang.String">
<fieldDescription><![CDATA[complemento]]></fieldDescription>
</field>
<field name="prazo" class="java.lang.String">
<fieldDescription><![CDATA[prazo]]></fieldDescription>
</field>
<field name="taxaDeJuros" class="java.lang.String">
<fieldDescription><![CDATA[taxaDeJuros]]></fieldDescription>
</field>
<field name="taxaParaBanco" class="java.lang.String">
<fieldDescription><![CDATA[taxaParaBanco]]></fieldDescription>
</field>
<background>
<band splitType="Stretch"/>
</background>
<detail>
<band height="20" splitType="Stretch">
<textField>
<reportElement style="borda" x="243" y="0" width="81" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{comissao}]]></textFieldExpression>
</textField>
<textField>
<reportElement style="borda" x="324" y="0" width="81" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{complemento}]]></textFieldExpression>
</textField>
<textField>
<reportElement style="borda" x="0" y="0" width="81" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{prazo}]]></textFieldExpression>
</textField>
<textField>
<reportElement style="borda" x="81" y="0" width="81" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{taxaDeJuros}]]></textFieldExpression>
</textField>
<textField>
<reportElement style="borda" x="162" y="0" width="81" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{taxaParaBanco}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
As the sub-report is called ?
In the "Palette" tab, select the "Subreport" element, in the "Data Source Expression" property put:
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource(/*expressao que resultado em uma referencia para java.util.Collection (geralmente um java.util.List) */)
Under "Subreport Expression", enter the name of your sub-report: reportABC .Jasper
Used models
public class Tabela implements Serializable {
private static final long serialVersionUID = 203356217547759664L;
private String descricao;
private String status;
private List vigencias;
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List getVigencias() {
if (vigencias == null) {
vigencias = new ArrayList();
}
return vigencias;
}
public void setVigencias(List vigencias) {
this.vigencias = vigencias;
}
}
public class Vigencia implements Serializable {
private static final long serialVersionUID = -4743305406353605507L;
private String descricao;
private List faixas;
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public List getFaixas() {
if (faixas == null) {
faixas = new ArrayList();
}
return faixas;
}
public void setFaixas(List faixas) {
this.faixas = faixas;
}
}
public class Faixa implements Serializable {
private static final long serialVersionUID = -1713006520166696857L;
private String prazo;
private String taxaDeJuros;
private String taxaParaBanco;
private String comissao;
private String complemento;
public String getPrazo() {
return prazo;
}
public void setPrazo(String prazo) {
this.prazo = prazo;
}
public String getTaxaDeJuros() {
return taxaDeJuros;
}
public void setTaxaDeJuros(String taxaDeJuros) {
this.taxaDeJuros = taxaDeJuros;
}
public String getTaxaParaBanco() {
return taxaParaBanco;
}
public void setTaxaParaBanco(String taxaParaBanco) {
this.taxaParaBanco = taxaParaBanco;
}
public String getComissao() {
return comissao;
}
public void setComissao(String comissao) {
this.comissao = comissao;
}
public String getComplemento() {
return complemento;
}
public void setComplemento(String complemento) {
this.complemento = complemento;
}
}
Man, I’m having a little trouble, you’d like to post the source code please?
– Macario1983
I edited and put the source of the templates. What exactly would be your difficulty ?
– wryel
Dude like you said, I went soft because I should have posted the class structure but it’s gone, I’m having problems generating, maybe it’s the part where you take the report in the folder.
– Macario1983
You can use the ones I attached, they follow 1 Table for N Vigencias that has N Tracks. But comment here its structure to get a concenso :)
– wryel
I’ll post the classes up there but it won’t change much, but here’s the thing, I saw you put this up
/jasper/tabela.jasper
, I have to have a file of this kind?– Macario1983
/jasper/
is just a directory for my Jasper files, the *.Jasper are the compiled (from *.jrxml) generated by iReport. If you want to compile at runtime, you should do something like:JasperCompileManager.compileReport(Main.class.getResource("/jasper/tabela.jrxml").getFile());
. But I do not recommend this method, after all, you would be compiling every time you were going to generate a report.– wryel
Let’s go continue this discussão in chat.
– Macario1983