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

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:

[code] 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();
	}
	
}[/code]

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

Ninguém passou por isso?

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:

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…

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.

[code]private JRBeanCollectionDataSource createCollectionDataSource() {

	try {
		
		return new JRBeanCollectionDataSource(this.linhas);
	} catch (Exception e) {
		System.out.println(e.getMessage());
		return null;
	}
}[/code]

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

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

[code]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;
}

}[/code]
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

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…

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

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…

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

[code]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;
}

}[/code]

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

Espero que este exemplo te ajude.

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

sim linhas é um field do iReport.

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…

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.