Mostrando postagens com marcador IReport. Mostrar todas as postagens
Mostrando postagens com marcador IReport. Mostrar todas as postagens

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.