Exportação de Arquivos Excel com JXLS e Templates em Java

A biblioteca JXLS permite a geração de planilhas Excel complexas de forma simplificada, utilizando arquivos de modelo (templates) com marcações específicas. Este guia detalha o processo de preenchimento de um template no formato .xls e o salvamento do arquivo resultante em um diretório local para posterior download. O exemplo baseia-se na versão 2.4.7 do JXLS e no formato legado do Excel (97-2003).

Configuração de Dependências

Adicione as seguintes dependências ao seu arquivo pom.xml para integrar o JXLS e seus processadores subjacentes (Apache POI e JExcel):

<dependencies>
    <!-- Núcleo do JXLS -->
    <dependency>
        <groupId>org.jxls</groupId>
        <artifactId>jxls</artifactId>
        <version>2.4.7</version>
    </dependency>
    <!-- Integração com Apache POI -->
    <dependency>
        <groupId>org.jxls</groupId>
        <artifactId>jxls-poi</artifactId>
        <version>1.0.16</version>
    </dependency>
    <!-- Integração com JExcel -->
    <dependency>
        <groupId>org.jxls</groupId>
        <artifactId>jxls-jexcel</artifactId>
        <version>1.0.7</version>
    </dependency>
</dependencies>

Classe Utilitária para Processamento do Template

Crie uma classe responsável por ler o template, injetar os dados do mapa de contexto e escrever o arquivo final. A implementação abaixo utiliza try-with-resources para garantir o fechamento adequado dos streams e configura o avaliador JEXL para suportar funções personalizadas e modo silencioso.

public class ExcelTemplateProcessor {

    /**
     * Processa o template do Excel e salva o resultado no diretório de exportação.
     *
     * @param templatePath   Caminho ou nome do arquivo de template
     * @param outputFileName Nome do arquivo de saída gerado
     * @param dataPayload    Mapa contendo os dados a serem injetados no template
     * @return O nome do arquivo gerado
     * @throws IOException Em caso de falha na leitura ou escrita de arquivos
     */
    public static String generateReport(String templatePath, String outputFileName, Map<String, Object> dataPayload) throws IOException {
        File templateFile = new File("/opt/app/templates/" + templatePath);
        File outputFile = new File(AppConfig.getExportDirectory() + outputFileName);

        try (InputStream templateStream = new FileInputStream(templateFile);
             OutputStream outputStream = new FileOutputStream(outputFile)) {

            Context jxlsContext = PoiTransformer.createInitialContext();
            if (dataPayload != null) {
                dataPayload.forEach(jxlsContext::putVar);
            }

            JxlsHelper helper = JxlsHelper.getInstance();
            Transformer transformer = helper.createTransformer(templateStream, outputStream);

            // Configuração do avaliador de expressões JEXL
            JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) transformer.getTransformationConfig().getExpressionEvaluator();
            evaluator.getJexlEngine().setSilent(true);

            // Registro de funções utilitárias personalizadas
            Map<String, Object> customFunctions = new HashMap<>();
            customFunctions.put("reportUtils", new ExcelTemplateProcessor());
            evaluator.getJexlEngine().setFunctions(customFunctions);

            // Desativa o processamento rápido de fórmulas para evitar erros de cálculo em planilhas complexas
            helper.setUseFastFormulaProcessor(false).processTemplate(jxlsContext, transformer);
        }
        return outputFileName;
    }
}

Integração no Controller

No controlador da sua aplicação, prepare o mapa de dados e invoque o método da classe utilitária. O exemplo abaixo demonstra uma abordagem utilizando Spring Boot:

@RestController
@RequestMapping("/api/reports")
public class ReportController {

    @GetMapping("/export")
    public ResponseEntity<String> triggerExcelExport() {
        Map<String, Object> reportData = new HashMap<>();
        reportData.put("currentYear", 2023);
        reportData.put("currentMonth", 10);

        String templateName = "financial_report.xls";
        String generatedFile = "financial_report_out.xls";

        try {
            String resultFile = ExcelTemplateProcessor.generateReport(templateName, generatedFile, reportData);
            return ResponseEntity.ok(resultFile);
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Falha na exportação do relatório");
        }
    }
}

Diretrizes para Criação do Template

  • Formato do Arquivo: O template deve ser salvo obrigatoriamente no formato Excel 97-2003 (.xls). Se estiver utilizando versões mais recentes do Microsoft Office, use a opção "Salvar Como" para converter o arquivo.
  • Definição de Áreas (Comentários): As diretivas do JXLS são inseridas através de comentários nas células do Excel (Não confunda com notas simples). A diretiva lastCell deve abranger toda a área de dados a ser processada. O comentário contedno a diretiva deve ser ancorado na célula superior esquerda da área de iteração.

Resolução de Problemas Comuns

  • Caracteres Especiais e Sobrescritos: Para unidades de medida como m³, evite depender de métodos de entrada de teclado específicos que possam corromper a codificação. Recomenda-se inserir o caractere Unicode diretamente (³) ou aplicar a formatação de sobrescrito nativa do Excel na célula do template.
  • Notação Científica: A formatação de células com notação exponencial (ex: 10^n) pode causar erros de parseamento no motor do JXLS durante a exportação. Como solução alternativa, formate a célula como texto no template ou converta o valor para uma string formatada no back end antes de passá-lo ao mapa de dados.

Tags: java jxls apache-poi Excel spring-boot

Publicado em 6-1 23:54 por Thomas