Boa tarde pessoal.
Estou com um problema em um relatório gerado pelo Jasper Report.
Criei uma tela com parâmetros do relatório que ao pressionar o botão chama o método abaixo.
` public void imprimir() {
try {
RpFolhaDePagamentoDAO dao = new RpFolhaDePagamentoDAO();
List resultado = dao.gerarSQL(folhaDePagamento, dataInicial, dataFinal, eventosSelecionados, funcionariosSelecionados);
JRBeanCollectionDataSource colecao = new JRBeanCollectionDataSource(resultado);
String caminho = Faces.getRealPath("/reports/folhaDePagamento.jasper");
Map<String, Object> parametros = new HashMap<>();
parametros.put("dataInicial", dataInicial);
parametros.put("dataFinal", dataFinal);
JasperPrint relatorio = JasperFillManager.fillReport(caminho, parametros, colecao);
byte[] buffer = JasperExportManager.exportReportToPdf(relatorio);
Faces.sendFile(buffer, "folhaDePagamento.pdf", false);
} catch (JRException | IOException erro) {
String mensagemCapturada = TratadorDeErros.capturarMensagem(erro);
Messages.addGlobalWarn("Erro ao emitir relatorio da Folha de Pagamento " + mensagemCapturada);
erro.printStackTrace();
}
}`
Ao final não da erro de execução, o SQL me retorna informações, mas não é aberto a aba com o relatório em PDF.
Tenho vários outros relatórios que seguem o mesmo padrão e neste tive problema.
Detalhe. Este relatório foi criado em uma nova versão do Eclipse e do JasperSoftStudio 6.6.0
Darlan, ele não da erro nenhum. Debuguei o método e ele não cai no catch.
Simplesmente ele gera o SQL, gera o JasperPrint e o buffer. Mas não cria a aba com o relatório. Eu ja confirmei que retorna dados no SQL.
E você tem tratamento de erro para o trecho de código onde consta a geração do relatóri?
Da Minha tela ao clicar no botão ele cai no método abaixo, que tem o tratamento.
try {
RpFolhaDePagamentoDAO dao = new RpFolhaDePagamentoDAO();
List resultado = dao.gerarSQL(folhaDePagamento, dataInicial, dataFinal, eventosSelecionados, funcionariosSelecionados);
JRBeanCollectionDataSource colecao = new JRBeanCollectionDataSource(resultado);
String caminho = Faces.getRealPath("/reports/folhaDePagamento.jasper");
Map<String, Object> parametros = new HashMap<>();
parametros.put("dataInicial", dataInicial);
parametros.put("dataFinal", dataFinal);
JasperPrint relatorio = JasperFillManager.fillReport(caminho, parametros, colecao);
byte[] buffer = JasperExportManager.exportReportToPdf(relatorio);
Faces.sendFile(buffer, "folhaDePagamento.pdf", false);
} catch (JRException | IOException erro) {
String mensagemCapturada = TratadorDeErros.capturarMensagem(erro);
Messages.addGlobalWarn("Erro ao emitir relatorio da Folha de Pagamento " + mensagemCapturada);
erro.printStackTrace();
}
}
E deste método é chamado o DAO para criar o SQL e gerar o DTO.
public class RpFolhaDePagamentoDAO {
public List<RpFolhaDePagamentoDTO> gerarSQL(FolhaDePagamento folhaDePagamento, Date dataInicial,
Date dataFinal, List<EventoDaFolhaDePagamento> eventos, List<Pessoa> funcionarios) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT\n");
sql.append(" fp.mesEanoDeReferencia MESEANO,\n");
sql.append(" fp.dataDoPagamento DATADEPAGAMENTO,\n");
sql.append(" pes.nome FUNCIONARIO,\n");
sql.append(" lfp.totalDosItens TOTALDOSITEMS,\n");
sql.append(" ev.descricao DESCRICAODOITEM,\n");
sql.append(" ifp.quantidade QUANTIDADE,\n");
sql.append(" ifp.valorUnitario VALORUNITARIO,\n");
sql.append(" case ev.tipoDeEvento when 'D' THEN\n");
sql.append(" ((ifp.quantidade * ifp.valorUnitario) * -1)\n");
sql.append(" else\n");
sql.append(" (ifp.quantidade * ifp.valorUnitario)\n");
sql.append(" END as TOTALDOITEM\n");
sql.append("FROM\n");
sql.append(" FolhaDePagamento fp INNER JOIN LancamentoDaFolhaDePagamento lfp on fp.codigo = lfp.folhaDePagamento_codigo\n");
sql.append(" INNER JOIN Funcionario func ON lfp.funcionario_codigo = func.codigo\n");
sql.append(" INNER JOIN Pessoa pes ON func.pessoa_codigo = pes.codigo\n");
sql.append(" INNER JOIN ItemDaFolhaDePagamento ifp ON lfp.codigo = ifp.lancamentoDaFolhaDePagamento_codigo\n");
sql.append(" INNER JOIN EventoDaFolhaDePagamento ev ON ifp.eventoDaFolhaDePagamento_codigo = ev.codigo\n");
sql.append("WHERE 1=1");
if (folhaDePagamento != null){
sql.append("\n AND fp.codigo = " + folhaDePagamento.getCodigo());
}else{
SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd");
if (dataInicial != null) {
sql.append("\n AND dataDoPagamento >= '" + formato.format(dataInicial) + "'");
}
if (dataFinal != null) {
sql.append("\n AND dataDoPagamento <= '" + formato.format(dataFinal) + "'");
}
if (funcionarios.size() > 0) {
sql.append("\n AND lfp.funcionario_codigo in " + criarListaDeFuncionarios(funcionarios));
}
}
if (eventos.size() > 0) {
sql.append("\n AND ifp.eventoDaFolhaDePagamento_codigo in " + criarListaDeEventos(eventos));
}
sql.append("\nORDER BY fp.dataDoPagamento asc, pes.nome asc");
Connection conexao = null;
PreparedStatement comando = null;
ResultSet resultado = null;
try {
conexao = HibernateUtil.getConexao();
comando = conexao.prepareStatement(sql.toString());
resultado = comando.executeQuery();
List<RpFolhaDePagamentoDTO> lista = new ArrayList<>();
while (resultado.next()) {
RpFolhaDePagamentoDTO dto = new RpFolhaDePagamentoDTO();
dto.setDATADEPAGAMENTO(resultado.getDate("DATADEPAGAMENTO"));
dto.setDESCRICAODOITEM(resultado.getString("DESCRICAODOITEM"));
dto.setFUNCIONARIO(resultado.getString("FUNCIONARIO"));
dto.setMESEANO(resultado.getString("MESEANO"));
dto.setQUANTIDADE(resultado.getDouble("QUANTIDADE"));
dto.setVALORUNITARIO(resultado.getBigDecimal("VALORUNITARIO"));
dto.setTOTALDOITEM(resultado.getBigDecimal("TOTALDOITEM"));
lista.add(dto);
}
resultado.close();
comando.close();
conexao.close();
return lista;
}catch(SQLException erro){
throw new RuntimeException(erro);
}
}
Acabei achando um jeito de resolver o problema. Quando chamo o relatório, eu precisava desabilitar o Ajax no botão. Segue abaixo um exemplo.
<p:commandButton title="Print"
actionListener="#{rpFolhaDePagamentoBean.imprimir}" ajax="false"
onclick="this.form.target='_blank'" icon="fa fa-print" />