Ajudem! Jasper + Servlet, Subreports vindo em Branco

14 respostas
ccfranqueira

Olá para todos, já faz um tempo que estou pesquisando sobre isso, eu to fazendo um relatório de despesas e receitas nele eu chamo dois subrelatórios, no ireport funciona normalmente, mas quando tento exibir no servlet aparece o relatório principal e não os sub, achei um tópico que falava para criar um hashmap e nele carregar os parâmetros de onde se encontram o subrelatório, mas não funcionou.
No meu servlet eu carrego o resultset no relatório principal e nesse relatório ele passa os parâmetros para os sub para q eles possam compilar.

Código Servlet sem parametro:

public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        ServletOutputStream outputStream = response.getOutputStream();
        Connection conn = null;
        Statement stm = null;
        ResultSet rs= null;
        String sql= request.getParameter("sql");
        String nomeRelatorio = request.getParameter("relatorio");
        Map parameterMap = new HashMap();
        JRResultSetDataSource jrRS = null;
        byte[] bytes = null;
        try{
            Class.forName("com.mysql.jdbc.Driver");
            conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost/sgf","root","123456");

            stm = (Statement) conn.createStatement();
            rs = stm.executeQuery(sql);

            jrRS = new JRResultSetDataSource(rs);
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }

        try{
            InputStream url = this.getClass().getClassLoader().getResourceAsStream("/web/relatorios/"+nomeRelatorio+".jasper");
            JasperReport relatorioJasper = (JasperReport)JRLoader.loadObject(url);
            bytes = JasperRunManager.runReportToPdf(relatorioJasper, parameterMap,jrRS);

        }
        catch(Exception e){
            System.out.println("erro:"+e.getMessage());
        }
        if (bytes != null && bytes.length > 900) {
            response.setContentType("application/pdf");
            outputStream.write(bytes, 0 , bytes.length);
            outputStream.flush();
            outputStream.close();
        }else{
            outputStream.flush();
            outputStream.close();
            JOptionPane.showMessageDialog(null, "Nada encontrado tente denovo.","Informação: ", JOptionPane.INFORMATION_MESSAGE);
        }

    }

Agradeço desde já, até mais;

[email removido]

14 Respostas

blackout

Opa ccfranqueira, blza?

Seguinte, vou dar duas dicas, a principio não “resolvem” teu problema, mas facilitam tua vida.

1 - Tente tirar essas informações do subrelatório para que as mesmas estejam no relatório principal.
Subrelatórios deixam seu relatório mais difícil de entender e manipular. Só use se for muito necessário.

2 - Tire o sql de dentro da aplicação e coloque-o diretamente dentro do iReport. Quando você chamar o relatório, vai precisar somente passar a conexão para o mesmo, o resto ele fará sozinho.
Dessa maneira você simplifica teu código e deixa mais claro as responsabilidades de cada coisa.

Como eu disse, não resolve diretamente seu problema, mas indiretamente acho que resolve.

Espero ter ajudado.
Grande abraço!

Blackout

Fernando_Generoso_da

blackout:
Opa ccfranqueira, blza?

Seguinte, vou dar duas dicas, a principio não “resolvem” teu problema, mas facilitam tua vida.

1 - Tente tirar essas informações do subrelatório para que as mesmas estejam no relatório principal.
Subrelatórios deixam seu relatório mais difícil de entender e manipular. Só use se for muito necessário.

2 - Tire o sql de dentro da aplicação e coloque-o diretamente dentro do iReport. Quando você chamar o relatório, vai precisar somente passar a conexão para o mesmo, o resto ele fará sozinho.
Dessa maneira você simplifica teu código e deixa mais claro as responsabilidades de cada coisa.

Como eu disse, não resolve diretamente seu problema, mas indiretamente acho que resolve.

Espero ter ajudado.
Grande abraço!

Blackout

Olha, Tua primeira dica está ok. Subreports, quando desnecessários, não devem ser utilizados…

Tua segunda dica, eu discordo. Eu acho o correto a manipulação dos dados serem feitos na aplicação, e enviar os dados já prontos para o relatório.

Quanto ao problema, geralmente quando isso acontece, é problema no JRDataSource…que está indo vazio. Primeiro, verifique se ele contém dados. Se ele conter dados, dah uma verificada no teu subreport, em details…

Fernando

blackout

Fernando Generoso da Rosa:
blackout:
Opa ccfranqueira, blza?

Seguinte, vou dar duas dicas, a principio não “resolvem” teu problema, mas facilitam tua vida.

1 - Tente tirar essas informações do subrelatório para que as mesmas estejam no relatório principal.
Subrelatórios deixam seu relatório mais difícil de entender e manipular. Só use se for muito necessário.

2 - Tire o sql de dentro da aplicação e coloque-o diretamente dentro do iReport. Quando você chamar o relatório, vai precisar somente passar a conexão para o mesmo, o resto ele fará sozinho.
Dessa maneira você simplifica teu código e deixa mais claro as responsabilidades de cada coisa.

Como eu disse, não resolve diretamente seu problema, mas indiretamente acho que resolve.

Espero ter ajudado.
Grande abraço!

Blackout

Olha, Tua primeira dica está ok. Subreports, quando desnecessários, não devem ser utilizados…

Tua segunda dica, eu discordo. Eu acho o correto a manipulação dos dados serem feitos na aplicação, e enviar os dados já prontos para o relatório.

Quanto ao problema, geralmente quando isso acontece, é problema no JRDataSource…que está indo vazio. Primeiro, verifique se ele contém dados. Se ele conter dados, dah uma verificada no teu subreport, em details…

Fernando

Então… eu já testei as duas abordagens, acho que no final das contas pode até ser uma questão de gosto.
Mas eu prefiro, colocar o sql dentro do relatório, ao invés de mandar os objetos prontos para o relatório.

Prefiro assim por algumas razões:

  • Reduz código pra gerar o relatório.
  • Aumenta a “clareza” do código, ou seja, fica mais fácil de entender.
  • Delega toda a função de vizualização do relatório para o próprio relatório, inclusive os dados que são vizualizados.
  • Quando o sql é executado dentro do relatório, o próprio iReport cria as variáveis que são retornadas pelo result set do sql.
ccfranqueira

Olha tentei, mais um pouco, mandei por parâmetro, mandei subreport com sql sem parâmetro, e nada de aparecer, vocês poderiam verificar se tem algo no meu código que tenho que acrescentar, pois no ireport ele compila… :?

Agradeço desde já, até mais;

[email removido]

blackout

ccfranqueira:
Olha tentei, mais um pouco, mandei por parâmetro, mandei subreport com sql sem parâmetro, e nada de aparecer, vocês poderiam verificar se tem algo no meu código que tenho que acrescentar, pois no ireport ele compila… :?

Agradeço desde já, até mais;

[email removido]

Vamos tentar algo a mais então… a principio, de errado mesmo não vejo nada, mas talvez o errado seja estar faltando algumas coisas ali, por exemplo:
Nessa parte do código:

try{  
   InputStream url = this.getClass().getClassLoader().getResourceAsStream("/web/relatorios/"+nomeRelatorio+".jasper");  
   JasperReport relatorioJasper = (JasperReport)JRLoader.loadObject(url);  
   bytes = JasperRunManager.runReportToPdf(relatorioJasper, parameterMap,jrRS);     
}  
catch...

Vamos substituir pelo seguinte:

try{  
   InputStream url = this.getClass().getClassLoader().getResourceAsStream("/web/relatorios/"+nomeRelatorio+".jasper");  
   gerarPDF(response, url, nomeRelatorio);
}  
catch...
private void gerarPDF(HttpServletResponse response, InputStream inputStream, String fileName)
{
   response.setContentType(CONTENT_TYPE_PDF);
   response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".pdf");

   try
   {
       //JasperReport relatorioJasper = (JasperReport)JRLoader.loadObject(url);  //não lembro o que essa linha faz, mas acho que não é mais necessária
       //bytes = JasperRunManager.runReportToPdf(relatorioJasper, parameterMap,jrRS); //essa linha será substituída pela linha abaixo.
       JasperRunManager.runReportToPdfStream(inputStream, response.getOutputStream(), parameterMap, jrRS);
   }
   catch (Exception e)
   {
       throw new Exception("msg.erroOperacao", e);
    }
}
R

Acho que o problema é o caminho em seu relatorio. Quando vc faz no ireports ele usa o caminho real do relatorio.
Vc vai ter q passar o caminho do relatorio para o sub-relatorio.

ccfranqueira

blackout, implementei do modo que você passou e mesmo fazendo download o relatório não abriu o subreport, vou tentar do modo do rjbcordeiro, que eu acho que funcione.

Agradeço desde já, até mais;

[email removido]

blackout

ccfranqueira:
blackout, implementei do modo que você passou e mesmo fazendo download o relatório não abriu o subreport, vou tentar do modo do rjbcordeiro, que eu acho que funcione.

Agradeço desde já, até mais;

[email removido]

Mas nada aparece no relatório todo? Tipo, fora do subrelatório tem alguma coisa? Se sim, essa alguma coisa, aparece?
Se aparecer, ok, o problema está com o subrelatório, senão, o problema está no relatório como um todo.

Não aparece nenhum erro no stackTrace do console do eclipse?
Você já debugou linha por linha pra ver se não ocorre nenhuma exceção em alguma delas?

ccfranqueira

Bom dia, sim relatório normalmente aparece, mas não o sub sendo que no ireport o sub aparece, já erro não aperece nenhum e já debuguei várias vezes, mas nada muda.

Obrigado e até mais.

[email removido]

Gerva

seguinte mano

muuuito provável que o problema é em encontrar os Subreports, você precisa enviar este parametro para o relatório "SUBREPORT_DIR" ex:

parametros.put("SUBREPORT_DIR", "caminho/Jasper/Subreports");

caso não for isso, talves o subreport esta com um tamanho maior do que o tamanho maximo atribuido a ele (que provavelmente ira variar de acordo com a quantidade de valores que ele carregar, explicando o fato de no ireport ele aparecer)

Kleber-rr

Eae man, conseguiu resolver??
Se conseguiu, posta a correção, por favor. Estou com o mesmo problema.

Agradeço.

ccfranqueira:
Bom dia, sim relatório normalmente aparece, mas não o sub sendo que no ireport o sub aparece, já erro não aperece nenhum e já debuguei várias vezes, mas nada muda.

Obrigado e até mais.

[email removido]

ccfranqueira

Kleber, eu não achei solução para resolver falei com meu cliente e sugeri a divisão do relatório em dois.

Minha sorte foi que ele aceitou.

Mas eu ainda estou procurando uma solução.

Até mais.

Kleber-rr

Obrigado por ter respondido. No meu caso, eu não tenho outra opção. Tenho que resolver isso.
Espero que o pessoal mais experiente do fórum ajude, pois vejo que é uma dúvida comum, porém poucos tópicos relacionados à ela foram resolvidos.

Abs.

ccfranqueira:
Kleber, eu não achei solução para resolver falei com meu cliente e sugeri a divisão do relatório em dois.

Minha sorte foi que ele aceitou.

Mas eu ainda estou procurando uma solução.

Até mais.

R

Kleber-rr:
Obrigado por ter respondido. No meu caso, eu não tenho outra opção. Tenho que resolver isso.
Espero que o pessoal mais experiente do fórum ajude, pois vejo que é uma dúvida comum, porém poucos tópicos relacionados à ela foram resolvidos.

Abs.

ccfranqueira:
Kleber, eu não achei solução para resolver falei com meu cliente e sugeri a divisão do relatório em dois.

Minha sorte foi que ele aceitou.

Mas eu ainda estou procurando uma solução.

Até mais.

Olá.
-Vá na aba Propriedades do seu Subreport;

  • Na opção ‘When no Data’,escolha a opção “All Sections,no Detail”;
Criado 15 de outubro de 2010
Ultima resposta 16 de nov. de 2010
Respostas 14
Participantes 7