domingo, 15 de fevereiro de 2026

Gerando Relatórios PDF no Java EE com iReport 5.6 e DTOs (JavaBeans)

        Olá, nesse artigo vou falar sobre geração de relatórios com IReport a partir de dados que já estão na memória (objetos DTO) em vez de fazer uma consulta SQL direta no Jasper. Para isso, utilizamos o JRBeanCollectionDataSource.

        Vamos ver primeiro as dependencias do POM:

<!-- Core do Jasper -->
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports</artifactId>
        <version>5.6.0</version>
    </dependency>
    <!-- Necessário para ler os campos do DTO -->
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.9.4</version>
    </dependency>
    <!-- Motor de exportação PDF (Jasper 5.6 usa essa versão) -->
    <dependency>
        <groupId>com.lowagie</groupId>
        <artifactId>itext</artifactId>
        <version>2.1.7</version>
    </dependency>

        O IReport gera dois arquivos:

.jrxml: É o seu arquivo de edição (código-fonte XML). É onde você desenha no iReport.

.jasper: É o arquivo compilado. Dica: Sempre coloque o .jasper na pasta de recursos (src/main/resources) do seu projeto Java para que a aplicação o encontre facilmente.

        Configurando o iReport para reconhecer o DTO:

Para que os campos apareçam no designer:

  1. Vá em Tools -> Options -> iReport -> Classpath e adicione a pasta target/classes do seu projeto.
  2. No Report Inspector, clique com o botão direito em Fields -> Add Field.
  3. O nome do campo deve ser idêntico ao atributo da classe Java (ex: se no Java é private String nomeCliente, no iReport o campo deve se chamar nomeCliente).
        Como lidar com Logos e Backgrounds

        No ambiente Java EE, o relatório não sabe "onde ele está" a menos que você diga. Para usar caminhos como images/logo.png direto no .jrxml, faça o seguinte:

        No iReport (Designer) crie um parâmetro chamado IMAGENS_DIR (tipo String). No campo da imagem, use a expressão:

$P{IMAGENS_DIR} + "logo.png"

        No Java você extrai o caminho da pasta de relatórios dinamicamente:

// Obtém o caminho físico da pasta de relatórios dentro do seu WAR
String pathRelatorios = getServletContext().getRealPath("/WEB-INF/imagens/");

Map<String, Object> parametros = new HashMap<>();
// Passa esse caminho base para o Jasper
parametros.put("IMAGENS_DIR", pathRelatorios + File.separator);

        Outra opção é usando o InputStream, passá-la como um InputStream via parâmetro. 
        
        No iReport:
  1. Vá em Parameters -> Add Parameter. Nomeie como LOGO_IMG.
  2. Mude a Parameter Class para java.io.InputStream.
  3. Arraste um elemento de Image para o relatório. No campo Image Expression, digite: $P{LOGO_IMG}.
        No Java carregue a imagem da sua pasta de recursos (src/main/resources/images/logo.png) e envie para o Jasper:

InputStream logo = this.getClass().getResourceAsStream("/images/logo.png");
parametros.put("LOGO_IMG", logo);


        O Código Java de geração do Relatório

        Aqui está o restante do código Java para a geração do relatório:

// Centralizando a lógica de criação do JasperPrint
private JasperPrint prepararRelatorio(List<MeuDTO> listaDados, Map<String, Object> parametros) throws JRException {

    // Carrega o arquivo compilado dos resources
    InputStream relatorioStream = this.getClass().getResourceAsStream("/relatorios/meu_arquivo.jasper");
    
    // Transforma a lista de objetos no DataSource do Jasper
    JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(listaDados);

    // Gere os parametros necessários
    Aqui você pega o caminho relativo da imagem por exemplo
    
    // Une o layout (.jasper) + Parâmetros + Dados (DTOs)
    return JasperFillManager.fillReport(relatorioStream, parametros, ds);
}

// Método para enviar ao navegador
public void emitirRelatorio(HttpServletResponse response, List<MeuDTO> lista, boolean baixar) {

    try {
        JasperPrint jp = prepararRelatorio(lista, new HashMap<>());
        
        // Define o tipo de saída (PDF)
        response.setContentType("application/pdf");
        
        // Define se abre no navegador ou faz download
        String modo = baixar ? "attachment" : "inline";
        response.setHeader("Content-Disposition", modo + "; filename=\"relatorio.pdf\"");
        
        // Escreve o PDF na resposta HTTP
        JasperExportManager.exportReportToPdfStream(jp, response.getOutputStream());
        
        response.getOutputStream().flush();
        response.getOutputStream().close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}



Dica: Se usarem uma versão do Java muito nova (Java 17+), o Jasper 5.6 pode precisar de flags extras no servidor (--add-opens), pois ele é uma ferramenta antiga que acessa classes internas do Java.