Relatório - Ireport erro ao gerar relatorio

03/12/2010

0

Bom dia Pessoal

Minha aplicação JSF, JPA , já olhei varios exemplos na net, mas ainda não consegui resolver e nem gerar o relatório na web.  esta dando um erro. Alguem pode me ajudar?


Segue codigo Java,


   @SuppressWarnings("deprecation")
    private List<?> todosResultsPesq() {

    try {

        if (this.dtCirurgia != null) {
        java.sql.Timestamp dataCirurgia = new java.sql.Timestamp(this.dtCirurgia.getYear(), this.dtCirurgia
            .getMonth(), this.dtCirurgia.getDate(), 0, 0, 0, 0);

        return agendaCirurgicaDao.listPesqParamClauseWhere("Obj.cancelaCirurgia <> 2 AND obj.dtCirurgia = '"
            + dataCirurgia + "'");
        }
        Date now = new Date();
        java.sql.Timestamp dataGrid = new java.sql.Timestamp(now.getYear(), now.getMonth(), now.getDate(), 0, 0, 0,
            0);
        return agendaCirurgicaDao.listPesqParamClauseWhere("Obj.cancelaCirurgia <> 2 AND obj.dtCirurgia >= '"
            + dataGrid + "'");

    } catch (Exception ex) {
        System.out.println(ex.getCause() + " -> " + ex.getMessage() + " -> " + ex.getLocalizedMessage());
    }
    return null;

    }
    

    @SuppressWarnings("unchecked")
    public void executarRelatorio(ActionEvent action) throws ParseException {

    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

    // pega o caminho do arquivo .jasper da aplicação
    InputStream reportStream = context.getExternalContext().getResourceAsStream(
        "/relatorios/agendaBlocoCirurgico.jasper");

    // envia a resposta com o MIME Type PDF
    response.setContentType("application/pdf");
    /*
     * força a abertura de download
     * response.setHeader("Content-disposition",
     * "attachment;filename=relatorio.pdf");
     */

    try {
        ServletOutputStream servletOutputStream = response.getOutputStream();

        // envia o título para o relatório, usando o parâmetro criado
        Map<String, String> parametros = new HashMap<String, String>();
        //parametros.put("TITULO", "Relatório de Compras Efetuadas no Site");

        List dados = new ArrayList();

        Map record = null;

        // varre a consulta e separa os objetos
        for (Iterator iterator = todosResultsPesq().iterator(); iterator.hasNext();) {

        Object[] o = (Object[]) iterator.next();
        record = new HashMap();
        // coloca em um Map cada um dos campos criados
        // manualmente pelo relatório
        record.put("pacinte", o[0].toString());
        record.put("procedimento", o[1].toString());
        record.put("medico", o[2].toString());
        record.put("convenio", o[3].toString());
        record.put("statusCor", o[4].toString());
        record.put("observacao", o[4].toString());

        // adiciona o List dados
        dados.add(record);

        }

        // cria uma fonte de dados para coleções
        JRBeanCollectionDataSource fonteDados = new JRBeanCollectionDataSource(dados);

        // envia para o navegador o PDF gerado
        JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parametros, fonteDados);

        servletOutputStream.flush();
        servletOutputStream.close();

    } catch (JRException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // evita erro do JSF após completar
        // a geração do relatório
        // avisando o FacesContext que a resposta está completa
        context.responseComplete();

    }
    }


Depois uso
<h:commandLink actionListener="#{agendaCirurgicaController.executarRelatorio}" value="Gerar Relatório" />
- para chamar o relatorio


Segue Erro:

09:34:07,179 ERROR AjaxViewRoot:327 - Error processing faces event for the component formGrid:j_id532
javax.faces.event.AbortProcessingException: /ti/cadastraAgendaCirurgica.xhtml @172,116 actionListener="#{agendaCirurgicaController.executarRelatorio}": java.lang.ClassCastException: br.com.scp.intranet.modelo.AgendaCirurgica cannot be cast to [Ljava.lang.Object;
    at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:118)


Cleber Faria*

Cleber Faria*

Responder

Posts

03/12/2010

Davi Costa

Bom Cleber,
duas considerações a fazer:
1-  a classe agendaCirurgicaController está declarada no faces-config dessa forma?

2- Talvez em alguma parte da sua página tenha uma comboBox de AgendaCirurgica e precise de um converter para ela.

Att Davi
Responder

03/12/2010

Cleber Faria*

sim esta declarada no faces-config minha agendaCirurgicaController, mas como faria esse converte, nao entendi.
Me parece que o erro seja alguma coisa sobre actionListener não poder fazer o cast (conversão) é isso?
Responder

03/12/2010

Cleber Faria*

Não sei se entendeu o codigo que enviei, mandei com as tags  CODE e /CODE ma nao deu certo saiu tudo desconfigurado. O meu metodo para gerar o Relatório esta correto?
Responder

03/12/2010

Davi Costa

Realmente está ruim de enchergar, só precisaremos nos preocupar com converter se tiver alguma opção de combobox dakela entidade, tem alguma na tela?
Realmente ficou ruim de ver o método de gerar relatório, postei alguns exemplos em outras threads, tenta dar uma olhada...... e por fim coloca um break-point no método para ver se pelo menos ele é chamado. E se passa por ele sem problemas.

Att Davi
Responder

03/12/2010

Davi Costa

Dando uma olhada nmelhor no seu código está um pouco estranho essa abordagem  nesse trecho de código:

 record.put("pacinte", o[0].toString());
        record.put("procedimento", o[1].toString());
        record.put("medico", o[2].toString());
        record.put("convenio", o[3].toString());
        record.put("statusCor", o[4].toString());
        record.put("observacao", o[4].toString());

Vc não está usando JPA, porque usar essa lista de Object, pq não retorna o objeto que vc realmnete quer na sua camada de persistência, mas se estiver funcionando tudo bem, depois vc repensa em refatorar isso.
Coloca um break-point para ver se em alguma linha desse método estoura.
Att Davi
Responder

03/12/2010

Cleber Faria*

Olhá o código novamente, tenho um metdo de conexao e outro do relatorio que chama essa conexão, vou enviar novamente sem as tags...

   @SuppressWarnings("deprecation")
    private List<?> todosResultsPesq() {

    try {

        if (this.dtCirurgia != null) {
        java.sql.Timestamp dataCirurgia = new java.sql.Timestamp(this.dtCirurgia.getYear(), this.dtCirurgia
            .getMonth(), this.dtCirurgia.getDate(), 0, 0, 0, 0);

        return agendaCirurgicaDao.listPesqParamClauseWhere("Obj.cancelaCirurgia <> 2 AND obj.dtCirurgia = '"
            + dataCirurgia + "'");
        }
        Date now = new Date();
        java.sql.Timestamp dataGrid = new java.sql.Timestamp(now.getYear(), now.getMonth(), now.getDate(), 0, 0, 0,
            0);
        return agendaCirurgicaDao.listPesqParamClauseWhere("Obj.cancelaCirurgia <> 2 AND obj.dtCirurgia >= '"
            + dataGrid + "'");

    } catch (Exception ex) {
        System.out.println(ex.getCause() + " -> " + ex.getMessage() + " -> " + ex.getLocalizedMessage());
    }
    return null;

    }
   

    @SuppressWarnings("unchecked")
    public void executarRelatorio(ActionEvent action) throws ParseException {

    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

    // pega o caminho do arquivo .jasper da aplicação
    InputStream reportStream = context.getExternalContext().getResourceAsStream(
        "/relatorios/agendaBlocoCirurgico.jasper");

    // envia a resposta com o MIME Type PDF
    response.setContentType("application/pdf");
    /*
     * força a abertura de download
     * response.setHeader("Content-disposition",
     * "attachment;filename=relatorio.pdf");
     */

    try {
        ServletOutputStream servletOutputStream = response.getOutputStream();

        // envia o título para o relatório, usando o parâmetro criado
        Map<String, String> parametros = new HashMap<String, String>();
        //parametros.put("TITULO", "Relatório de Compras Efetuadas no Site");

        List dados = new ArrayList();

        Map record = null;

        // varre a consulta e separa os objetos
        for (Iterator iterator = todosResultsPesq().iterator(); iterator.hasNext();) {

        Object[] o = (Object[]) iterator.next();
        record = new HashMap();
        // coloca em um Map cada um dos campos criados
        // manualmente pelo relatório
        record.put("pacinte", o[0].toString());
        record.put("procedimento", o[1].toString());
        record.put("medico", o[2].toString());
        record.put("convenio", o[3].toString());
        record.put("statusCor", o[4].toString());
        record.put("observacao", o[4].toString());

        // adiciona o List dados
        dados.add(record);

        }

        // cria uma fonte de dados para coleções
        JRBeanCollectionDataSource fonteDados = new JRBeanCollectionDataSource(dados);

        // envia para o navegador o PDF gerado
        JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parametros, fonteDados);

        servletOutputStream.flush();
        servletOutputStream.close();

    } catch (JRException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // evita erro do JSF após completar
        // a geração do relatório
        // avisando o FacesContext que a resposta está completa
        context.responseComplete();

    }
    }



Responder

03/12/2010

Davi Costa

Tenta alterar esse teu método de pesquisa para algo do tipo:

   @SuppressWarnings("deprecation")
    private <T> List<T>  todosResultsPesq(Class<T> classToCast) {

   //pega o código do seu DAO etrata para que ele te reorne a de objetos que vc quer

   /algo do tipo  List<T> listoReturn = query.getResultList();
    }


Mas como falei, vamos resolver seu problema primeiro.. tente colocar o break-point e ver primeiro se o método do action Listener é chamado e depois se quebra em alguma linha

Att Davi
Responder

03/12/2010

Cleber Faria*

Então, fiz o debug na chamada do relatório, passou legal, vai para pagina em branco, o erro só vejo no console do eclipse. Vou ver se consigo fazer o que vc me disse talvez mudar o esquema do Object.
Responder

03/12/2010

Davi Costa

Faz só mais um teste descomenta akele trecho de código
que força o download do relatório p ver o q acontece,.. e pq veio todo em branco realmente não tinha registros no banco?

Att Davi
Responder

03/12/2010

Davi Costa

Ah quase esquecia tenta trocar na sua página para vc usar um action normal aí no seu manage bean vc tira os parâmetros ActionEvent do seu método de execução do relatório .
Em relação ao uso de Generics estou fazendo uma série de artigo que a segunda parte vai tratar de generics, artigo qual que estarei entregando até domingo.

https://www.devmedia.com.br/post-18574-Desmistificando-a-Certificacao-SCJP6-Parte-I.html

Att Davi
Responder

03/12/2010

Cleber Faria*

Fiz o teste que me falou, salvei o arquivo ao abri-lo informou uma mensagem "O Adobe Reader não pode abrir este tipo de aquivo pois não fornece suport ou ele foi danificado por exemplo (foi enviado com anexo de email e não foi decodificado corretamente)".
Responder

03/12/2010

Davi Costa

Tenho esses dois métodos que chamam o relatório e tenho certeza que funcionam pois uso aki nas minhas aplicações, adapta teu código para usá-los (um passa o dataSource e o outro usa uma connection):


//executa o relatório através de um JRBeanCollectionDataSource
    public static void executarRelatorio(String caminhoRelatorio, Map<String, Object> parametros, String nomeRel, JRBeanCollectionDataSource fonteDados) throws Exception{
       
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
       
        //pega o caminho do arquivo .jasper da aplicação
        InputStream reportStream = context.getExternalContext().getResourceAsStream(caminhoRelatorio);

        /*//envia a resposta com o MIME Type
        if(tipoFormatoRelatorio.equals(TipoFormatoRelatorio.ACROBAT_PDF)){
            response.setContentType("application/pdf");
        }else if(tipoFormatoRelatorio.equals(TipoFormatoRelatorio.PAGINA_HTML)){
            response.setContentType("application/html");
        }
        */
        response.setHeader("Content-Disposition", "attachment; filename="+ nomeRel +".pdf");
        response.setContentType("application/download");
        response.setHeader("Pragma", "no-cache");
        try {
            ServletOutputStream servletOutputStream = response.getOutputStream();
           
            //envia parametros para o relatório
            if (parametros == null){
                parametros = new HashMap<String, Object>();
            }
       
            //envia para o navegador o PDF gerado
            JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parametros, fonteDados);
            servletOutputStream.flush();
            servletOutputStream.close();
       
        } catch (JRException e) {
            e.printStackTrace();
            throw new Exception("Um erro ocorreu quando o relatório estava sendo executado.");
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("Um erro ocorreu quando o relatório estava sendo executado.");
        }finally{
            context.responseComplete();
        }
    }
   
    //executa o relatorio através de uma Connection
    public static void executarRelatorio(String caminhoRelatorio, Map<String, Object> parametros, TipoFormatoRelatorio tipoFormatoRelatorio, Connection conn) throws Exception{
       
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
       
        //pega o caminho do arquivo .jasper da aplicação
        InputStream reportStream = context.getExternalContext().getResourceAsStream(caminhoRelatorio);

        //envia a resposta com o MIME Type
        if(tipoFormatoRelatorio.equals(TipoFormatoRelatorio.ACROBAT_PDF)){
            response.setContentType("application/pdf");
        }else if(tipoFormatoRelatorio.equals(TipoFormatoRelatorio.PAGINA_HTML)){
            response.setContentType("application/html");
        }
       
        try {
            ServletOutputStream servletOutputStream = response.getOutputStream();
           
            //envia parametros para o relatorio
            if (parametros == null){
                parametros = new HashMap<String, Object>();
            }
       
            //envia para o navegador o PDF gerado
            JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parametros, conn);
            servletOutputStream.flush();
            servletOutputStream.close();
       
        } catch (JRException e) {
            e.printStackTrace();
            throw new ReportException("Um erro ocorreu quando o relatório estava sendo executado.");
        } catch (IOException e) {
            e.printStackTrace();
            throw new ReportException("Um erro ocorreu quando o relatório estava sendo executado.");
        }finally{
            context.responseComplete();
        }
    }

A estratégia que gosto de usar e deixar esses métodos em uma classe separada, por exemplo ReportUtil e como eles são static só faço sua chamadas para essa classe sem instanciá-la na minha Action, por exemplo:
ReporUtil.executarRelatorio(...);

Espero ter ajudado

Att Davi
Responder

03/12/2010

Cleber Faria*

Fiz como vc disse sobre tirar o Parametro do metodo e mudei para action em vez de actionListener

Pelo jeito deu o mesmo erro!!!

03/12/2010 11:12:30 com.sun.faces.application.ActionListenerImpl processAction
SEVERE: java.lang.ClassCastException: br.com.scp.intranet.modelo.AgendaCirurgica cannot be cast to [Ljava.lang.Object;
javax.faces.el.EvaluationException: java.lang.ClassCastException: br.com.scp.intranet.modelo.AgendaCirurgica cannot be cast to [Ljava.lang.Object;
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)

Responder

03/12/2010

Davi Costa

Deixa ActionListener mesmo tem problema não, testa os métodos que postei aki por último e passa o feedBack do que aconteceu, e debuga a formação do teu DataSource só para garantir que os registros estão vindo direitim do teu banco.


Att Davi
Responder

03/12/2010

Cleber Faria*

Vou fazer com seu exemplo
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar