Olá Javeiros!

Eu estava com uma dificuldade enorme para trabalhar com ArrayList de VOs (Value Objects ) com um atributo ArrayList para alimentar um relatório. O problema era o seguinte: montar um relatório através de um ArrayList de VOs de Aluno (ver listagem 1) que tem um ArrayList de VOs de Disciplina (ver listagem 2), sendo um aluno por página. Listagem 1:
package vo;
import java.io.Serializable;
import java.util.ArrayList;
/**
* @author RJFurutani
* @04/05/2005
*/
public class Aluno implements Serializable{
private String nome;
private String curso;
private ArrayList disciplinas;
/**
* @param nome
* @param curso
* @param disciplinas
*/
public Aluno(String nome, String curso, ArrayList
					disciplinas) {
super();
this.nome = nome;
this.curso = curso;
this.disciplinas = disciplinas;
}
/**
* @return Returns the curso.
*/
public String getCurso() {
return curso;
}
/**
* @param curso The curso to set.
*/
public void setCurso(String curso) {
this.curso = curso;
}
/**
* @return Returns the disciplinas.
*/
public ArrayList getDisciplinas() {
return disciplinas;
}
/**
* @param disciplinas The disciplinas to set.
*/
public void setDisciplinas(ArrayList
			disciplinas) {
this.disciplinas = disciplinas;
}
/**
* @return Returns the nome.
*/
public String getNome() {
return nome;
}
/**
* @param nome The nome to set.
*/
public void setNome(String nome) {
this.nome = nome;
}
}
Listagem 2
	package vo;
import java.io.Serializable;
/**
* @author RJFurutani
* @04/05/2005
*/
public class Disciplina implements Serializable{
/**
* @param nome
* @param cargaHoraria
*/
public Disciplina(String nome,String cargaHoraria){
super();
this.nome = nome;
this.cargaHoraria = cargaHoraria;
}
/**
* @return Returns the cargaHoraria.
*/
public String getCargaHoraria() {
return cargaHoraria;
}
/**
* @param cargaHoraria The cargaHoraria to set.
*/
public void setCargaHoraria(String cargaHoraria){
this.cargaHoraria = cargaHoraria;
}
/**
* @return Returns the nome.
*/
public String getNome() {
return nome;
}
/**
* @param nome The nome to set.
*/
public void setNome(String nome) {
this.nome = nome;
}
private String nome;
private String cargaHoraria;
}

Depois de um tempão pesquisando e perguntando no GUJ, JavaFree, na lista enterprise-list@soujava.dev.java.net e usando o Google achei esse video http://ireport.sourceforge.net/swf/Subreport_viewlet_swf.htm que me deu uma luz e vou tentar passar de forma mais objetiva a solução que eu encontrei.

Eu vou considerar que o leitor já tenha alguma experiência com o iReports e o JasperReports. Não vou entrar em muitos detalhes de design.

Primeiro vamos criar o relatório principal, nele vamos por os fields nome do aluno e o curso que ele faz e abaixo vai ficar o subrelatório. A ferramenta para adicionar o subrelatório está na barra de ferramentas:

Clique no icone destacado e desenhe ele como na figura anterior. Agora vamos criar o subrelatório, esse é bem mais simples.

no subrelatório os fields são esses:

Não tem nada de mais. Agora vamos aos fields do relatório principal. O field nome e curso são para o próprio relatório principal, o field ListaDisciplinas é o que vai ser passado para o subrelatório, reparem que ele é do tipo Object. E como parâmetro o relatório principal recebe o caminho do subrelatório compilado (.jasper).

Agora vamos nas propriedades do subrelatório que foi adicionado no relatório principal. Dê um duplo clique nele e vamos as configurações.

Na aba Subreport selecione Use datasource expression e digite $F{ListaDisciplinas} , esse nome deve ser igual ao informado no field.

Clique na aba subreport (other) e configure conforme mostra a figura. Como estamos trabalhando com VO o nome dos fields deve coincidir com o nome dos atributos das classes VO (Aluno e Disciplina) . Com layout feito podemos ir para o desenvolvimento da classe DataSource. Eu vou chamar aqui de relatórioAlunosDataSource. É uma classe que implementa a interface JRDataSource, então devemos implementar obrigatoriamente dois métodos o next() e getFieldValue(). O método next() retorna um boolean, true se houver mais Aluno na ArrayList ou false se não tiver mais.
 valorAtual = itrAlunos.hasNext() ? itrAlunos.next() : null;
 irParaProximoAluno = (valorAtual != null);
 return irParaProximoAluno;
O método getFieldValue() recebe um parâmetro JRField, através desse parâmetro nós podemos saber qual field o JasperReports está pedindo pra por no relatório.
  Object valor = null;
  Aluno aluno = (Aluno) valorAtual;
 if ("nome".equals(campo.getName())) {
   valor = aluno.getNome();
 } else if ("ListaDisciplinas".equals(campo.getName())) {
   valor = new JRBeanCollectionDataSource(
   			aluno.getDisciplinas());
 } else if ("curso".equals(campo.getName())) {
   valor = aluno.getCurso();
 }
Observer que quando é solicitado o field ListaDisciplinas nós devolvemos um JRBeanCollectionDataSource instanciado com a ArrayList de Disciplina do Aluno. Lembra que na configuração dos fields do relatório principal nós colocamos ListaDisciplinas do tipo Object, foi justamente por esse motivo. Chegou a hora de criar a classe principal
package jasper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.view.JasperViewer;
public class Gerarelatório {
private static final String rel1 = "RelAlunos.jasper";
private static final String rel2 =
"jasper/RelAlunosDisciplinas.jasper";
public Gerarelatório() throws Exception {
// Lista dos alunos
ArrayList listaAlunos = GerarDadosFicticios.getListaAlunos();
// Cria o data source para o relatório
relatórioAlunosDataSource ds =
	new relatórioAlunosDataSource(
		listaAlunos);
// parâmetros do relatório
Map parâmetros = new HashMap();
parâmetros.put("pathSubRel",rel2);
JasperPrint impressao = JasperFillManager.fillReport(
getClass().getResourceAsStream(rel1), parâmetros, ds);
//exibe o relatório
JasperViewer viewer = new JasperViewer(impressao, true);
viewer.show();
}
public static void main(String[] args) throws Exception {
new Gerarelatório();
}
}
Para criar dados ficticios usados para testar o relatório foi criado a classe GerarDadosFicticios
package jasper;
import java.util.ArrayList;
import vo.Aluno;
import vo.Disciplina;
/**
* @author RJFurutani
* @04/05/2005
*/
public class GerarDadosFicticios {
public static ArrayList getListaAlunos() {
ArrayList listaAlunos = new ArrayList();
ArrayList disciplinas = null;
Disciplina disciplina1 = null;
Disciplina disciplina2 = null;
Disciplina disciplina3 = null;
Disciplina disciplina4 = null;
/*
* Aluno Roberto
*/
disciplina1 =
   new Disciplina("Banco de Dados I", "45Hs");
disciplina2 =
   new Disciplina("Equações Diferenciais I", "50Hs");
disciplina3 =
   new Disciplina("Algoritmos e Estrutura de Dados I",
"60Hs");
disciplinas = new ArrayList();
disciplinas.add(disciplina1);
disciplinas.add(disciplina2);
disciplinas.add(disciplina3);
Aluno roberto =
   new Aluno("Roberto Furutani", "Ciencia da Computacao",
disciplinas);
listaAlunos.add(roberto);
/*
* Aluna Fernanda
*/
disciplina1 = new Disciplina("Biologia", "45Hs");
disciplina2 = new Disciplina("Matematica Elementar II",
"30Hs");
disciplina3 = new Disciplina(
"Instrumentação Cirurgica", "70Hs");
disciplinas = new ArrayList();
disciplinas.add(disciplina1);
disciplinas.add(disciplina2);
disciplinas.add(disciplina3);
Aluno fernanda = new Aluno("Fernanda Fernandes",
"Enfermagem", disciplinas);
listaAlunos.add(fernanda);
/*
* Aluna Silvia
*/
disciplina1 = new Disciplina("Fisica", "45Hs");
disciplina4 = new Disciplina("Quimica", "45Hs");
disciplina2 = new Disciplina("Equações Diferenciais II",
"50Hs");
disciplina3 = new Disciplina(
"Inglês", "60Hs");
disciplinas = new ArrayList();
disciplinas.add(disciplina1);
disciplinas.add(disciplina2);
disciplinas.add(disciplina3);
disciplinas.add(disciplina4);
Aluno silvia = new Aluno("Silvia da Silva", "Matemática",
disciplinas);
listaAlunos.add(silvia);
/*
* Aluno André
*/
disciplina1 = new Disciplina("Banco de Dados II", "65Hs");
disciplina2 = new Disciplina("Calculo Numerico I",
"50Hs");
disciplina3 = new Disciplina(
"Eletronica I", "60Hs");
disciplinas = new ArrayList();
disciplinas.add(disciplina1);
disciplinas.add(disciplina2);
disciplinas.add(disciplina3);
Aluno andre =
   new Aluno("André Oliveira Lima", "Engenharia da Computacao",
disciplinas);
listaAlunos.add(andre);
return listaAlunos;
}}
O relatório vai ficar assim: É isso ai!!! Espero ter ajudado alguém com esse humilde tutorial. Referências: Download dos fontes GUJ - www.guj.com.br (http://www.guj.com.br/posts/list/23830.java) JavaFree - www.javafree.com.br Lista Enterprise - enterprise-list@soujava.dev.java.net Docs iReport - http://ireport.sourceforge.net/docs.html Videos iReport - http://ireport.sourceforge.net/swf/ Relatórios com Hibernate - http://www.hibernate.org/79.html Tutorial Relatórios com JasperReports e iReports - www.furutani.com.br Atualizado em 24/06/2009
Share


20 comentários

  1. #
    Usando o JRBeanCollectionDataSource » Roberto Furutani
    maio 16th, 2009 at 21:11

    […] Em um outro tutorial eu tive o trabalho de criar um DataSource customizado, mas creio que é facilmente adaptado […]

    Responda a esse comentário
  2. #
    Dirceu Sobrinho
    maio 20th, 2009 at 17:35

    Olá, Roberto

    Primeiramente, parabéns pelo tutorial, está mt bom! =)

    estou tendo um problema, na hora de passar o datasource expression, eu passo um campo $F{programasDeTrabalho} que corresponde ao atributo: private List programasDeTrabalho; em minha classe Java, quando tento rodar o relatorio estou obtendo o seguinte error:

    Caused by: java.lang.ClassCastException: org.hibernate.collection.PersistentBag cannot be cast to net.sf.jasperreports.engine.JRDataSource

    Eu deverei retirar o Generic do ArrayList para funcionar? existe alguma forma de usar lista de um determinado objeto?

    OBS.: as imagens estão com o links quebrado ta faltando uma “/” antes do caminho da imagem para exibi-las

    Att. Dirceu

    Responda a esse comentário
  3. #
    Dirceu Sobrinho
    maio 20th, 2009 at 18:20

    Consegui resolver o problema provisoriamente com uma gambiarra.

    criei um atributo:

    @Transient
    private JRBeanCollectionDataSource programasTrabalho2;

    e coloquei como datasource expression: $F{programasTrabalho2}

    onde programasTrabalho2 recebe um new JRBeanCollectionDataSource(programasTrabalho)

    Não é melhor solução mais ta funcionando, o ideal seria se eu conseguisse passar como um datasource expression, a seguinte expressão: new JRBeanCollectionDataSource($F(programasTrabalho))

    mas isso não funcionou =/

    Valeu

    Responda a esse comentário
  4. #
    Jeremias Araújo
    julho 8th, 2009 at 9:58

    Furutani, Mto bom o tutorial.
    Baixando os fontes, percebi que tem uma classe ListaDisciplinas. Tentei refazer o passo a passo e não consegui criar esse arquivo. Como é gerado esse ListaDisciplinas? Manualmente ou pelo iReport.
    Grato,
    Jeremias Araujo

    Responda a esse comentário
  5. #
    Frederico Nascimento
    julho 10th, 2009 at 8:52

    Furutani, gostei muito do seu tutorial ele me deu um grande empurrão para desenvolver relatórios com o iReport, estou tendo algumas dificuldades com a compilação pois quando faço modificações no relatório principal e recompilo os relatórios ele não está atualizando o layout do relatório principal, caso eu modifique o sub-relatório ele e recompile ele atualiza somente o layout do sub-relatório, vc tem alguma dica que possa me ajudar estou com o iReport 3.0.0.

    Obrigado,

    Frederico G. do Nascimento

    Responda a esse comentário
    • #
      Roberto Furutani
      julho 10th, 2009 at 10:27

      Frederico,
      Eu fiz um teste agora com a mesma versão do iReport (3.0.0), toda vez quando modifico o principal e executo ele, a modificação reflete no PDF criado. Verifique se quando você compila o arquivo .jasper está atualizando, ou melhor antes de compilar apague o .jasper do principal e do sub- relatório. Olhe no console de saída se não houve nenhum erro na compilação do principal.
      Quando existe um erro ele não vai gerar o .jasper, consequentemente não vai atualizar o layout.

      Responda a esse comentário
  6. #
    Frederico Nascimento
    julho 10th, 2009 at 10:52

    Furotani, obrigado pela ajuda, além dos passos que você falou vi que há a necessidade de sempre salvar antes de compilar senão ele mantem a versão anterior, e como eu estou com o Eclipse também tem necessidade após a compilação do relatorio tem que dar um F5 no projeto com com isso funciona.

    Obrigado,
    Frederico G. do Nascimento

    Responda a esse comentário
    • #
      Roberto Furutani
      julho 10th, 2009 at 11:26

      No menu opções, selecione opções. Na aba compilador tem uma opção salvar automaticamente antes de compilar, é só marcar para não ter o trabalho de salvar toda hora.

      Responda a esse comentário
  7. #
    Frederico Nascimento
    julho 10th, 2009 at 17:47

    Cara valeu novamente obrigado 😀

    Responda a esse comentário
  8. #
    Introdução a relatórios crosstab com iReport/JasperReports » Roberto Furutani
    julho 28th, 2009 at 19:56
  9. #
    Daian Henz
    agosto 11th, 2009 at 8:59

    Furutani, tenho uma dúvida… Em qual classe você declara o field ListaDisciplinas?

    Responda a esse comentário
  10. #
    Bruno Sales
    agosto 26th, 2009 at 13:00

    Fala Roberto Furutani!
    atraves do seu tutorial aprendi muito!
    valeu!

    mas estou com um problema semelhante ao do frederico nascimento!
    o relatorio nao atualiza! e nao da erro nenhum de compilacao.
    e quando vejo o .pdf gerado, esta correto, o problema é que quando compilar/executa a aplicação o relatorio que abre eh o relatorio antigo, nao atualizado.

    eu vi voce dando uma solucao pro frederico:
    ” No menu opções, selecione opções. Na aba compilador tem uma opção salvar automaticamente antes de compilar, é só marcar para não ter o trabalho de salvar toda hora. ” mas estou usando o ireport 3.5.2 e nao achei esta opçao.

    agradeço qualquer ajuda!

    t+

    Responda a esse comentário
  11. #
    Alberto Palma
    setembro 15th, 2009 at 16:07

    Ótimo, o material que vc desenvolve, muito util, realmente, tive sucesso em rodar a aplicação acima, mas ao desenvolver um relatorio para minha aplic. WEB com POJO e anotações para Hibernate, estou gerando o seguinte erro:
    org.vraptor.LogicException: net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression :
    Source text : $F{respostaLista}
    ……
    Caused by: java.lang.ClassCastException: org.hibernate.collection.PersistentBag cannot be cast to net.sf.jasperreports.engine.JRDataSource

    Responda a esse comentário
  12. #
    Maykel
    outubro 6th, 2009 at 21:09

    Olá Furtani!
    Meu nome é Maykel e seu tutorial funcionou perfeitamente comigo. Agora estou tentando passar para dois subrelatórios duas coleções diferentes: produtos(id,descrição,preço) e formas de pagamento(descricao). Entretanto quando uso apenas um JRBeanCollectionDataSource funciona, mas quando tento colocar um segundo de formas ele não encontra o campo forma no segundo subrelatório. Os dois subrelatórios tem as memas configurações. É possível passar duas coleções ao mesmo tempo e estas serem impressas?
    Obrigado,
    Maykel

    Responda a esse comentário
  13. #
    Maykel
    outubro 8th, 2009 at 23:17

    Olá Furtani!
    Sou eu novamente. Ao tentar rodar a aplicação com dois subrelatórios recebo um erro(segue abaixo), acontece que quando retiro o segundo subrelatório o sistema não apresenta o erro, e o campo que dá problema é o que está no segundo subreport. Já modiiquei nome de objetos, já alterei o report e ainda assim aparec este erro. Na classe está tudo certo, é cópia de outra classe ainda assim o erro persiste. Será que é problema de versão, eu uso ireport 3.0.0
    Abraço,
    Maykel

    Estes dados iniciais do erro está na minha classe que implementa o JRdataSource e este é o método
    public Object getFieldValue(JRField campo) throws JRException {
      Object valor = null;
      Venda v =(Venda) valorAtual;
      if ("id".equals(campo.getName())) {
          valor = v.getId();
      } else if ("col".equals(campo.getName())){
          //datasource coleção de produtos
                ds1 = new JRBeanCollectionDataSource(v.getColecao());
                valor = ds1;
                System.out.println("o campo é uma Collection de produtos");
                System.out.println("campo: " + campo.getName());
       }else if ("colecao".equals(campo.getName())){
            //datasource formas de pagamento
                ds2 = new JRBeanCollectionDataSource(v.getFormasDePagamento());
                valor = ds2;
                System.out.println("O campo é uma Collection de formas de pagamento");
                System.out.println("campo: " + campo.getName());
       }
       return valor;
    }
    

    ///Aqui vai o erro

    o campo é uma Collection de produtos
    campo: col
    O campo é uma Collection de formas de pagamento
    campo: colecao
    Fill 29715552: exception
    net.sf.jasperreports.engine.JRException: Error retrieving field value from bean : forma
    Exception in thread “main” net.sf.jasperreports.engine.JRRuntimeException: net.sf.jasperreports.engine.JRException: Error retrieving field value from bean : forma
    at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:127)
    at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getFieldValue(JRAbstractBeanDataSource.java:100)
    at net.sf.jasperreports.engine.fill.JRFillSubreport.prepare(JRFillSubreport.java:635)
    at net.sf.jasperreports.engine.data.JRBeanCollectionDataSource.getFieldValue(JRBeanCollectionDataSource.java:104)
    at net.sf.jasperreports.engine.fill.JRFillElementContainer.prepareElements(JRFillElementContainer.java:344)
    at net.sf.jasperreports.engine.fill.JRFillDataset.setOldValues(JRFillDataset.java:787)
    at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:346)
    at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:751)
    at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:305)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.next(JRBaseFiller.java:1422)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:1382)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:111)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:692)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:879)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:255)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:801)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:113)
    at net.sf.jasperreports.engine.fill.JRFillSubreport.fillSubreport(JRFillSubreport.java:536)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:879)
    at net.sf.jasperreports.engine.fill.JRSubreportRunnable.run(JRSubreportRunnable.java:63)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:801)
    at net.sf.jasperreports.engine.fill.JRThreadSubreportRunner.run(JRThreadSubreportRunner.java:209)
    at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:89)
    at java.lang.Thread.run(Thread.java:595)
    Caused by: java.lang.NoSuchMethodException: Unknown property ‘forma’
    at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:601)
    at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:582)
    at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1122)
    at subrel.Subrelatorio.imprimeVenda(Subrelatorio.java:183)
    at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:686)
    at subrel.Subrelatorio.main(Subrelatorio.java:292)
    at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:715)
    Caused by: net.sf.jasperreports.engine.JRException: Error retrieving field value from bean : forma
    at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:290)
    at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:127)
    at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:115)
    … 12 more
    at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getFieldValue(JRAbstractBeanDataSource.java:100)
    at net.sf.jasperreports.engine.data.JRBeanCollectionDataSource.getFieldValue(JRBeanCollectionDataSource.java:104)
    at net.sf.jasperreports.engine.fill.JRFillDataset.setOldValues(JRFillDataset.java:787)
    at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:751)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.next(JRBaseFiller.java:1422)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:111)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:879)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:801)
    at net.sf.jasperreports.engine.fill.JRFillSubreport.fillSubreport(JRFillSubreport.java:536)
    at net.sf.jasperreports.engine.fill.JRSubreportRunnable.run(JRSubreportRunnable.java:63)
    at net.sf.jasperreports.engine.fill.JRThreadSubreportRunner.run(JRThreadSubreportRunner.java:209)
    at java.lang.Thread.run(Thread.java:595)
    Caused by: java.lang.NoSuchMethodException: Unknown property ‘forma’
    at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1122)
    at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:686)
    at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:715)
    at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:290)
    at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:115)
    … 12 more
    Java Result: 1

    Responda a esse comentário
  14. #
    André Wolf
    abril 16th, 2010 at 10:59

    Furutani,
    Parabéns pelo tutorial.

    Minha duvida é a seguinte, tentei criar o relatório seguindo passo a passo este tutorial, no final não funcionava, sempre o mesmo erro na hora de encontrar o arquivo .jasper. Decidi baixar os fontes para saber se tinha alguma diferença, percebi que existia mais classes do que estava criando antes, são elas “untitled_report_1”, “ListaDisciplinas”, “CartaListaLicencas”, vi que aparece em todas elas “Generated by JasperReports”, gostaria de saber como que elas foram criadas?
    No final tudo funcionou corretamente, depois de algumas mudanças, agradeço desde já por este e por outros tutoriais já consultados.

    Responda a esse comentário
  15. #
    Alex
    junho 10th, 2014 at 17:07

    Furutani,
    Mesmo escrito a algum tempo me ajudou!

    Só uma pergunta, este exemplo gera o relatório somente de um aluno.
    E se eu tiver uma lista de alunos, cada um com sua lista de disciplinas?

    Responda a esse comentário

Deixe um comentário