Relatório com subClasses - Jasper

Eu tenho um problema, qnd uso o JRBeanCollectionDataSource, ele não consegue reconhecer o atributo Endereço que está dentro da que eu enviei para a collection, como eu posso tratar esse tipo de classe no meu relatório ?
(Apenas com os atributos comuns funciona)

Utilizo jasper studio e a versão 6.20 da biblioteca do jasper

package pdf;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;

public class Teste{
public static void main(String[] args) {
try {
new Teste().gerarRelatório();
} catch (JRException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void gerarRelatório() throws JRException{
List pessoas=new ArrayList<>();
pessoas.add(new Pessoa(“Marco”,“riansco@”, new Endereco(“PITOMBEIRA”)));
pessoas.add(new Pessoa(“China”,“riansco@”, new Endereco(“RIO BRANCO”)));
pessoas.add(new Pessoa(“China”,“riansco@”, new Endereco(“PITOMBEIRA”)));

  InputStream reportStream = this.getClass().getResourceAsStream("/pdf/Invoice.jrxml");  
  JasperDesign jasperDesign =JRXmlLoader.load(reportStream);
  JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);  
    
   
  JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, new JRBeanCollectionDataSource(pessoas));  
    
  JasperExportManager.exportReportToPdfFile(jasperPrint, "relatorio.pdf");

}
}

Bom, até onde eu consigo entender, você precisará de um getter, é isso que torna o atributo acessível ao mecanismo do iReport que vai ler os dados e preencher os campos do relatório.
Como está a classe Pessoa?

1 curtida

public class Pessoa {
private String nome;
private String email;
private Endereco endereco;

public Pessoa(String nome, String email, Endereco endereco) {
super();
this.nome = nome;
this.email = email;
this.endereco = endereco;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}

}
public class Endereco {
private String rua;

public Endereco(String rua) {
super();
this.rua = rua;
}

public String getRua() {
return rua;
}

public void setRua(String rua) {
this.rua = rua;
}

}

Bom, com certeza que o iReport jamais encontrará o atributo endereço. Não existe um getter para ele…
Crie o getter para o endereço, isso resolverá o problema, com certeza.

1 curtida

Realmente, depois de perceber isso, também achei outras coisas que resolveram meus problemas, a ideia era aprender a acessar um elemento isolado pra depois poder aprender a acessar uma List com vários destes endereços.
Após conseguir acessar o Endereco, substitui por uma List< Endereco> enderecos
Ai foi simples, mapeei no jasper como uma List normal apelidada de enderecos e criei um subrelatório.
Para conseguir alimentar o subrelatório com dados utilizei como DataSource no próprio jasper esta linha:
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{enderecos},false)
No subrelatório foi bem simples apenas coloquei o nome de cada variável e disponibilizei o get, sua resposta foi simples, mas eu realmente tinha esquecido desse detalhe, obrigado.

@Rian15sco, um dos maiores problemas do desenvolvimento de relatórios jasper (na verdade no desenvolvimento de qualquer coisa) é ter resistência à tecnologia (mesmo que seja ultrapassada). O outro é não prestar atenção aos detalhes.