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運算式不會被決議

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/199667.html
標籤:Java
