jxls最新版本的ExcelUtil导出工具类

 

jXLS 的功能是:只使用几行代码就可以建立极端复杂的 Excel 报表。你所需要实现的大部分工作是建立 XLS 模板文件,完成所需要的格式,公式和宏等等,使用注释来指示出数据需要填入的位置。接着写几行代码调用 jXLS 引擎解析 XLS 模板文件并将数据作为参数输入到报表文件中。相对于POI,可以更加方便的设计出表结构比较复杂的excel.

 

1. jxls-core功能相对简单,无法提供自定义函数增强。但是相应的excel的模板设定中,可以不适用批注。本人不推荐使用

推荐使用第二种依赖  :jxls-api依赖 推荐

    <!-- jxls-api依赖  功能较弱,无法提供自定义方法-->
           <!-- <dependency>
                <groupId>net.sf.jxls</groupId>
                <artifactId>jxls-core</artifactId>
                <version>1.0.3</version>
            </dependency>-->
            <!-- jxls-api依赖  推荐-->
               <dependency>
                   <groupId>org.jxls</groupId>
                   <artifactId>jxls-poi</artifactId>
                   <version>${jxls-poi.version}</version>
               </dependency>
               <dependency>
                   <groupId>org.jxls</groupId>
                   <artifactId>jxls</artifactId>
                   <version>${jxls-poi.version}</version>
               </dependency>

 

2.  ExcelUtil的工具类封装  提供了一些方法重载和一个默认的函数增强。

package com.common.base.utils;

import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.jxls.common.Context;
import org.jxls.expression.JexlExpressionEvaluator;
import org.jxls.transform.Transformer;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.transform.poi.WritableCellValue;
import org.jxls.transform.poi.WritableHyperlink;
import org.jxls.util.JxlsHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * jxls2.6以上版本适用
 * Excel 导出工具类
 * @Auther: tony_t_peng
 * @Date: 2020-10-27 13:35
 * @Description: 
 */
public class ExcelUtil {


    public static Logger logger = LoggerFactory.getLogger(ExcelUtil.class);
    /**
     * 导出excel
     * @param  template  模板文件
     * @param  targetFile 目标文件
     * @param  model jxls表达式数据
     * @Author tony_t_peng
     * @Date  2020-10-28 11:54
     */
    public static void exportExcel(File template, File targetFile, Map<String, Object> model) throws IOException {
        exportExcel(template, targetFile, model,buildFuncs());
    }

    /**
     * 导出excel
     * @param  template  模板文件
     * @param  targetFile 目标文件
     * @param  t jxls表达式数据
     * @Author tony_t_peng
     * @Date  2020-10-28 11:54
     */
    public static <T> void exportExcel(File template, File targetFile, T... t) throws IOException, IllegalAccessException {
        exportExcel(template, targetFile, buildFuncs(),t);
    }


    /**
     * 导出excel
     * @param  template  模板文件
     * @param  targetFile 目标文件
     * @param  t jxls表达式数据
     * @param  funcs   自定义函数增强
     * @Author tony_t_peng
     * @Date  2020-10-28 11:54
     */
    public static <T> void exportExcel(File template, File targetFile,Map<String, Object> funcs, T... t) throws IOException, IllegalAccessException {
        FileOutputStream fileOutputStream = null;
        try{
            fileOutputStream = new FileOutputStream(targetFile);
            exportExcel(new FileInputStream(template), fileOutputStream, buildContext(t),buildFuncs(funcs));
        }finally {
            if(fileOutputStream!=null){
                fileOutputStream.close();
            }
        }
    }


    /**
     * 导出excel
     * @param  template  模板文件
     * @param  targetFile 目标文件
     * @param  model jxls表达式数据
     * @param  funcs   自定义函数增强
     * @Author tony_t_peng
     * @Date  2020-10-28 11:54
     */
    public static void exportExcel(File template, File targetFile, Map<String, Object> model,Map<String, Object> funcs) throws IOException {
        FileOutputStream fos = null;
        FileInputStream fis=null;
        try{
            fos = new FileOutputStream(targetFile);
            fis = new FileInputStream(template);
            exportExcel(fis, fos, buildContext(model),buildFuncs(funcs));
        }finally {
            if(fos!=null){
                fos.close();
            }
            if(fis!=null){
                fis.close();
            }
        }
    }

    /**
     * 导出excel
     * @param  is  输入流
     * @param  os  输出流
     * @param  model jxls表达式数据
     * @Author tony_t_peng
     * @Date  2020-10-28 11:54
     */
    public static void exportExcel(InputStream is, OutputStream os, Map<String, Object> model) throws IOException {
        exportExcel(is, os, buildContext(model),buildFuncs());
    }

    /**
     * 导出excel
     * @param  is  输入流
     * @param  os  输出流
     * @Author tony_t_peng
     * @Date  2020-10-28 11:54
     */
    public static <T> void exportExcel(InputStream is, OutputStream os, T... t) throws IOException, IllegalAccessException {
        exportExcel(is, os, buildContext(t),buildFuncs());
    }

    /**
     * 导出excel
     * @param  is  输入流
     * @param  os  输出流
     * @param  context jxls表达式数据源
     * @param  funcs 自定义函数增强
     * @Author tony_t_peng
     * @Date  2020-10-28 11:54
     */
    public static void exportExcel(InputStream is, OutputStream os,Context context,Map<String, Object> funcs) throws IOException {
        JxlsHelper jxlsHelper = JxlsHelper.getInstance();
        Transformer transformer  = jxlsHelper.createTransformer(is, os);
        //获得配置
        JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator)transformer.getTransformationConfig().getExpressionEvaluator();
        //函数增强
        if(funcs!=null){
            evaluator.setJexlEngine(new JexlBuilder().namespaces(funcs).create());
        }
        //必须要这个,否者表格函数统计会错乱
        jxlsHelper.setUseFastFormulaProcessor(false).processTemplate(context, transformer);
    }

    /***
     * 组装context
     * @Author tony_t_peng
     * @Date  2020-10-28 16:02
     */
    private static Context buildContext(Map<String, Object> model){
        Context context = PoiTransformer.createInitialContext();
        if (model != null) {
            for (String key : model.keySet()) {
                context.putVar(key, model.get(key));
            }
        }
        return context;
    }

    /***
     * 组装context
     * @Author tony_t_peng
     * @Date  2020-10-28 16:02
     */
    private static <T> Context buildContext(T... t) throws IllegalAccessException {
        Context context = PoiTransformer.createInitialContext();
        if(t!=null){
            for(T t1:t){
                Field[] declaredFields = t1.getClass().getDeclaredFields();
                for (Field field : declaredFields) {
                    field.setAccessible(true);
                    context.putVar(field.getName(), field.get(t1));
                }
            }
        }
        return context;
    }


    /**
     * 默认自定义函数增强
     * @Author tony_t_peng
     * @Date   17:37
     */
    private static  Map<String, Object> buildFuncs(Map<String, Object> funcs){
        if(funcs==null){
             funcs = new HashMap<>();
        }
        funcs.put("excelUtil",new ExcelUtil());
        return funcs;
    }

    /**
     * 默认自定义函数增强
     * @Author tony_t_peng
     * @Date   17:37
     */
    private static  Map<String, Object> buildFuncs(){
        Map<String, Object> funcs = new HashMap<>();
        funcs.put("excelUtil",new ExcelUtil());
        return funcs;
    }


    //超链接
    public WritableCellValue myHyperlink(String address, String title) {
        return new WritableHyperlink(address, title);
    }

    /**
     * 日期转换
     */
    public String dateToString(Date date, String pattern) {
        return DateFormatUtils.format(date, pattern);
    }


}

  

3.excel模板定义:

在最新版本jxls(jxls2.6以上版本适用)的模板定义中,需要增加批注以确定excle模板数据加载的范围.

注:A1的栏位上需要加上批注,该批注用于确定模板数据加载范围。   批注格式为  jx:area(lastCell="F5")

       如果需要循环加载数据也可以使用批注  jx:each(items="data" var="item" lastCell="E3") 

 

 

 

查看源码:JXLS中加载模板的代码中,会去那批注确定的范围。所以A1上面一定要加上批注,否则JXL表达式不会被解析

 

 

posted @ 2020-11-02 11:04  火羽  阅读(748)  评论(0编辑  收藏  举报