EasyExcel导入导出网上资料很多,这里就不多做描述了,总之就是一款比较轻而小,易用的excel操作工具包;这里在项目中使用到,做下笔记。以及表格中下拉框的实现;
声明:本文思路是借鉴于某大神的,然后自己进行二次改版而成的,用注解的方式来进行动态下拉列表的绑定。所以代码略微有点多。 还有另一种方式,则是将数据源传入进来直接进行绑定,这样可以做到真正的与业务分离,可以更加灵活。

EasyExcel导入

EasyExcel.read(file.getInputStream(), ImportSecurityPerson.class,new PeronDataListener(securityPersonService, dto)).sheet(0).doRead();

这里一句话就可以导入成功,参数为文件流,需要导出的表格的表头实体类,第三个是读取时的监听类即可。实体类如下:

@Data
@ToString(callSuper = true)
@ApiModel(value = " 安保人员导入 ", description = " 安保人员导入 ")
public class ImportSecurityPerson {/** 安保公司name **/@ApiModelProperty(value = "安保公司name")@ExcelProperty(value = "公司名称(必填)",index = 0)private String securityCompanyName;/** 安保人员姓名 **/@ApiModelProperty(value = "安保人员姓名")@ExcelProperty(value = "人员姓名(必填)",index = 1)private String securityPersonName;/** 安保人员性别 **/@ApiModelProperty(value = "安保人员性别")@ExcelProperty(value = "性别(必填)",index = 2)private String sexCode;/** 在职状态 **/@ApiModelProperty(value = "在职状态")@ExcelProperty(value = "状态(必填)",index = 3)private String inPostStatusCode;/** 作业区 **/@ApiModelProperty(value = "作业区")@ExcelProperty(value = "作业区(必填)",index = 4)private String workZoneCode;/** 学历 **/@ApiModelProperty(value = "学历")@ExcelProperty(value = "学历",index = 5)private String eduLevelCode;@ApiModelProperty(value = "错误信息")@ExcelIgnoreprivate String msg;@ExcelIgnoreprivate String uuid;}

ExcelProperty 需要导出的表格属性,ExcelIgnore 忽略此属性。index则是顺序,value是标题;监听类中有三个重要的方法:invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context):此方法可以进行头部标题判断,判断是否是需要导入的表格;invoke(ImportSecurityPerson data, AnalysisContext context):每解析一行便会回调此方法,可以在这个方法中做一些处理;doAfterAllAnalysed(AnalysisContext context):解析完成所有数据后执行此方法, 可以进行批量入库,导入成功,错误的信息反馈(如导入成功条数,错误条数)等。

EasyExcel导出

response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("安保人员", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
List<SecurityPersonVo> securityPersonVos = securityPersonService.listSecurityPersons(getUserCharacter(), dto);
EasyExcel.write(response.getOutputStream(), SecurityPersonVo.class).sheet(0).sheetName("人员").doWrite(securityPersonVos);

首先设置response的信息,securityPersonVos 为数据源。导出的参数为第一个:输出流;第二个:导出的实体类,和导入是一样的;导出非常简单,对于样式的话,也可以在write后进行调用registerWriteHandler方法,写自定义样式就可以满足。

EasyExcel下载模板

其实下载模板和导出是一样的,只是在这里加了一些初始化的数据,如下拉内容项。下载模板的实体类有一点点特殊,就是采用了注解方式进行绑定下拉的内容。进入正题:

response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("安保人员导入模板", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
//用作需要传入的入参,如无须参数,则为空
Map<String, String> map = new HashMap<>();
map.put("clientId", user.getCustomerId());
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
WriteSheet writeSheet = EasyExcelUtil.writeSelectedSheet(DownLoadSecurityPerson.class,0, "安保人员", map);//写
excelWriter.write(new ArrayList<String>(), writeSheet);
//手动关闭
excelWriter.finish();

以上是下载模板的代码,具体看下这个工具类:EasyExcelUtil

我们先看下表格实体类:

@Data
@ToString(callSuper = true)
@ApiModel(value = " 治安人员导入 ", description = " 治安人员导入 ")
public class DownLoadSecurityPerson {/** 安保公司name **/@ApiModelProperty(value = "安保公司name")@ExcelProperty(value = "公司名称(必填)",index = 0)private String securityCompanyName;/** 安保人员姓名 **/@ApiModelProperty(value = "安保人员姓名")@ExcelProperty(value = "人员姓名(必填)",index = 1)private String securityPersonName;/** 安保人员性别 **/@ApiModelProperty(value = "安保人员性别")@ExcelSelected(source = {"男","女"})@ExcelProperty(value = "性别(必填)",index = 2)private String sexCode;/** 在职状态 **/@ApiModelProperty(value = "在职状态")@ExcelSelected(source = {"在职","离职"})@ExcelProperty(value = "状态(必填)",index = 3)private String inPostStatusCode;/** 作业区 **/@ApiModelProperty(value = "作业区")@ExcelSelected(sourceClass = ZoneExcelSelectImpl.class)@ExcelProperty(value = "作业区(必填)",index = 4)private String workZoneCode;/** 学历 **/@ApiModelProperty(value = "学历")@ExcelSelected(sourceClass = EduExcelSelectImpl.class)@ExcelProperty(value = "学历",index = 5)private String eduLevelCode;
}

模板标题类属性使用了ExcelSelected注解,用来绑定下拉内容,如何是固定的值,则采用source 来赋予,如果是动态的,则动态获取绑定。

注解类

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelSelected {/*** 固定下拉内容*/String[] source() default {};/*** 动态下拉内容*/Class<? extends ExcelDynamicSelect>[] sourceClass() default {};/*** 设置下拉框的起始行,默认为第二行*/int firstRow() default 1;/*** 设置下拉框的结束行,默认为最后一行*/int lastRow() default 0x10000;
}

注解解析类

@Data
@Slf4j
public class ExcelSelectedResolve {/*** 下拉内容*/private String[] source;/*** 设置下拉框的起始行,默认为第二行*/private int firstRow;/*** 设置下拉框的结束行,默认为最后一行*/private int lastRow;public String[] resolveSelectedSource(ExcelSelected excelSelected, Map<String,String> map) {if (excelSelected == null) {return null;}// 获取固定下拉框的内容String[] source = excelSelected.source();if (source.length > 0) {return source;}// 获取动态下拉框的内容Class<? extends ExcelDynamicSelect>[] classes = excelSelected.sourceClass();if (classes.length > 0) {try {ExcelDynamicSelect excelDynamicSelect = classes[0].newInstance();String[] dynamicSelectSource = excelDynamicSelect.getSource(map);if (dynamicSelectSource != null && dynamicSelectSource.length > 0) {return dynamicSelectSource;}} catch (InstantiationException | IllegalAccessException e) {log.error("解析动态下拉框数据异常", e);}}return null;}
}

动态数据源接口

public interface ExcelDynamicSelect {/*** 获取动态生成的下拉框可选数据* @return 动态生成的下拉框可选数据*/String[] getSource(Map<String,String> map);
}

动态数据源实现类

public class EduExcelSelectImpl implements ExcelDynamicSelect{@Overridepublic String[] getSource(Map<String,String> map) {SecurityPersonService bean = SpringContextUtil.getBean(SecurityPersonService.class);Map<String, String> stringStringMap = bean.mapDict();Collection<String> values = stringStringMap.values();return values.toArray(new String[values.size()]);}
}public class ZoneExcelSelectImpl implements ExcelDynamicSelect{@Overridepublic String[] getSource(Map<String,String> map) {SecurityPersonService bean = SpringContextUtil.getBean(SecurityPersonService.class);Map<String, String> stringStringMap = bean.mapCustomerDict(map.get("clientId"));Collection<String> values = stringStringMap.values();return values.toArray(new String[values.size()]);}
}

接下来是工具类

public class EasyExcelUtil {/*** 创建即将导出的sheet页(sheet页中含有带下拉框的列)* @param head 导出的表头信息和配置* @param sheetNo sheet索引* @param sheetName sheet名称* @param map 入参* @return sheet页*/public static <T> WriteSheet writeSelectedSheet(Class<T> head, Integer sheetNo, String sheetName,Map<String,String> map) {Map<Integer, ExcelSelectedResolve> selectedMap = this.resolveSelectedAnnotation(head,map);return EasyExcel.writerSheet(sheetNo, sheetName).head(head).registerWriteHandler(new CommentWriteHandler()) //创建批注.registerWriteHandler(new CustomColumnWidthStyle()) //自适应宽度.registerWriteHandler(new CustomSheetWriteHandler(selectedMap)) //绑定下拉数据源.build();}/*** 解析表头类中的下拉注解* @param head 表头类* @param <T> 泛型* @return Map<下拉框列索引, 下拉框内容> map*/private static <T> Map<Integer, ExcelSelectedResolve> resolveSelectedAnnotation(Class<T> head,Map<String,String> map) {//用来存储对应的列与值对象Map<Integer, ExcelSelectedResolve> selectedMap = new HashMap<>();// getDeclaredFields(): 返回全部声明的属性;getFields(): 返回public类型的属性Field[] fields = head.getDeclaredFields();for (int i = 0; i < fields.length; i++){Field field = fields[i];// 解析注解信息ExcelSelected selected = field.getAnnotation(ExcelSelected.class);ExcelProperty property = field.getAnnotation(ExcelProperty.class);if (selected != null) {ExcelSelectedResolve excelSelectedResolve = new ExcelSelectedResolve();String[] source = excelSelectedResolve.resolveSelectedSource(selected,map);if (source != null && source.length > 0){excelSelectedResolve.setSource(source);excelSelectedResolve.setFirstRow(selected.firstRow());excelSelectedResolve.setLastRow(selected.lastRow());if (property != null && property.index() >= 0){selectedMap.put(property.index(), excelSelectedResolve);} else {selectedMap.put(i, excelSelectedResolve);}}}}return selectedMap;}
}

最重要的在绑定类CustomSheetWriteHandler

@Data
@AllArgsConstructor
public class CustomSheetWriteHandler implements SheetWriteHandler {private final Map<Integer, ExcelSelectedResolve> selectedMap;@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {}@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {// 区间设置 第一列第一行和第二行的数据。由于第一行是头,所以第一、二行的数据实际上是第二三行// 这里可以对cell进行任何操作Sheet sheet = writeSheetHolder.getSheet();DataValidationHelper helper = sheet.getDataValidationHelper();selectedMap.forEach((k, v) -> {// 设置下拉列表的行: 首行,末行,首列,末列CellRangeAddressList rangeList = new CellRangeAddressList(v.getFirstRow(), v.getLastRow(), k, k);// 设置下拉列表的值DataValidationConstraint constraint = helper.createExplicitListConstraint(v.getSource());// 设置约束DataValidation validation = helper.createValidation(constraint, rangeList);// 阻止输入非下拉选项的值validation.setErrorStyle(DataValidation.ErrorStyle.STOP);validation.setShowErrorBox(true);validation.setSuppressDropDownArrow(true);validation.createErrorBox("提示", "请选择下拉选项中的内容");sheet.addValidationData(validation);});}
}

至此,就完成了下载模板带有下拉选项的表格。
完整代码GitHub: https://github.com/qinyunsurd/EasyExcel

EasyExcel导入导出下载模板(带下拉)相关推荐

  1. Excel表格下载模板(带下拉框选项)

    下载excel模板需要带下拉框选项,现在纯JAVA代码来实现 1.模板标题实体类 import cn.afterturn.easypoi.excel.annotation.Excel; import ...

  2. poi下载模板含下拉框

    poi下载模板含下拉框 第一种方法 新建QuestionsImport类import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.u ...

  3. ant Desgin vue 导入 导出 下载模板

    先说导入吧, 首先 我们先发请求 代码如下: 按照自己的接口发请求,因为我这个用的是封装的, 因为我这个请求是总导入,好多个用一个,所以我们定义importType类型,来区分 //导入档案总 exp ...

  4. EasyExcel在项目中的应用-在web中导出带下拉框和批注的excel文件

    前言 ​ 好长一段时间没有更新博客了,最近刚刚找到实习工作,接触了企业中的项目,在这段时间的实习过程中,终于知道了企业级项目的体量和业务难度跟之前的小项目是完全不同的.10多天的适应期也逐渐让我找到了 ...

  5. Java EXCEL 表格导入导出(带下拉选-带VLOOKUP函数封装)

    Java EXCEL 表格导入导出(带下拉选-带VLOOKUP函数封装) 对于excel Java POI 使用 目前简单导出导入功能网上很多,但是对于有下拉选,样式等缺点却是最大硬伤,故此封装一个通 ...

  6. ExcelJS 导入导出excel带下拉框筛选数据

    import ExcelJS from "exceljs"; 配上文档地址 下载方法 //数据格式 deviceJson:{         't(数据类型)':[{value:0 ...

  7. 【使用EasyExcel导入导出】

    使用EasyExcel导入导出 一,为什么要使用EasyExcel 1.1 EasyExcel与Poi的区别 Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个 ...

  8. 个人HTML期末大作业~ 个人网页(HTML+CSS)6页面带下拉特效~简单带表格带设计说明 ~学生网页设计作业源码

    HTML期末大作业~ 个人网页6页面带下拉特效~简单带表格带设计说明 ~学生网页设计作业源码 作品介绍 下面介绍一下我的个人小网站吧,我的网站背景稍微单调一点白色,主要个人比较喜欢白色了,布局上面使用 ...

  9. 阿里EasyExcel导入导出

    阿里EasyExcel导入导出 前言 使用阿里提供的EasyExcel进行excel的导入导出简单,方便,快捷 ` 一.使用版本 <dependency><groupId>co ...

最新文章

  1. hadoop之MapReduce框架TaskTracker端心跳机制分析(源码分析第六篇)
  2. 如何 提高企业网站大数据量 效率
  3. springmvc导出excel并弹出下载框
  4. [NewLife.XCode]分表分库(百亿级大数据存储)
  5. 2014_anshan_onsite
  6. 代码合并工具_分享几款比较常用的代码比较工具
  7. numpy+pandas+matplotlib绘制对数函数图形
  8. centos7启用EPEL Repository
  9. 编译win10的WSL2内核(windows subsystem linux)
  10. 2011-8-13 随笔一二
  11. 网盘助手插件chrome插件
  12. java 项目启动后页面乱码_java生成的Html打开后展示乱码
  13. 如何实现一个拍照搜题功能
  14. origin柱状图同时有两组数和两组数差值_「技能」如何用Origin进行实验数据处理...
  15. FTP在资源管理器里打不开
  16. Golang interface 接口详解
  17. Cubieboard安装系统
  18. P2394 yyy loves Chemistry I
  19. GPU跑TensorFlow的各种显卡下的电脑配置(1080ti)
  20. 苹果采集插件全套教程-苹果cmsV10采集插件

热门文章

  1. MT6158原理图,MT6158处理器参数,MT6158射频芯片资料
  2. HDU 4997 Biconnected (状态压缩DP)
  3. 解决Weboffice控件的遮挡问题
  4. macos 虚拟环绕声_虚拟和“真实”环绕声游戏耳机有什么区别?
  5. 快乐英语新概念英语 绿色
  6. P3722 [AH2017/HNOI2017]影魔(树状数组)
  7. RocketMQ——Mac电脑OS系统docker安装Dashboard
  8. 关于图片无缝拼接的学习(PTGui)
  9. 我为什么反对寄希望于内部培训提升员工技能的方法?
  10. python分别计算100以内(含100)奇数和偶数的和