Alguém já fez um subreport em pdf utilizando jsf com jasper ireport?

14 respostas
dahenz

Boa tarde!

Simplesmente eu não consigo gerar o sub-relatório!!! Tenho dois arquivos jasper... um como relatório principal e outro como sub-relatório...

Utilizo um array de bytes para gerar esse relatório, mas só consigo passar para esse array a quantidade de bytes do relatório principal, vejam o código:

public void gerarRelatorio() throws ParseException, SQLException, ClassNotFoundException, JRException{
		
		if (isValidFields()){						
									
			String data = MySQLDAO.getDataUtil(getDataVigencia());
			
			setListaResumoMedia(getMediaGeralEncomendasDAO().gerarResumoMediaGeralEncomendas(getRegioesSelecionadas(), 
					 																		 getSupervisoresSelecionados(), 
					 																		 getCobrancasSelecionadas(), 
					 																		 getImoveisSelecionados(), 
					 																		 data));						

			setListaMedia(getMediaGeralEncomendasDAO().gerarConsultaMediaGeralEncomendas(getRegioesSelecionadas(), 
																				   		 getSupervisoresSelecionados(), 
																				   		 getCobrancasSelecionadas(), 
																				   		 getImoveisSelecionados(), 
																				   		 data));						
			
		}
		
		JRDataSource jrDS = new JRBeanCollectionDataSource(getListaMedia());
				
		try {
			
			if (!getListaMedia().isEmpty()){
							
				String pathJasper = FacesUtil.getCurrentDirectory()+"/WEB-INF/classes/br/com/project/project";		
				
				String reportFileName = pathJasper + File.separator + "ComparativoMediaEncomendas.jasper";								
								
				String data_aa = getMediaGeralEncomendasDAO().getAnoAnterior(MySQLDAO.formata_ddMMyyyy(getDataVigencia()));
				String data_at = MySQLDAO.formata_ddMMyyyy(getDataVigencia());
				String data_ma = getMediaGeralEncomendasDAO().getMesAnterior(MySQLDAO.formata_ddMMyyyy(getDataVigencia()));
								
				String regiao_footer = "TOTAL:";
				
				if (!getRegioesSelecionadas().isEmpty()){
					
					regiao_footer = "TOTAL PARA REGIÃO(ÕES):";
					
				} else {
					
					if (!getCobrancasSelecionadas().isEmpty()){
						
						regiao_footer = "TOTAL PARA COBRANÇA(S):";
						
					} else {
						
						if (!getImoveisSelecionados().isEmpty()){
							
							regiao_footer = "TOTAL PARA IMÓVEL(IS):";
							
						} else {
							
							if (!getSupervisoresSelecionados().isEmpty()){
								
								regiao_footer = "TOTAL PARA SUPERVISOR(ES):";
								
							}							
						}						
					}				
				}	
				
				String target = null;
				
				if (!getRegioesSelecionadas().isEmpty()){
					
					target = getDescricaoRegioes();
					
				} else {
					
					if (!getSupervisoresSelecionados().isEmpty()){
					
						target = "RELATÓRIO EMITIDO POR SUPERVISOR";
						
					} else {
						
						if (!getCobrancasSelecionadas().isEmpty()){
							
							target = "RELATÓRIO EMITIDO POR COBRANÇA";
							
						} else {
						
							if (!getImoveisSelecionados().isEmpty()){
								
								target ="RELATÓRIO EMITIDO POR IMÓVEL";
								
							}						
						}						
					}										
				}
				
				Map<String, String> parametros = new HashMap<String, String>();				
				parametros.put("data_aa", data_aa);
				parametros.put("data_at", data_at);
				parametros.put("data_ma", data_ma);
				parametros.put("regiao_footer", regiao_footer);
				parametros.put("regiao", target);
				parametros.put("usuario", MySQLDAO.getUsuarioLogado());	
				parametros.put("PathResumo", pathJasper + File.separator + "ResumoComparativoMediaEncomendas.jasper");

				JasperReport report = (JasperReport) JRLoader.loadObject(reportFileName);
				
				JasperPrint print = JasperFillManager.fillReport(report, parametros, jrDS);
				
				byte[] bytes = JasperExportManager.exportReportToPdf(print);

				FacesContext facesContext = FacesContext.getCurrentInstance();
				HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
												 
				response.setContentType("application/pdf");
				response.setContentLength(bytes.length);
				response.setHeader("Content-Disposition","inline; filename=report.pdf"); 
				
				ServletOutputStream ouputStream = response.getOutputStream(); 
				
				ouputStream.write(bytes, 0, bytes.length); 
				ouputStream.flush(); 
				ouputStream.close(); 
				
				facesContext.responseComplete();
								
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
	}

Pergunta: Como faço para escrever o sub-report também???? AJUDA :)

14 Respostas

dahenz

Ninguém passou por isso?

vi-gb

Hum já fiz relatorio e sub-relatorio mas utilizando o ireport, ele tem a opção de adicionar um sub-relatorio feito no relatorio e atraves de uma lista passada para o relatorio preencher o sub.
o componente sub-relatorio tem a propriedade “connection type” onde vc seleciona a opção “use a datasource expression” e na propriedade “data source expression” vc coloca o campo que terá seu array que na verdade ficou declarado como Object.
Desculpe se nao ficou bem explicado :cry:

dahenz

Obrigado pela ajuda, mas tenho uma dúvida:
A collection pode ser um JRDataSource? Se for, devo criar um parâmetro dentro do meu relatório pai do tipo Object?

Obrigado mais uma vez…

vi-gb

Uso uma linkedList e no relatorio pai tenho um field do tipo object, quando o dataSource é chamado para pegar este objeto eu uso este metodo para transformar a lista no objeto esperado.

private JRBeanCollectionDataSource createCollectionDataSource() {
		
		try {
			
			return new JRBeanCollectionDataSource(this.linhas);
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return null;
		}
	}
dahenz

Desculpe o encômodo :slight_smile: hehe mas como você chama esse dataSource… através do Parameters Map Expression???

vi-gb

pelo ireport eu criei um "Custom JRDataSource" e na minha app eu fiz um factory para ele chamar

public class MeuDataSourceFactory {

	private static MeuDataSource data;

	public static JRDataSource createDatasource() {
		if (data == null) {
			return new MeuDataSource();
		}
		return data;
	}
	
	public static MeuDataSource createDataSource(LinkedList<Objeto> linhas) {
		data = new MeuDataSource(linhas);
		return data;
	}
}
assim fica setado no relatorio qual a fonte dos seus dados e quando vc chama pela pagina para gerar o relatorio o proprio relatorio usa esta classe
dahenz

Estou tentando fazer algo simples para ver se entendo o que vc acabou de explicar… fiz o seguinte codigo:

public class JRDataSourceFactory {
	
	public static JRDataSource createDataSource(){
				
		LinkedList<MediaGeralEncomendasBean> lista = new LinkedList<MediaGeralEncomendasBean>();
		
		MediaGeralEncomendasBean mediaGeralEncomendasBean = new MediaGeralEncomendasBean();
		mediaGeralEncomendasBean.setRegiao("SUL");
		mediaGeralEncomendasBean.setVlr_imovel_aa(0);
		mediaGeralEncomendasBean.setVlr_imovel_at(0);
		mediaGeralEncomendasBean.setVar_aa(0);
		mediaGeralEncomendasBean.setVlr_imovel_ma(0);
		mediaGeralEncomendasBean.setVlr_imovel_at(0);
		mediaGeralEncomendasBean.setVar_ma(0);
		
		JRDataSource jrDSResumo = new JRBeanCollectionDataSource(lista);
		
		return jrDSResumo;
		
	}

}

Criei uma classe JRDataSourceFactory para ser conectada pelo meu IReport, e populei um JRBeanCollectionDataSource retornando jrDSResumo, ate entao blz… :slight_smile:

No IReport, criei a conexao JRDSCustom apontando para a classe acima atraves de seus pacotes… Criei o field $F{JRDSResumo} e discriminei ele no DataSource Expression… Basicamente deveria ser mostrado os valores populados no subreport… mas ocorre um erro:

Caused by: java.lang.NoSuchMethodException: Unknown property ‘jrDSResumo’

Gostaria de saber se falta algo… onde estou errando?

Poxa obrigado pela ajuda… desculpa estar encomodando… mas preciso resolver… e sinto que estou quase… :slight_smile:

Abraco…

dahenz

No caso acima, eu criei o field $F{jrDSResumo} e coloquei na propriedade Connection / Datasource Expression…

Mas traz o erro em questão…

Alguém sabe o que pode ser?

Obrigado

dahenz

Eu criei um field $F{jrDSResumo} no iReport para utilizá-lo em Connection / Datasource Expression do subreport…

Mas o erro em questão diz que não encontrou essa propriedade… Alguém passou por isso???

Obrigado…

vi-gb

desculpe esqueci de postar a classe junto com a factory, esta é a classe que o factory cria.

public class MeuDataSource implements JRDataSource{

	private LinkedList<Objeto> linhas;
	private int contador;
	
	public MeuDataSource (LinkedList<Objeto> linhas) {

		this.linhas = linhas;
		this.contador = 0;
	}
	
	public RoteiroDataSource() {
	
		this.linhas = null;
		this.contador = 0;
	}
	
	public Object getFieldValue(JRField field) throws JRException {
		if (field.getName().equals("linhas")) {//vejo se o campo que o relatorio pede é o linha ($F{linhas})
			return createCollectionDataSource();
			
		} 
		return null;
	}
	
	private JRBeanCollectionDataSource createCollectionDataSource() {
		
		try {
			
			return new JRBeanCollectionDataSource(this.linhas);
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return null;
		}
	}

	
	public boolean next() throws JRException {
		this.contador++;
		if (this.contador == 1)
			return true;      
		return false;
	}
}

O jasper diferencia maiuscula de minuscula por isso da uma conferida.

Espero que este exemplo te ajude.

dahenz

Obrigado pela força vi… mais uma dúvida… “linhas” é o nome da propriedade que vc criou no iReport e apontou para o Datasource Expression?

Valew

vi-gb

sim linhas é um field do iReport.

dahenz

Continua dando o erro… o código que gera o relatório é o seguinte:

public void gerarRelatorio() throws ParseException, SQLException, ClassNotFoundException, JRException{
		
		if (isValidFields()){						
									
			String data = MySQLDAO.getDataUtil(getDataVigencia());
			
			setListaMedia(getMediaGeralEncomendasDAO().gerarConsultaMediaGeralEncomendas(getRegioesSelecionadas(), 
																				   		 getSupervisoresSelecionados(), 
																				   		 getCobrancasSelecionadas(), 
																				   		 getImoveisSelecionados(), 
																				   		 data));						
			
		}
		
		JRDataSource jrDS = new JRBeanCollectionDataSource(getListaMedia());
				
		try {
			
			if (!getListaMedia().isEmpty()){
							
				String pathJasper = FacesUtil.getCurrentDirectory()+"/WEB-INF/classes/br/com/sistema/vieweb";		
				
				String reportFileName = pathJasper + File.separator + "ComparativoMediaEncomendas.jasper";								
								
				String data_aa = getMediaGeralEncomendasDAO().getAnoAnterior(MySQLDAO.formata_ddMMyyyy(getDataVigencia()));
				String data_at = MySQLDAO.formata_ddMMyyyy(getDataVigencia());
				String data_ma = getMediaGeralEncomendasDAO().getMesAnterior(MySQLDAO.formata_ddMMyyyy(getDataVigencia()));
								
				String regiao_footer = "TOTAL:";
				
				if (!getRegioesSelecionadas().isEmpty()){
					
					regiao_footer = "TOTAL PARA REGIÃO(ÕES):";
					
				} else {
					
					if (!getCobrancasSelecionadas().isEmpty()){
						
						regiao_footer = "TOTAL PARA COBRANÇA(S):";
						
					} else {
						
						if (!getImoveisSelecionados().isEmpty()){
							
							regiao_footer = "TOTAL PARA IMÓVEL(IS):";
							
						} else {
							
							if (!getSupervisoresSelecionados().isEmpty()){
								
								regiao_footer = "TOTAL PARA SUPERVISOR(ES):";
								
							}							
						}						
					}				
				}	
				
				String target = null;
				
				if (!getRegioesSelecionadas().isEmpty()){
					
					target = getDescricaoRegioes();
					
				} else {
					
					if (!getSupervisoresSelecionados().isEmpty()){
					
						target = "RELATÓRIO EMITIDO POR SUPERVISOR";
						
					} else {
						
						if (!getCobrancasSelecionadas().isEmpty()){
							
							target = "RELATÓRIO EMITIDO POR COBRANÇA";
							
						} else {
						
							if (!getImoveisSelecionados().isEmpty()){
								
								target ="RELATÓRIO EMITIDO POR IMÓVEL";
								
							}						
						}	 					
					}		 								
				}			 
				
				Map<String, String> parametros = new HashMap<String, String>();				
				parametros.put("data_aa", data_aa);
				parametros.put("data_at", data_at);
				parametros.put("data_ma", data_ma);
				parametros.put("regiao_footer", regiao_footer);
				parametros.put("regiao", target);
				parametros.put("usuario", MySQLDAO.getUsuarioLogado());	
				parametros.put("pathSubReport", pathJasper + File.separator + "ResumoComparativoMediaEncomendas.jasper");

				JasperReport report = (JasperReport) JRLoader.loadObject(reportFileName);
				
				JasperPrint print = JasperFillManager.fillReport(report, parametros, jrDS);				
				
				byte[] bytes = JasperExportManager.exportReportToPdf(print);

				FacesContext facesContext = FacesContext.getCurrentInstance();
				HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
												 
				response.setContentType("application/pdf");
				response.setContentLength(bytes.length);
				response.setHeader("Content-Disposition","inline; filename=report.pdf"); 
				
				ServletOutputStream ouputStream = response.getOutputStream(); 
				
				ouputStream.write(bytes, 0, bytes.length); 
				ouputStream.flush(); 
				ouputStream.close(); 
				
				facesContext.responseComplete();
								
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

Na linha 98 acontece o erro: Caused by: java.lang.NoSuchMethodException: Unknown property ‘linhas’…

O que estou fazendo de errado? O resto está como vc me explicou… Obrigado pela ajuda…

vi-gb

Esta é a linha em que o relatorio é preenchido eu acho.
Posta o xml do seu relatorio, lá deve ter um field ou parameter com este nome.

Criado 6 de agosto de 2009
Ultima resposta 12 de ago. de 2009
Respostas 14
Participantes 2