iReport- Gerar relatorio com Objetos

18 respostas
E

Bom dia pessoal, tenho um objeto (Omissao) vindo de um p:dataTable,
onde o mesmo e relacionado com outros objetos, ex:

O objeto Omissao, possui uma Empresa, Linha e Veiculo.(ManyToOne ataves de Ids).
Preciso gerar um relatorio PDF deste objeto atraves de seus atributos e passando
nome_empresa, nome_linha e nome_veiculo.

O .jrxml esta criado e compilando perfeitamente no iReport 4.7.0 com os field (nome_empresa, nome_linha e nome_veiculo)
todos reconhecidos.

Ao gerar o PDF na aplicação, e lançado um erro no qual não e reconhecido esses field no .jrxml.

byte[] bytes = JasperRunManager.runReportToPdf(expRelatorio, null, new JRBeanCollectionDataSource(objRelatorio));

objRelatorio vem de uma lista de objtos Omissao.

Obs: Já pesquisei em vários post, não preciso realizar busca no BD, e não queria fazer subRelatorios.
Minha dúvida é como passar este objeto para a geração do relatorio na aplicação e configurar o relatorio no iReport.

Se puderem me ajudar…obrigaduuuuu…abraçuuu

18 Respostas

J

Tem como disponibilizar o erro para podermos analisar?

Outro detalhe, os fields que você criou são do mesmo tipo que você está passando pela sua aplicação? Por exemplo: String no field e String na aplicação.

G

Esse objeto está num Detail? Ou seja, você terá N objetos desse saindo no relatório???
E quanto aos nomes? Os nomes dos atributos tem de ser EXATAMENTE iguais aos nomes dos Fields no Report.

Posta mais partes do seu código e a definição dos seus fields no jrxml pra ficar mais fácil de te ajudar. Uma alternativa no caso do IReport é gerar os fields através de uma ferramenta que ele possui que lê os atributos do seu JavaBean e gera os fields que você selecionar (e não criá-los na mão).

E

Boa tarde GusMcCart e jhaga, eu não tenho N objetos saindo do relatorio não, apenas um, enquanto aos nomes (field))eu não os criei na mao, foi todos criados pelo iReport atraves da busca no banco de dados, estão assim:
Ex: Busca foi realizada atraves da chave estrangeira de cada coluna referente a cada objeto(tabela)

Imagine uma tabela.

omissao | id_empresa | id_linha | id_veiculo
bla bla 1 2 1

Entao nos field(.jrxml) tenho os atributos de omissao, mais nome_empresa, nome_linha, nome_veiculo. (Inner Join, left join).

O que eu não estou entendendo e como passar o objeto para geração do PDF na aplicação, sendo
que este objeto omissao nao tem os campos relativos aos field, e sim id_empresa, id_linha e id_veiculo.

Ex:
omissao.Empresa.nome_empresa

e não:

omissao.nome_empresa

Insiro este objeto em um List e passo para o JRBeanCollectionDataSource.

Entenderam…se tiverem alguma ideia…obrigadoooo

G

Bom, pelo que entendi então os nomes dos campos estão diferentes dos atributos da entidades, o que não pode acontecer… Os nomes dos atributos têm de ser os mesmos que os nomes dos fields, se tiver id_empresa na classe, tem que estar id_empresa no field.

Se for um objeto só passa por parâmetro (POR FAVOR, crie os parâmetros com os mesmos nomes que passar no “put(…)” do HashMap, antes no relatório!!!):

HashMap<String, Object> parametros = new HashMap<String, Object>();
parametros.put("idDaEmpresa", objRelatorio.getIdEmpresa());
parametros.put("nomeDaLinha", objRelatorio.getNomeDaLinha());
parametros.put("nomeDoVeiculo", objRelatorio.getNomeDoVeiculo());
byte[] bytes = JasperRunManager.runReportToPdf(expRelatorio,  parametros, new JRBeanCollectionDataSource(objRelatorio));

Isso é só um exemplo! Existem várias maneiras de passar informações para os relatórios. Por exemplo… Eu tenho um com uma Tabela e um SubRelatório, um dos DataSources passo via parâmetro e o outro pego direto dentro do relatório de um objeto que é um DataSource do relatório principal.

Quando aos fields só repito, os nomes dos campos dentro do relatório têm de estar exatamente iguais aos nomes dos atributos do(s) objeto(s) que você passou como DataSource, e não do que está no retorno do Select.

E

GusMcCart , obrigado pela dica, não estou agora com o projeto aberto, estou em uma reuniao aki,
mas ao chegar em casa vou fazer desse jeito, crio que vai dar certinho.

Uma duvida, os outros field referente aos atributos do objeto omissao o jasperReport
cosegue identificalos normalmente ne, sem passa-los por parametros, ok.

Valeuuuuuuuuu…brigadãoooo…

G

Você não necessariamente precisa criar parâmetros e passar esses atributos como parâmetro, foi só um exemplo.
Da forma que você está tentando fazer daria certo também, mas pelo que você disse, você criou os fields com os nomes dos campos que estão vindo do banco de dados, e quer passar informações utilizando o objeto… como o nome dos atributos difere do que está no banco de dados (pense nisso na visão do relatório, você tem o campo de nome X e passou um objeto que tem um campo de nome Y) ele não está encontrando e está gerando o erro.

E

GusMcCart, isso eu entendi, so que no meu objeto eu tenho o atributo (chave estrangeira ) id_empresa = 1,
so que no relatorio no field id_empresa eu não quero passar o valor 1 e sim nome_empresa.

Essa e minha duvida, se o field estiver como nome_empresa, como vou passar atraves do objeto omissao se eu tenho id_empresa = 1 e nao o nome_empresa.

Classe Empresa
id_empresa
nome_empresa

Classe Omissao
fk_id_empresa
fk_id_linha
hora_omissao
dia_omissao
etc

Assim funcionaria, eu pensei dessa forma, pois o jarperReport não reconhece nome_empresa como sendo valido, creio que seja pelo relacionamento.
parametros.put(“nome_empresa”, objRelatorio.getEmpresa.getNome_empresa);

Mais uma vez obrigaduuuuu

E

heeeelp........kkk

Classe de geração do relatorio. o que esta erradoooo...

package br.com.omissoesWeb.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import br.com.omissoesWeb.omissao.Omissao;
import br.com.omissoesWeb.omissao.OmissaoRN;

public class RelatorioOmissao {

	FacesContext contexto = FacesContext.getCurrentInstance();

	public void geraRelatorio(Integer codOmissao) {

		try {
								
			OmissaoRN omissaoPorCodigo = new OmissaoRN();
			
			List<Omissao> omissao = new ArrayList<Omissao>();
			omissao.add(omissaoPorCodigo.carregar(codOmissao));
			
			if (omissao.size() != 0) {

				HttpServletResponse response = (HttpServletResponse) contexto
						.getExternalContext().getResponse();

				ServletOutputStream responseStream = response.getOutputStream();

				String caminhoRelatorio = "/RelatorioOmissaoWeb.jrxml";
				InputStream caminho = this.getClass().getResourceAsStream(
						caminhoRelatorio);
				JasperDesign desgner = JRXmlLoader.load(caminho);
				JasperReport expRelatorio = JasperCompileManager
						.compileReport(desgner);
												
				byte[] bytes = JasperRunManager.runReportToPdf(expRelatorio,
						null, new JRBeanCollectionDataSource(omissao));

				System.out.println("gerou todo pdf");
				response.setContentType("aplication/pdf");
				response.setContentLength(bytes.length);
				response.setHeader("Content-Disposition",
						"attachment;filename=\"RelatorioOmissaoWeb.pdf\"");
				responseStream.write(bytes, 0, bytes.length);
				responseStream.flush();
				responseStream.close();
				contexto.renderResponse();
				contexto.responseComplete();

			} else {
				System.out.print("não passou no metodo de busca");
			}

		} catch (Exception e) {

			e.printStackTrace(System.err);

		}

	}
}

Os field estão iguais aos atributos do objeto.

Erro :
net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression : 
	Source text : $F{empresa}
	at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:203)
	at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:591)
	at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:559)
	at net.sf.jasperreports.engine.fill.JRFillElement.evaluateExpression(JRFillElement.java:884)
	at net.sf.jasperreports.engine.fill.JRFillTextField.evaluateText(JRFillTextField.java:421)
	at net.sf.jasperreports.engine.fill.JRFillTextField.evaluate(JRFillTextField.java:406) .......

Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'br.com.omissoesWeb.empresa.Empresa@dd458804' with class 'br.com.omissoesWeb.empresa.Empresa' to class 'java.lang.Number'
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToNumber(DefaultTypeTransformation.java:130)
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:256)
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:632)
	at RelatorioOmissaoWeb_1343820865276_96158.evaluate(calculator_RelatorioOmissaoWeb_1343820865276_96158:219)
	at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:190)

Obrigaduuuuuuuu

G

Posta aí o código da sua classe (só atributos) e a definição dos seus fields no jrxml. Pelo jeito agora os nomes estão iguais, o que não bate é a classe dos objetos (deu um erro de casting aí)

J

eduardimaa:
heeeelp…kkk
Erro :

... Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'br.com.omissoesWeb.empresa.Empresa@dd458804' with class 'br.com.omissoesWeb.empresa.Empresa' to class 'java.lang.Number'
Obrigaduuuuuuuu

Posso estar enganado, mas… observe que seu relatório está com a propriedade “language” em Groovy. Mude para Java.
Se não sabe onde mudar, clique no nome do relatório na aba “Report Inspector” (onde ficam as bandas do seu relatório) e na aba propriedades procure por language.

Outra coisa que você citou, é que você tem o ID e quer passar o nome, então no relatório você tem que fazer esta referência com o campo específico. Como o colega GusMcCart explicou, se o campo estiver com o tipo diferente ou não existir, ele vai dar erro, independente de ser parametro ou field.

E

jhaga e GusMcCart, obrigado pelo apoio que vcs estão me dando…valeuuuuuuuuuuu mesmo…

Entao jhaga, mudei a linguagem do relatorio para java, e o erro desapareceu, referente ao campo nome_empresa(ex) estou passando
somente o id mesmo somente para teste.

GusMcCart, ta ai classe omissao.

package br.com.omissoesWeb.omissao;

import br.com.omissoesWeb.empresa.Empresa;
import br.com.omissoesWeb.linhas.Linha;
import br.com.omissoesWeb.veiculo.Veiculo;
import java.io.Serializable;
import java.util.Date;
import javax.faces.bean.RequestScoped;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;


@Entity
@RequestScoped
public class Omissao implements Serializable {

	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue
	private Integer id_omissao;
	@Temporal(TemporalType.DATE)
	private Date data_cad_omissao;
	@Temporal(TemporalType.DATE)
	private Date data_ocor_omissao;
	private Double quant_omissao;
	@Temporal(TemporalType.TIME)
	private Date hora_omissao;
	private String mtv_omissao;
	private String pto_omissao;
	private String obs_omissao;
	private String resp_omissao;
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="empresa",nullable = false)
	private Empresa empresa = new Empresa();
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="veiculo",nullable = false)
	private Veiculo veiculo = new Veiculo();
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name="linha" , nullable = false)
	private Linha linha = new Linha();

get  e setters
hashCode e equals
}

Fields no .jrxml

$F{resp_omissao}

$F{data_cad_omissao

$F{resp_omissao}

$F{data_ocor_omissao}

$F{resp_omissao}

$F{empresa}

$F{linha}

$F{veiculo}

$F{hora_omissao}

$F{pto_omissao}

$F{quant_omissao}

$F{mtv_omissao}

$F{obs_omissao}

Abraçuuuu

J

TENTE o seguinte:
No iReport, onde você está indicando a empresa, acessar o atributo ao invés de:

Utilize:

*Lembrando que “empresa” é o mesmo nome do atributo definido no seu entity.

G

No caso jhaga isso n vai resolver por conta do campo, ele criou através do resultado de um select e não mapeando a classe pelo ireport. Tem que alterar o tipo do field e adicionar o jar no classpath.

E

GusMcCart , mapei as Classes Omissao, Empresa, Linha e Veiculo no iReport,

Da classe Omissao peguei todos os aributos menos empresa, linha e Veiulo.
Das classes Empresa(nome_empresa), Linha(nome_linha), Veiculos(nome_veiculo).
Todos serao meus fields.

Duvida.

$F{empresa}.get($F{nome_empresa}) funciona ou está errado a expressão ?
Obs: não estou utilizando assim, mas sim desta forma $F{nome_empresa}.

Ao compilar o .jrxml apresenta o sequinte erro...

net.sf.jasperreports.engine.JRException: Error retrieving field value from bean : nome_empresa
	at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:123)
	at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getFieldValue(JRAbstractBeanDataSource.java:96)
	at net.sf.jasperreports.engine.data.JRBeanCollectionDataSource.getFieldValue(JRBeanCollectionDataSource.java:100)
	at net.sf.jasperreports.engine.fill.JRFillDataset.setOldValues(JRFillDataset.java:1317)
	at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:1218)
	at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:1194).......

Caused by: java.lang.NoSuchMethodException: Unknown property 'nome_empresa' on class 'class br.com.omissoesWeb.omissao.Omissao'
	at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1322)
	at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:770)
	at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:846)
	at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:426)
	at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:111)
	... 77 more

TA complicado ....kkkk

E

Pessoal consegui resolver as pendencias relativas aos fields, agora so tem mais um probleminha,

O browser não mostra a janelinha de download ou impressão do arquivo é não apresenta e relátorio,
referente ao relátorio ele e compilado normalmente pela aplicação pois não apresenta nenhum erro
é passa por todos os metódos da classe RelatorioOmissao normalmente.

Olhem a classe :

package br.com.omissoesWeb.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import br.com.omissoesWeb.omissao.Omissao;

public class RelatorioOmissao {

	public void geraRelatorio(Omissao objOmissao) {

		try {

			List<Omissao> omissao = new ArrayList<Omissao>();
			omissao.add(objOmissao);

			if (omissao.size() != 0) {

				FacesContext context = FacesContext.getCurrentInstance();

				HttpServletResponse response = (HttpServletResponse) context
						.getExternalContext().getResponse();

				ServletOutputStream responseStream = response.getOutputStream();

				String caminhoRelatorio = "/relatorioJrxml/RelatorioOmissaoWeb.jrxml";
				
				InputStream caminho = this.getClass().getResourceAsStream(caminhoRelatorio);
				
				JasperDesign desgner = JRXmlLoader.load(caminho);
				
				JasperReport expRelatorio = JasperCompileManager.compileReport(desgner);

				byte[] bytes = JasperRunManager.runReportToPdf(expRelatorio,
						null, new JRBeanCollectionDataSource(omissao));

				response.setContentType("aplication/pdf");
				response.setContentLength(bytes.length);
				response.setHeader("Content-Disposition","attachment;filename=\"RelatorioOmissaoWeb.pdf\"");
				responseStream.write(bytes, 0, bytes.length);
				responseStream.flush();
				responseStream.close();
				context.renderResponse();
				context.responseComplete();

				System.out.println("gerou todo pdf");

			} else {
				System.out.print("não passou no metodo de busca");
			}

		} catch (Exception e) {

			e.printStackTrace(System.err);

		}

	}
}

Sugestões.......obrigaduuuuu

E

Caracaaaaaa…mlk…consegui resolver as pendencias todas…
ta tudo ok…gerando os relatorios tudo blezinha…

Obrigado…muito obrigado mesmo a quem me ajudou…pela dicas…por tudo…

Solução:

1° - busquei os atributos pelas classe do projeto no ireport.
2° - como tinha relacionamento os fileds ficaram assim.
$F{empresa}.getNome_empresa()
$F{linha}.getNome_linha()
$F{veiculo}.getNome_veiculo()
3° - Estava chamando o relatorio de um p:dialog, isso gerava um conflito com o contexto da geração do PDF.

Enfim esta tudo ok…

Valeu galera…

C

Olá pessoal, ja olhei varios exemplos mas nada deu certo, tenho um botão para gerar o relatorio, porem o relatório já está pronto com as querys (Report Wizard) não exite um jeito de só chamálo sem criar as conexões e tudo mais? Abraços

K

Aproveitar seu Tópico aqui amigo e ver se tiro uma dúvida sobre…
Tenho um relatório aqui e populo o cabeçalho dele com uma propriedade chamada RP_CABECALHO que recebe como parâmetro uma classe java cujo caminho estou passando corretamente no Parameter Class;

br.mil.eb.dgp.daprom.vm.web.relatorio.fichavalorizacaomerito.RelatorioFichaValorizacaoMeritoCabecalhoDTO

quando tento compilar o relatório dá ClassNotFoundException… Segue o stackTrace

net.sf.jasperreports.engine.design.JRValidationException: Report design not valid :       1. java.lang.ClassNotFoundException: br.mil.eb.dgp.daprom.vm.web.relatorio.fichavalorizacaomerito.RelatorioFichaValorizacaoMeritoCabecalhoDTO     at net.sf.jasperreports.engine.design.JRAbstractCompiler.verifyDesign(JRAbstractCompiler.java:262)     at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:144)     at com.jaspersoft.ireport.designer.compiler.IReportCompiler.run(IReportCompiler.java:524)     at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:561)     at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:986)

o tópico que criei é esse
http://www.guj.com.br/java/279061-ireport-314-classnotfoundexception#1473795

Se puderem ajudar agradeço muito

Criado 31 de julho de 2012
Ultima resposta 8 de ago. de 2012
Respostas 18
Participantes 5