1. 程式人生 > 實用技巧 >jxls最新版本的ExcelUtil匯出工具類

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表示式不會被解析