jxls最新版本的ExcelUtil匯出工具類
阿新 • • 發佈:2020-11-02
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表示式不會被解析