IReport - gerando um report em excel - Problema

19 respostas
M

Bom Dia

Estou estudando o IReport porque ele atende exatamente ao que preciso na minha aplicação.
Vi alguns exemplos, criei no IReport um exemplo de um relatório simples e (no próprio IReport) consigo executa-lo e visualizar os registros do banco. Mas quando executo a minha servlet, o arquivo abre vazio!

Por favor, alguém me ajude. Já pesquisei a respeito, mas desde ontem não evoluo.
Segue abaixo minha servlet:

package com.ericsson.report;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ericsson.dao.GerContratoDao;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRResultSetDataSource;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JExcelApiExporter;
import net.sf.jasperreports.engine.export.JExcelApiExporterParameter;

public class ProgramacaoReport extends HttpServlet {
	
	protected void doPost(HttpServletRequest req, HttpServletResponse res)
	throws ServletException, IOException 
	{
		
		Connection connection = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		String sql = "SELECT * FROM livros";
		
		try {
			connection = GerContratoDao.getConnection();
			pstmt = connection.prepareStatement(sql);
			rs = pstmt.executeQuery(sql);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		 
		JRDataSource jrDS = new JRResultSetDataSource(rs);
		
		Map parametros = new HashMap();
		String pathJasper = getServletContext().getRealPath(
		"/WEB-INF/classes/com/ericsson/report/")
		+ "/";
		   
		JasperPrint jasperPrint;
		
		try {
			
			jasperPrint = JasperFillManager.fillReport(pathJasper
					+ "report1.jasper", parametros, jrDS);
		
			//-------------------------------------------------   
			//XLS OUTPUT STREAM   
			//-------------------------------------------------           
			                   
			JExcelApiExporter exporter = new JExcelApiExporter();   
			ByteArrayOutputStream xlsReport = new ByteArrayOutputStream();   
			exporter.setParameter(JExcelApiExporterParameter.JASPER_PRINT, jasperPrint);   
			exporter.setParameter(JExcelApiExporterParameter.OUTPUT_STREAM, xlsReport);   
			exporter.setParameter(JExcelApiExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);   
			exporter.setParameter(JExcelApiExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.TRUE);   
			exporter.setParameter(JExcelApiExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.TRUE);   
			  
		
			exporter.exportReport();
		   
			byte[] bytes = xlsReport.toByteArray();   
			res.setContentType("application/vnd.ms-excel");   
			res.setContentLength(bytes.length);   
			xlsReport.close();   
			OutputStream ouputStream = res.getOutputStream();   
			ouputStream.write(bytes, 0, bytes.length);   
			ouputStream.flush();   
			ouputStream.close();
			
		} catch (JRException e) {
			e.printStackTrace();
		} 
	}
	
	protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1)
	throws ServletException, IOException {
		doPost(arg0, arg1);
	}
}

Obrigada

19 Respostas

T

Mas o aplicativo retorna algum erro?

Documento em branco? O que ocorre??

Ficou vago o tópico :wink:

Att. Jonas

T

ps.: Verifique se as informações estão sendo enviadas para o relatório

JRDataSource jrDS = new JRResultSetDataSource(rs);

//VERIFICANDO RESULT SET
System.out.println("RS AQUI: "+rs);
//FIM DO RESULT SET
System.out.println("TERMINOU");

Att. Jonas

M

Oi TheKill

Então… Eu já tinha testado. O ResultSet traz certinho os meus registros.
Não é gerado erro algum. Simplesmente o report abre em branco!

Tentei fazer ele apenas apresentar em pdf ( é mais simples a conversão). E a mesma coisa acontece: Abre o relatório em branco, inclusive os textos que são estáticos não são exibidos.

Eu não sei se ele está criando um novo jasper, ou se é algum problema de configuração do Eclipse… Eu nunca usei essa ferramenta. Por favor, Thekill, eu preciso muito de ajuda.

Abs.

T
try {  
               
             jasperPrint = JasperFillManager.fillReport(pathJasper  
                     + "report1.jasper", parametros, jrDS);

Observação, utilize o jrxml, exemplo abaixo:

try {  
               
             jasperPrint = JasperFillManager.fillReport(pathJasper  
                     + "report1.jrxml", parametros, jrDS);  
//...

PS.: O nome que vc gerou do relatorio é report1 ? Compilou e colocou dentro do projeto?

Att. Jonas

M

O nome do meu report é report1.

Dessa maneira, pelo .jrxml, ele nem abre o report, nem vazio. Simplesmente abre uma página em branco… =(

T

Desculpe não sei te dizer especificamente qual erro,

Porém talvez seja isso:

Relatório errado,
Aquela classe para exportar excel,
ou até mesmo aquele xlsReport que não vi vc chamar em nenhum lugar…
vc usa o exporter.setParameter e não usa aquele xlsReport…

Nao conheço essa maneira de gerar por excel então nao tenho como ajudar muito…

Att. Jonas

M

Jonas,

meu maior problema é gerar meu report com os registros. Não precisa ser em excel. Isso é de menos. Mas meus registros não aparecem! =(
Mudei o servlet pra extrair em pds ok?
Em pdf, o que é texto estático aparece, mas os registros não.
E o resultset está trazendo os registros normalmente.

Se não entender meu código, mas puder me dar um exemplo de um servlet que gere um report simples (um select * FROM só), já será da maior ajuda.
Não me abandone!!! =)

Abs.

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ericsson.dao.GerContratoDao;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRResultSetDataSource;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperManager;
import net.sf.jasperreports.engine.JasperPrint;

public class Relatorio extends HttpServlet {
	
	public static Connection con;
	public static String banco = "db_gercontrato"; // Nome do banco de dados
	public static String usuario = "root"; // Usuario do banco
	public static String senha = "root"; // Senha
	
	protected void doPost(HttpServletRequest req, HttpServletResponse res)
	throws ServletException, IOException 
	{
		Connection connection = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		String sql = "SELECT * FROM livros";
		
		try {
			connection = GerContratoDao.getConnection();
			pstmt = connection.prepareStatement(sql);
			rs = pstmt.executeQuery(sql);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		  
		JRDataSource jrDS = new JRResultSetDataSource(rs);
		
		// Na variavel pathJasper ficara o caminho do diretório para
		// os relatórios compilados (.jasper)
		String pathJasper = getServletContext().getRealPath(
			"/WEB-INF/classes/com/ericsson/report/")
			+ "/";
		
		List excludedCities = new ArrayList();	
		excludedCities.add("teste1");
		
		// A variavel path armazena o caminho real para o contexto
		// isso é util pois o seu web container pode estar instalado em lugares diferentes
		String path = getServletContext().getRealPath("/");
		// Parametros do relatorio
		Map parametros = new HashMap();
		
		try {
			
			// Aqui ele cria o relatório
			JasperPrint impressao = JasperFillManager.fillReport(pathJasper
			+ "report1.jasper", parametros, jrDS);;
					
			// Grava o relatório em disco em pdf
			JasperManager.printReportToPdfFile(impressao, path
			+ "/Relatorio.pdf");
			// Redireciona para o pdf gerado
			res.sendRedirect("Relatorio.pdf");
			
		} catch (Exception e) {
		res.getWriter().println("Erro ao gerar o relatório: " + e);
		}
	}
	
	protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1)
	throws ServletException, IOException {
		doPost(arg0, arg1);
	}

}
T

Faz o seguinte,

Me diga quais os campos que existem no relatório,
e seus respectivos nomes e tabela do banco

M

é um report simples. Só fiz pra entender como funciona o IReport.

Então minha tabela no sql é assim:

CREATE TABLE livros (
cd_livro int(11) unsigned NOT NULL auto_increment,
Titulo varchar(100) default NULL,
ISBN int(15) default NULL,
DataLancamento datetime default NULL,
PRIMARY KEY (cd_livro)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO livros (cd_livro, Titulo, ISBN, DataLancamento) VALUES
(1,‘Head First Servlets & JSP’,596005407,‘2004-07-01 00:00:00’),
(2,‘SQL Curso Prático’,857522041,‘2005-02-10 00:00:00’);

Na tela só tenho um estático “Título X” e um textfield com o Titulo.
Só. Se quiser até te mando o jxml.

Quando rodo no IReport, ele traz os dois registros. Mas no eclipse …
Acho que talvez possa ser alguma configuração da conexão do IReport com o banco através do Eclipe. Pq não faz sentido…

Obrigada mais uma vez

T

Espere, acho que vc nao entendeu oque eu perguntei…

Novamente, vamos lá:

1: Quantos campos existem no relatório, quais sao eles;

2: Qual o nome dos campos que existem no relatório, e seus respectivos no Banco de Dados;

3: Uma pergunta, essas informações do relatorio vc vai enviar através de sql do Sistema para o relatório correto?

Ou o proprio relatório faz a consulta automática?

Att. Jonas

M

1 - 2 Campos: um estático “Título X” e um textfield $F{Titulo}.
2 - No banco de Dados, $F{Titulo} é Titulo
3 - Eu quero enviar os dados através de um ResultSet, mas no xml, ele também tem uma consulta direta.

T

montagfla:
1 - 2 Campos: um estático “Título X” e um textfield $F{Titulo}.
2 - No banco de Dados, $F{Titulo} é Titulo
3 - Eu quero enviar os dados através de um ResultSet, mas no xml, ele também tem uma consulta direta.

Faz uma alteração e teste:

String sql = "SELECT Titulo FROM livros";

E outra coisa, retire qualquer outra informação do relatório. deixe apenas o Titulo e o campo estático Titulo X

M

Ainda acontece a mesma coisa. Nada de registros, só executando pelo IReport.

T

Então o problema é no envio das informações do sistema para o relatório…

Verifique corretamente o seu Result Set do sistema

M

O ResultSet traz os dados. E ele também grava no componente JRDataSource.
Acredito que o problema está quando gero o report. Ele não consegue ler os dados, mas eles estão lá.
Será que ele não está usando a conexão que criei no xml e não o resultset e esta conexão não está conseguindo ler os dados pelo Eclipse?

T

Faz o seguinte.

Altere seu código para:

JRResultSetDataSource ds = new JRResultSetDataSource(rs);

Qualquer coisa, retorne o resultado.

Att. Jonas

T

Eai? Deu certo???

M

Oi Jonas… Infelizmente continua na mesma…
Fiz assim:

JRResultSetDataSource ds = new JRResultSetDataSource(rs);

if (ds.next()){
System.out.println("true");
}

JasperPrint impressao = JasperFillManager.fillReport(pathJasper
+ "report1.jasper", parametros, ds);

O Ds returna true. Mas ainda não há registros…

T

só mais uma coisa…

nao se utilize o .jasper nessas situações…

JasperPrint impressao = JasperFillManager.fillReport(pathJasper

  • “report1.jasper”, parametros, ds);

altere para o .jrxml

Outra coisa… só para testes comente aquele seu ds.next

Criado 14 de janeiro de 2010
Ultima resposta 14 de jan. de 2010
Respostas 19
Participantes 2