Parte 1Parte 2Parte 3Parte 4Parte 5

Olá a todos! Nesta quinta e última parte do nosso tutorial, iremos aprender a como usar os nossos relatórios em um projeto Web. Esse parte do tutorial vai ser rápida, pois já temos praticamente tudo o que precisamos. Primeiro gostaria de pedir para quem não está acompanhando o tutorial, que baixe o projeto finalizado na Parte 4 clicando aqui. Iremos criar um novo projeto no NetBeans, só que agora do tipo Web e vamos configurá-lo com base no que já fizemos no nosso projeto original. Vamos lá então!

No NetBeans, vá em File -> New Project. No assistente de criação de projetos, escolha “Java Web” na lista de categorias e na lista de tipos de projetos, escolha “Web Application”. Clique em “Next”. Em “Project Name” dê o nome do projeto. Eu sugiro “TutorialRelatoriosWeb” (sem as aspas). Em “Project Location” escolha onde o projeto vai ser salvo. Eu vou deixar na mesma pasta do projeto original. Marque a opção “Use Dedicated Folder for Storing Libraries” e deixe o valor padrão (.\lib). Se quiser, marque a opção “Set as Main Project”. Clique em “Next”.

No próximo passo, onde é configurado o servidor que a aplicação vai ser executada, eu vou deixar o Tomcat escolhido. Se vocês preferirem usar outro servidor, não tem problema, basta selecioná-lo na lista. Deixe desmarcada a opção “Use dedicated library folder for server JAR files”. Em “JavaEE version”, deixe escolhida a versão padrão, pois não precisamos nos preocupar com isso no nosso projeto de testes. No meu caso, ficou selecionado Java EE 5. Em “Context Path” deixe o valor sugerido. No meu caso, é “/TutorialRelatoriosWeb”. Como não vamos usar nenhum framework MVC, você já pode clicar em “Next”. Feito isso, o projeto será criado e será aberto no NetBeans.

Com o projeto criado, acesse suas propriedades clicando com botão direito na raiz do projeto e escolhendo a opção “Properties”, que é a última da lista. Em “Categories” procure pelo item “Run” e selecione-o. Desmarque a opção “Deploy on Save” para evitar que seja feito um deploy a cada vez que salvarmos algo do nosso projeto. Já que estamos aqui, vamos aproveitar para configurar as bibiliotecas. Não vou colocar as figuras desse processo, pois já foi explicado nas primeiras partes do tutorial.

Selecione o item “Libraries” na lista de categorias e clique no botão “Add Library”. Primeiro vamos importar o driver do MySQL que vamos utilizar. Na janela que foi aberta, clique no botão “Import”. Procure pela biblioteca “MySQL JDBC Driver”, selecione-a e clique no botão “Import Library”. A biblioteca vai ser importada e aparecerá na janela anterior, mas ela ainda não foi inserida no projeto. Antes de a inserirmos, vamos criar a biblioteca do JasperReports. Para isso, clique no botão “Create…”. Em “Library Name” entre com o valor “JasperReports-3.7.5” (sem as aspas) e clique em “OK”. Note que eu vou manter a versão do JasperReports utilizado nas partes anteriores do tutorial, sendo assim sua versão pode variar dependendo de quando você estiver seguindo esse tutorial, visto que novas versões do JasperReports são lançadas frequentemente. Se a versão que você estiver usando for mais nova, vamos dizer, 3.7.6, defina um nome da biblioteca que reflita a versão utilizada, ou seja “JasperReports-3.7.6”.

Feito isso, a janela “Customize Library” será exibida. Clique no botão “Add JAR/Folder”. Como já fizemos isso uma vez nas partes anteriores do tutorial, o projeto original já tem essa biblioteca configurada com os JARs necessários. Então vamos usá-los. Procure pela pasta do projeto original (TutorialRelatorios). Dentro dela, entre na pasta “lib”. Dentro da pasta “lib”, existirá uma pasta chamada “JasperReports-3.7.5”. O número da versão pode variar de acordo com a sua versão. Entre nela, selecione todos os JARs e clique no botão “Add JAR/Folder”. O NetBeans vai perguntar se você quer criar um diretório com o nome da biblioteca dentro da pasta “lib” do projeto atual (TutorialRelatoriosWeb). Diga que sim e os JARs serão listados na janela “Customize Library”. Clique em OK.

Novamente a janela “Add Library” será exibida, agora contendo a também a biblioteca do JasperReports que acabamos de configurar. Selecione tanto a biblioteca do JasperReports quanto a biblioteca do MySQL e clique no botão “Add Library”. Agora as bibliotecas serão adicionadas no projeto.

Ainda na janela de propriedades, procure a categoria “Sources” (primeira) e selecione-a. Vamos criar agora o diretório onde guardaremos os nossos fontes do relatório. Na tabela “Source Package Folders”, clique no botão “Add Folder…”. Serão exibidas os diretórios contidos no projeto. Crie então uma nova pasta, chamada “relatorios” (sem acentos e sem aspas), selecione-a e clique em “Open”. A pasta será referenciada na tabela. Clique duas vezes na célula correspondente à coluna “Label” da pasta, preencha com “Relatórios” (sem as aspas) e tecle <ENTER> para trocar o “Label” da pasta. Esse “Label” vai ser utilizado para mostrar a pasta de relatórios na árvore do projeto.

Estamos quase lá. Por fim, ainda na janela de propriedades, selecione a categoria “Packaging”, dentro da categoria “Build”. Em “Exclude From WAR File”, adicione uma vírgula e o valor “**./*.jrxml” (sem as aspas). Isso fará com que os nossos arquivos fonte de relatórios não sejam empacotados no arquivo WAR. O valor final do campo deve ficar assim: “**/*.java,**/*.form, **/*.jrxml” (sem as aspas). Pronto! Clique em OK na janela de propriedades e aguarde o NetBeans escanear as novas configurações do projeto.

Agora, abra o projeto anterior, vá na pasta de “Relatórios” dele, copie o arquivo “ClientesPorNome.jrxml” e cole na pasta “Relatórios” do novo projeto. Ainda não feche o projeto anterior. No projeto atual, abra o relatório que foi copiado e faça um Preview dele para ver se está tudo ok. Lembre-se que o datasource correto (Sakila – JDBC) tem que estar selecionado lá na barra de ferramentas do NetBeans. Se o relatório for renderizado e os dados aparecerem é porque está tudo ok.

Até agora nenhuma novidade. Criamos e configuramos o novo projeto e copiamos e testamos o arquivo de relatório que já fizemos para o novo projeto. Agora vamos às novidades.

Vamos criar um Servlet que vai ser responsável em pegar os possíveis dados do request que serão usados como parâmetros para os relatórios e invocar o JasperReports para criar o relatório. O funcionamento é parecido com o que fizemos no nosso programa desktop, entretanto agora não iremos mais criar um JFrame para exibir os relatórios, pois estamos usando um navegador não é mesmo? O que o nosso Servlet vai fazer é criar diretamente um arquivo .pdf do relatório e mandar exibir no navegador – caso haja algum plugin para leitura de PDF instalado – ou então o navegador vai sugerir que você faça o download do arquivo gerado.

Em “Source Packages”, crie três pacotes: “tutorialrelatoriosweb.jdbc”, “tutorialrelatoriosweb.servlets” e “tutorialrelatoriosweb.util” (todos sem as aspas). Vá no projeto anterior, no pacote “tutorialrelatorios.jdbc”, copie a classe ConnectionFactory e cole no pacote “tutorialrelatoriosweb.jdbc” do novo projeto. Se quiser, feche o projeto anterior. Agora no novo projeto, vá na pasta “tutorialrelatoriosweb.util” e crie uma classe com o nome de “ReportUtils” (sem as aspas). Ainda não vamos implementar nada nela. Feito isso, clique com o botão direito no pacote “tutorialrelatoriosweb.servlets”, vá em New -> Servlet. Se a opção Servlet não estiver sendo exibida, selecione “Other” e em “Categories” selecione “Web” e em “File Types” escolha “Servlet” e clique em “Next”.

O assistente para criar um novo Servlet será exibido. Em “Class Name” preencha com “ReportServlet” (sem as aspas) e clique em “Next”. Tanto “Servlet Name” quanto “URL Pattern” vão ser deixados da forma que o NetBeans sugeriu, ou seja, “ReportServlet” e “/ReportServlet” respectivamente. Clique em “Finish”.

O NetBeans vai gerar por padrão uma implementação padrão do método processRequest(…). Faça com que o seu fique assim:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

    OutputStream out = null;

    // aqui nós geramos o relatório...

    if ( out != null ) {
        out.close();
    }

}

Note que ainda não implementamos o método processRequest(…). Da mesma forma que fizemos no projeto anterior, vamos agora criar um método utilitário na classe ReportUtils que vai ser responsável em gerar o relatório. Segue a implementação comentada da classe ReportUtils.

tutorialrelatoriosweb.util.ReportUtils.java

package tutorialrelatoriosweb.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRPdfExporter;

/**
 * Classe com métodos utilitários para gerar relatórios.
 *
 * @author David Buzatto
 */
public class ReportUtils {

    /**
     * Gera o relatório em PDF.
     *
     * @param inputStream InputStream que contém o relatório.
     * @param parametros Parâmetros utilizados pelo relatório.
     * @param conexao Conexão utilizada para a execução da query.
     * @param response HttpServletResponse que será usado como base para
     * gerar o relatório.
     * @return O OutputStream do HttpServletResponse passado.
     * @throws JRException Caso ocorra algum problema na geração do relatório.
     * @throws IOException Caso ocorra algum problema na obtenção do
     * OutputStream.
     */
    public static OutputStream createPDFReport(
            InputStream inputStream,
            Map<String, Object> parametros,
            Connection conexao,
            HttpServletResponse response ) throws JRException, IOException {

        // configura o content type do response
        response.setContentType( "application/pdf" );

        // obtém o OutputStream para escrever o relatório
        OutputStream out = response.getOutputStream();

        /*
         * Cria um JasperPrint, que é a versão preenchida do relatório,
         * usando uma conexão.
         */
        JasperPrint jasperPrint = JasperFillManager.fillReport(
                inputStream, parametros, conexao );

        // Exporta em PDF, escrevendo os dados no output stream do response.
        JRExporter exporter = new JRPdfExporter();
        exporter.setParameter( JRExporterParameter.JASPER_PRINT,
                jasperPrint );
        exporter.setParameter( JRExporterParameter.OUTPUT_STREAM,
                out );

        // gera o relatório
        exporter.exportReport();

        // retorna o OutputStream
        return out;

    }

}

Como vocês podem perceber, o método createPDFReport(…) da classe ReportUtils gera um relatório em PDF e o escreve no OutputStream do response do Servlet. Caso vocês queiram outros tipos de exportação, basta mudar o tipo do exportador. Clicando aqui, vocês podem ver a documentação da interface JRExporter e de todas as classes que a implementam. Note que ao mudar o exportador, você também precisa alterar o content type do response para refletir o tipo de arquivo gerado.

Vamos agora atualizar o nosso Servlet. O método processRequest(…) vai ficar assim:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

    OutputStream out = null;

    // obtém o relatório compilado
    InputStream inputStream = getClass().getResourceAsStream( "/ClientesPorNome.jasper" );

    // preenche o mapa de parâmetros
    Map<String, Object> parametros = new HashMap<String, Object>();
    parametros.put( "primeiroNome", "D%" );

    try {

        // gera o relatório e atribui o OutputStream gerado
        out = ReportUtils.createPDFReport( inputStream, parametros,
                ConnectionFactory.getSakilaConnection(), response );

    } catch ( SQLException exc ) {
        exc.printStackTrace();
    } catch ( JRException exc ) {
        exc.printStackTrace();
    } finally {

        // se não aconteceu nenhum problema, fecha o output stream
        if ( out != null ) {
            out.close();
        }

    }

}

Com isso feito, rode a aplicação e aponte o navegador para o endereço “http://localhost:8084/TutorialRelatoriosWeb/ReportServlet&#8221; (sem as aspas). Por padrão o Tomcat usado em desenvolvimento no NetBeans roda na porta 8084. Certifque-se que o seu está rodando nesta porta e se não estiver, use a porta correta. Se você seguiu corretamente o tutorial até aqui, será gerado então um .pdf com todos os clientes que tenham o primeiro nome iniciando com a letra “D” (veja o parâmetro “primeiroNome” passado para o relatório).

Note que agora, para passar parâmetros para o relatório, basta você obter os parâmetros pelo request e então adicionar os parâmetros desejados no mapa de parâmetros do relatório. Se quiser outros tipos de exportação, por exemplo, para Excel, basta criar um novo método na classe ReportUtils, que configura o content type apropriado (“application/ms-excel”) e o exportador necessário (JRXlsExporter ou JRXlsxExporter). Tanto a passagem de parâmetros quanto a geração de outros tipos de arquivos ficam como exercício para vocês. O Servlet ReportServlet pode ser generalizado também, permitindo que o nome do arquivo do relatório a ser gerao seja passado via request :).

Com isso terminamos nosso tutorial sobre relatórios em Java! Espero que tenham gostado! Para baixar o projeto criado nesta parte, clique aqui. Nos próximos tutoriais iremos aprender a usar a biblioteca JavaScript jQuery, que é extremamente útil e facilita muito a nossa vida.

Então é isso pessoal! Grande abraço a todos! Até a próxima 😉

Parte 1Parte 2Parte 3Parte 4Parte 5