拉勾教育jxls新版本的ExcelUtil导出工具类
jXLS 的功能是:只使用几行代码就可以建立极端复杂的 Excel 报表。你所需要实现的大部分工作是建立 XLS 模板文件,完成所需要的格式,公式和宏等等,使用注释来指示出数据需要填入的位置。接着写几行代码调用 jXLS 引擎解析 XLS 模板文件并将数据作为参数输入到报表文件中。相对于POI,可以更加方便的设计出表结构比较复杂的excel.拉勾IT课小编为大家分解
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 co***mon.base.utils;
import org.a***mons.jexl3.JexlBuilder;
import org.a***mons.lang3.time.DateFormatUtils;
import org.jxl***mo***ntext;
import org.jxls.expression.JexlExpressioneva luator;
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 jav***.*;
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);
//获得配置
JexlExpressioneva luator eva luator = (JexlExpressioneva luator)transformer.getTransformationConfig().getExpressioneva luator();
//函数增强
if(funcs!=null){
eva luator.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表达式不会被解析
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 co***mon.base.utils;
import org.a***mons.jexl3.JexlBuilder;
import org.a***mons.lang3.time.DateFormatUtils;
import org.jxl***mo***ntext;
import org.jxls.expression.JexlExpressioneva luator;
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 jav***.*;
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);
//获得配置
JexlExpressioneva luator eva luator = (JexlExpressioneva luator)transformer.getTransformationConfig().getExpressioneva luator();
//函数增强
if(funcs!=null){
eva luator.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表达式不会被解析