Emissão de relatórios em sistema web

[quote=ivesbertoli]Eu sempre crio um diretório dentro da pasta WEB e ma referencio a ele através do getRealPath, pois nem sembre é sabido onde o sistema e qual ambiente o sistema estará implantado.

String relatorio = request.getRealPath("WEB/jasper/ModeloGuia.jasper"); try { java.util.Map parametro = new java.util.HashMap(); parametro.put("idemitida", idguia); JasperReport jr = (JasperReport) JRLoader.loadObject(relatorio); byte buffer[] = JasperRunManager.runReportToPdf(jr, parametro, banco.ConnectionFactory.getConnection()); response.setContentType("application/pdf"); response.setContentLength(buffer.length); ServletOutputStream outputStream = response.getOutputStream(); outputStream.write(buffer, 0, buffer.length); outputStream.flush(); outputStream.close(); } catch (JRException ex) { Logger.getLogger(bbIndex.class.getName()).log(Level.SEVERE, null, ex); }[/quote]

Olha só, parou de dar null sabe-se la por que motivo.
Agora ele não abre nem em uma outra aba e nem pede pra baixar o pdf, simplesmente exibe o seguinte:

E mais uma centena de linhas assim.
Saberia me dizer por que?
Obrigado!

Vamos por parte,
Vou fazer uma pergunta.

Qual a versão do jasperreport e ireport q vc ta usando se é q usa?

feita a pergunta vou esclarecer o erro de “linhas assim”.

seguinte: estas linhas são do arquivo pdf compilado e as vezes ele aparece assim por seu navegador não ter conseguido executalo em um programa leitor de pdf. compreende?
ok… supondo que seu sistema ta chamando o arquivo pdf normalmente da uma olhada nesta parte do leitor de pdf.

ps.: É nesse ponto que entra em cena o conceito de Servlet, que é uma classe especial JAVA que herda características da classe HttpServlet, permitindo que ela seja capaz de tratar requisições. Ao fazer isso, ela pode redefinir alguns métodos, chamados de serviço, que irão fazer a lógica necessária.
Os dois métodos mais utilizados nessa abordagem são o doGET (para tratar requisições que chegarem do tipo GET) e o doPOST (para tratar requisições que chegarem do tipo POST). Dentro desses métodos bancos de dados podem ser acessados, objetos criados, lógica inserida, enfim, qualquer tipo de lógica que seja válida num programa JAVA. Um diferencial por se tratar de aplicações web está na possibilidade de escrever código HTML que será enviado para a saída padrão, que normalmente é um navegador (como o Firefox) e será exibido da forma apropriada, como uma página da Internet.
Por tanto, podendo ser a interface entre o cliente e o servidor.

uma aula servlet de graça!

[quote=phmjunior]Vamos por parte,
Vou fazer uma pergunta.

Qual a versão do jasperreport e ireport q vc ta usando se é q usa?

[/quote]
Sim, uso JasperReports na versão 3.1.4, a princípio sem chances de usar outra (versões de bibliotecas também costumam ser controlados por aqui).

Quanto a isso eu entendi perfeitamente.
Já foi um parto instalar o AdobeReader no ubuntu 7.10, versão do servidor que ta rodando esse meu client remoto aqui (que infelizmente também não pode ser mudada a princípio, pelos mesmos motivos citados acima).
Também tenho instalado o plugin do adobereader no firefox corretamente. Ambos funcionando muito bem, obrigado.
O que eu quero, pra ser bem preciso, é que ele abra em outra aba (ou em outra janela, dependendo da configuração do navegador) o pdf e caso não haja plugin instalado que seja exigido o seu download. Entende?

Sei o que é um servlet.
A questão é que ele é executado no lado do servidor, por isso que não posso mandar ele abrir interfaces gráficas pelo Servlet, pois esse [color=darkred]será executado no servidor[/color].

Eve, conseguiu executar o JasperView no servlet com sucesso?

Meu jovem,
Segue um trecho do código comentado para vc entender melhor

// responsável por ler o arquivo jrxml "DO LADO DO SERVIDOR"            
JasperDesign design = JasperManager.loadXmlDesign(dir + "relatorios/comprovante_rendimentos1.jrxml");   

// compila o arquivo anterior para o formato jasper "DO LADO DO SERVIDOR"
JasperReport jr = JasperManager.compileReport(design);   

// Isso aqui é obrigatório vc quando trabalha com geração de pdf com jasper vc tera sempre q passar um parametro para o jasper mesmo sendo nulo
HashMap parameters = new HashMap();   
parameters.put("PAR_PEDID", 1);   

// aqui ele imprime o arquivo jasper em pdf "NO LADO DO SERVIDOR"
JasperPrint impressao = JasperManager.fillReport(jr, parameters, con);   

// aqui ele mostra o arquivo já em pdf na tela do seu browser, vindo "DO LADO DO SERVIDOR", ou seja ele funciona como um link.
JasperViewer jrviewer = new JasperViewer(impressao, false);   
// aqui ele de fato chama o cara da forma q vc quiser, seja parent, blank ou self
jrviewer.show();  

espero q ajude, saiba que tudo isso ocorre no lado do servidor e mesmo assim ele funciona.
sugiro que vc estude bem os processo assima para entender como elas são efetivamente ocorridos.

o pior é q aqui eu uso em todos os meus sistemas e roda perfeitamente.
o servlet trabalha do lado do servidor mas vc tanto pode solicitar request quanto response, get ou post.

outra sugestão para vc q trabalha com jsf é um livro q ensina como criar relatório e outra coisas bem legai com jsf, segue o nome do livro e autor:

Livro: Java na Web com JSF (Spring, Hibernate e Netbeans)
Autor: Yuri Marx P. Gomes

muito bom recomendo.

Meu filho, [color=darkred]minha dúvida não é como gerar um relatório,[/color] disso tudo eu seii!!

O problema é exibir o relatório montado no contexto web.
A estrategia que adotei é converte-lo para jpg “concatenando” as páginas num BufferedImage dinamicamente e exibi-la num MediaOutput.
Isso funciona muito bem, mas estou tendo problemas quando quero imprimi-lo, daí a alternativa de abri-lo no navegador diretamente como pdf.

A propósito, o método show do JasperViewer é deprecated, estude a possibilidade de substitui-lo pelo setVisible(true);
Também sugiro que estude a possibilidade de tratar com os relatórios já compilados (.jasper), pra poder pular essa parte na geração dos relatórios que causa um overhead desnecessário.

Ignorando esses passos todos, por que quando eu uso o JasperViewer no meu ManagedBean obtenho aquela exception do X11 citada acima?

Tchello alguns usuarios do guj deveriam fazer curso de interpretacao de textos rsrs

agora, velho, existem coisas que nao tem jeito, para abrir ele no navegador vc PRECISA do plugin ou entao deixa o usuario fazer download, que mal tem isso?

abrasssssssss

[quote=renanreismartins]Tchello

agora, velho, existem coisas que nao tem jeito, para abrir ele no navegador vc PRECISA do plugin ou entao deixa o usuario fazer download, que mal tem isso?

abrasssssssss[/quote]

Exatamente, nenhum problema, é exatamente o que quero.
Acontece que ele ta exibindo aqueles caracteres zuados.
Tenho o plugin instalado aqui sim, tanto que de outros sites já abri pdf’s nesse firefoca ontem mesmo.
É exatamente o que quero: se existir o plugin abrir o pdf em outra aba, se não existir mandar o arquivo pdf pro usuário salvar.
Teria alguma dica/sugestão/milagre/macumba ? uAuhaHUauhUHAuhA

Abraços!

Ok Tchello
não vamos discutir isso aqui pois, sabemos q não vai ajudar.
seu problema não ta diretamente na aplicação e sim no Java e SO q vc usa
qual a versão do java q vc usa no ubuntu?

deve ser algum problema de versão do seu Java.
tenta fazer isso no console.

java -Djava.awt.headless=true

depois restarta sua aplicação ou melhor restarta o tomcat, Jboss ou seja lá o q vc use.

qualquer coisa avisa que temos mais soluções para esse problema.

não entendi a sua meu amigo!!! será q é a tal “interpretacao de textos” q vc fala?

Tchello aqui eu faço um pouco diferente, ao inves de chamar o JasperRunManager.runReportToPdf, crio um JasperPrint. isso eh um metodo ejb.

JasperPrint print = JasperFillManager.fillReport(getClass().getResourceAsStream(("/relatorio/jasper/chamado.jasper")), parametros, ds);

onde parameteos é o map e ds é uma implementação de JRDataSource… bom mas enfim crio um JRPdfExporter.

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

JRPdfExporter exporter = new JRPdfExporter();
exporter.setParameter(JRPdfExporterParameter.JASPER_PRINT, print);
exporter.setParameter(JRPdfExporterParameter.OUTPUT_STREAM, outputStream);
exporter.setParameter(JRPdfExporterParameter.METADATA_AUTHOR, "OSWeb");

exporter.exportReport();

bom entao retorno meu ByteArrayOutputStream. No meu servlet recebo ele e entao imprimo:

response.setContentType("application/pdf");

ByteArrayOutputStream ou = gerenciarChamado.imprimir(chamado);

ServletOutputStream outputStream = response.getOutputStream();

ou.writeTo(outputStream);
outputStream.flush();
outputStream.close();

espero que ajude

abrassss

Bom, eu fiz como o phmjunior colocou aqui… porém não funcionou, deu um erro, mas pelo q pude ver no erro, nao é por conta do JasperView… =/

Erro:

java.lang.NoClassDefFoundError: net/sf/jasperreports/engine/JasperManager br.santacruz.tcc.control.RelatorioGeralControl.geraRelatorio(RelatorioGeralControl.java:49) br.santacruz.tcc.servlet.RelatorioGeralServlet.doPost(RelatorioGeralServlet.java:52) javax.servlet.http.HttpServlet.service(HttpServlet.java:637) javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Código:

[code]public class RelatorioGeralControl {

private Connection connect = null;
private String driver = "com.mysql.jdbc.Driver";
private String host = "//localhost:3306";
private String base = "snr";
private String user = "root";
private String senha = "";
private ResultSet rs = null;
private String valores[] = new String[10];	
	
//local relatorios
//private String dir1 = System.getProperty("user.dir") + "/web/";
private String dir = "F:\\PortalCorporativoWebTCC\\PortalCorporativoWebTCC\\WebContent\\Relatorios";

public void geraRelatorio(String sql, String relatorio){
	try{
		if(connect == null){
			Class.forName(driver);
			connect = DriverManager.getConnection("jdbc:mysql:" + host + "/" + base, user, senha);
			Statement stmt = connect.createStatement();
			rs = stmt.executeQuery(sql.toString());
			while(rs.next()){
				for(int i = 1; i < 10; i++){
					valores[i] = rs.getString(i);
				}
			}
		}
	}catch (Exception e){
		System.err.println("Problema na conexão");
		e.printStackTrace();
	}
	try{
		JasperDesign design = JasperManager.loadXmlDesign(dir + "Relatorios/geral.jasper");
		JasperReport jr = JasperManager.compileReport(design);
		HashMap parameters = new HashMap();
		parameters.put("PAR_PEDID", 1);
		//parameters.put("PARAMETRO_2", array(2));
		JasperPrint impressao = JasperManager.fillReport(jr, parameters, connect);
		JasperViewer jrviewer = new JasperViewer(impressao, false);
		jrviewer.show();			
	}catch(Exception e){
		e.printStackTrace();
	}
}	

}
[/code]

Código servlet:

[code]protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	String cmd = request.getParameter("cmd");		
	if(cmd == null){
		cmd = "principal";
	}
	
	String relatorio = "principal";
	String sql = "Select * from desp_rateio";
	try{
		if(cmd.equalsIgnoreCase(relatorio)){
			RelatorioGeralControl relatorioGeralControl = new RelatorioGeralControl();
			relatorioGeralControl.geraRelatorio(sql, relatorio);
		}			
	}catch(Exception e){
		e.printStackTrace();
	}
	
}[/code]

:?: :!: :?: :!: :?: :!:

[quote=phmjunior]

java -Djava.awt.headless=true

depois restarta sua aplicação ou melhor restarta o tomcat, Jboss ou seja lá o q vc use.

qualquer coisa avisa que temos mais soluções para esse problema.[/quote]

Ainda não foi, ele ta dando “null”.
O relatório é gerado normalmente, adicionei o argumento sugerido e parou de daro o erro do X11.
Não é um NPE, a exception ainda é uma HeadlessException, contendo a menssagem “null”.

Renan, como estou usando JSF o ServletOutputStream eu obtenho atraves do FacesContext, mas esse (o ServletOutputStream) não possui o método writeTo, estranho não?

Abraços.

eve_bsi,
no seu caso é necessário você ter essa lib JasperReport no classpath da sua aplicação.
segue link para baixar a lib

http://webscripts.softpedia.com/script/Health/JasperReports-31138.html

Tchello,

deixa eu ver se entendi direito;
você digitou o comando e parou de dar o erro x11, e seus relatorios são gerados normalmente? só q o erro HeadlessException continua só q vem null certo?

ele gera o relatório antes ou depois do erro?

Mas eu já tenho essa lib…

faz o seguinte procure no classpath do java do tomcat ou jboss e verifica se ela existe porai.
caso não tire ela do classpath de sua aplicação e cole direto nos classpath q informei assima.

vc tem telefone? :wink: (brincadeira)

[quote=eve_bsi][quote=phmjunior]
eve_bsi,
no seu caso é necessário você ter essa lib JasperReport no classpath da sua aplicação.
segue link para baixar a lib

http://webscripts.softpedia.com/script/Health/JasperReports-31138.html
[/quote]

Mas eu já tenho essa lib…

[/quote]
Colocou as libs no classpath da aplicação ou da IDE?

[quote=phmjunior]

Tchello,

deixa eu ver se entendi direito;
você digitou o comando e parou de dar o erro x11, e seus relatorios são gerados normalmente? só q o erro HeadlessException continua só q vem null certo?

ele gera o relatório antes ou depois do erro?[/quote]

O relatório é gerado antes e sempre funcionou, o único problema é a utilização do JasperViewer.
Adicionei aquele argumento nos OPTS do java no run.sh do JBoss.
O problema é que o JasperView continua lançando uma exceção (HeadlessException) com a mensagem “null”. Compreende?
Vale lembrar que uso JBoss 4.2.2 GA, rodando num Ubuntu Server 9.04 (ou seja, sem o X).

Então, o JasperViewer ele abre uma janela swing onde o relatório é exibido, como não tem a interface gráfica ele não tem onde mostrar isso deve ser a origem desse null.
Por que não gera um PDF e disponibiliza pra download.

[quote=furutani][quote=Tchello]

O relatório é gerado antes e sempre funcionou, o único problema é a utilização do JasperViewer.
Adicionei aquele argumento nos OPTS do java no run.sh do JBoss.
O problema é que o JasperView continua lançando uma exceção (HeadlessException) com a mensagem “null”. Compreende?
Vale lembrar que uso JBoss 4.2.2 GA, rodando num Ubuntu Server 9.04 (ou seja, sem o X).
[/quote]
Então, o JasperViewer ele abre uma janela swing onde o relatório é exibido, como não tem a interface gráfica ele não tem onde mostrar isso deve ser a origem desse null.
Por que não gera um PDF e disponibiliza pra download.[/quote]

Ai é que tá, como é server-side ele usa o X do servidor, certo?

Edit: já ia esquecendo, é o que estou tentando, se ver meus posts anteriores notará que também enfrento um problema com isso.

Abraços.

Só para gerar o PDF não sei se ele usa não.
Eu tenho vários servidores linux gerando relatórios em PDF e não teve problema.