Relatorios PDF com JasperReports

JasperReports: gere relatórios PDF na sua aplicação Web

Não sei você, mas eu sempre tive uma grande dificuldade com a API do JasperReports para gerar relatórios em PDF. Novo projeto significa reaprender a API. E acreditem, não tem como decorar um código que você praticamente escreve uma única vez e nunca mais olha.

Eu não gosto de simplesmente colar um código de um projeto em outro sem antes entender o que aquele código faz e como funciona. Por exemplo, para gerar relatórios nas minhas aplicações é comum ter um código semelhante a este:

// parametros
String jrxml = "/relatorios/todos-cursos.jrxml";
Map<String, Object> parametros = new HashMap<>();
Connection conexao = new ConnectionFactory().getConnection();

// gera relatorio pdf
GeradorDeRelatorios gerador = new GeradorDeRelatorios(conexao);
File pdf = gerador.geraPdf(jrxml, parametros);

// escreve na saida do response
Files.copy(pdf.toPath(), output);

O código é bem simples, não é? Isso porque toda a complexidade da API do JasperReports está encapsulada dentro da classe GeradorDeRelatorios. Todos os detalhes estão dentro dela e do seu método geraPdf. Dentro deste método existem 3 passos importantes para gerar relatórios em PDF, os relatórios que você desenhou com o iReport.

Para entender os 3 passos e o que realmente importa na API do JasperReports eu recomendo você ler meu novo post no blog da TriadWorks:

>> Como gerar relatórios PDF na Web com JasperReports

A verdade é que eu escrevi esse post para NUNCA mais esquecer como a API funciona e como posso tirar proveito dela. Ainda no post, eu aproveito para ensinar como disponibilizar seu PDF para download na sua aplicação Web.

E ai, como você implementou sua classe para gerar relatórios?

File Download sem framework web MVC

O que aprendi em quase 10 anos de experiência com desenvolvimento de software foi que conceitos são mais importantes do que ferramentas e tecnologias. Conceitos perduram por muitos anos, ferramentas não.

O que estou querendo dizer é que entender bem MVC é mais importante e útil do que saber como usar o último framework MVC da moda; saber OO é mais importante do que saber a sintaxe de uma linguagem de programação. Independentemente da linguagem ou plataforma.

Quando trabalhamos com aplicações Web é comum ter a ajuda do framework MVC para disponibilizar um arquivo para o cliente (navegador). No caso do VRaptor, normalmente basta um código como este abaixo:

public File foto(Perfil perfil) {
    return new File("/caminho/foto-" + perfil.getId() + ".jpg");
}

O código é simples e resolve bem o problema, pois este é o objetivo de uma framework, certo? Mas o que acontece por debaixo dos panos? O que é enviado para o navegador? A imagem acima será exibida diretamente no browser ou o usuário poderá baixá-la? Qual o nome do arquivo será exibido para o usuário ao fazer download?

Muitas perguntas, muitas vezes desnecessárias… desnecessárias até o 1o problema surgir e você ter que identificar se o problema está no framework, servidor ou proxy da sua rede. Enfim, para ajudá-lo a entender parte do processo de download de arquivos numa aplicação Web nós blogamos exatamente sobre o assunto:

>> Como disponibilizar arquivos para download em Java

No post você vai aprender como fazer o download de um arquivo diretamente de uma Servlet, pois é exatamente isso que um framework MVC faz. Você vai aprender alguns cabeçalhos HTTP importantes e claro, como forçar aquela janelinha “Salvar como…”.

E aí, já desceu alguma vez do salto para programar mais baixo nível sem ajuda do seu framework favorito?

 

O perigo do relacionamento bidirecional com JPA e Hibernate

Eu já bati muito a cabeça com JPA e Hibernate para aprender que relacionamento bidirecional no geral atrapalha mais do que ajuda. A verdade é que deveríamos evitar relacionamento bidirecional (o tal do mappedBy) sempre que possível. Ele só deveria ser utilizado em último caso, quando realmente não tiver para onde correr…

Por exemplo, será que o código abaixo funcionaria em um relacionamento bidirecional?

Item curso = new Item("Curso de Java e Orientação a Objetos", 1);

Carrinho carrinho = dao.buscaPor(id);

carrinho.getItens().add(curso);

dao.atualiza(carrinho);

E se eu te dissesse que NÃO? Esse código não funcionaria!

Quando trabalhamos com bidirecional somos obrigados a escrever um código mais complicado para manter a consistência entre as entidades, o que nem sempre é fácil. Para entender do que estou falando dá uma lida no novo post do blog da TriadWorks:

>> JPA: por que você deveria evitar relacionamento bidirecional

Se você ainda insistir em usá-lo nos post acima eu te dou algumas dicas de orientação a objetos (ENCAPSULAMENTO, tan dãn!!) para manter a consistência do relacionamento. Dessa forma você diminui as chances de ter dor de cabeça.

E aí, o que achou do post?