EasyExcel简介

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

EasyExcel使用

导入依赖

     <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.1</version></dependency>

excel映射实体的父类

import java.util.HashMap;
import java.util.List;public abstract class ExcelModel {/*** 验证参数有效性* @return 返回验证结果* @param args 参数*/public abstract boolean validation(String... args);/*** excel表头注释* @return 返回注释信息*/public abstract HashMap<Integer, String> getAnnotationsMap();/*** excel 下拉选内容* @return 返回下拉选信息*/public abstract HashMap<Integer, String[]> getDropDownMap();/*** 重点行* @return 返回重点行信息*/public abstract List<Integer> getEmphasizeColumns();
}

单元格格式处理类

import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.util.StyleUtil;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.*;import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;@Slf4j
public class EasyExcelTitleHandler implements CellWriteHandler {/**错误信息处理时正则表达式的格式*/private final String EXCEL_ERROR_REG = "^(.*)(\\(错误:)(.*)(\\))$";/**操作列*/private final List<Integer> columnIndex;/**颜色*/private final Short colorIndex;/**批注<列的下标,批注内容>*/private final HashMap<Integer,String> annotationsMap;/**下拉框值*/private final HashMap<Integer,String[]> dropDownMap;public EasyExcelTitleHandler(List<Integer> columnIndex, Short colorIndex, HashMap<Integer, String> annotationsMap, HashMap<Integer, String[]> dropDownMap) {this.columnIndex = columnIndex;this.colorIndex = colorIndex;this.annotationsMap = annotationsMap;this.dropDownMap = dropDownMap;}@Overridepublic void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {if(isHead){// 设置列宽Sheet sheet = writeSheetHolder.getSheet();writeSheetHolder.getSheet().getRow(0).setHeight((short)(1.8*256));Workbook workbook = writeSheetHolder.getSheet().getWorkbook();Drawing<?> drawing = sheet.createDrawingPatriarch();// 设置标题字体样式WriteCellStyle headWriteCellStyle = new WriteCellStyle();WriteFont headWriteFont = new WriteFont();headWriteFont.setFontName("宋体");headWriteFont.setFontHeightInPoints((short)14);headWriteFont.setBold(true);if (CollectionUtils.isNotEmpty(columnIndex) &&colorIndex != null &&columnIndex.contains(cell.getColumnIndex())) {// 设置字体颜色headWriteFont.setColor(colorIndex);}headWriteCellStyle.setWriteFont(headWriteFont);headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());CellStyle cellStyle = StyleUtil.buildHeadCellStyle(workbook, headWriteCellStyle);cell.setCellStyle(cellStyle);if (null != annotationsMap && annotationsMap.containsKey(cell.getColumnIndex())) {// 批注内容String context = annotationsMap.get(cell.getColumnIndex());// 创建绘图对象Comment comment=drawing.createCellComment(new XSSFClientAnchor(0, 0, 0,0, (short) cell.getColumnIndex(), cell.getRowIndex(), (short) cell.getColumnIndex()+2,  (short) cell.getRowIndex()+2));comment.setString(new XSSFRichTextString(context));cell.setCellComment(comment);}if(null != dropDownMap && !dropDownMap.isEmpty() &&dropDownMap.containsKey(cell.getColumnIndex())){String[] data = dropDownMap.get(cell.getColumnIndex());DataValidationHelper dvHelper = sheet.getDataValidationHelper();DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(data);CellRangeAddressList addressList = new CellRangeAddressList(1, 65535, cell.getColumnIndex(), cell.getColumnIndex());DataValidation validation = dvHelper.createValidation(dvConstraint, addressList);validation.createPromptBox("提示", "只能选择下拉框里的值");validation.setSuppressDropDownArrow(true);validation.setShowPromptBox(true);validation.setShowErrorBox(true);validation.setEmptyCellAllowed(false);sheet.addValidationData(validation);dropDownMap.remove(cell.getColumnIndex());}}// cell 匹配到错误信息规则,cell 字体设置为红色Pattern pat = Pattern.compile(EXCEL_ERROR_REG);if(pat.matcher(cell.getStringCellValue()).matches()) {Workbook workbook = writeSheetHolder.getSheet().getWorkbook();CellStyle cellStyle1 = workbook.createCellStyle();Font cellFont = workbook.createFont();assert colorIndex != null;cellFont.setColor(colorIndex);cellStyle1.setFont(cellFont);cell.setCellStyle(cellStyle1);}}
}

导入数据处理类

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.xxx.ExcelModel;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class EasyExcelListener<T extends ExcelModel> extends AnalysisEventListener<T> {/***  用于保存正常的数据*/private List<T> data = Collections.synchronizedList(new ArrayList<>());/***  用于保存异常数据*/private List<T> error = Collections.synchronizedList(new ArrayList<>());private String[] arg;@Overridepublic void invoke(T o, AnalysisContext analysisContext) {if(o.validation(arg)) {data.add(o);}else {error.add(o);System.out.println("error--" + o);}}/***  excel 读取完之后的操作*/@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {//        analysisContext.}public List<T> getData() {return data;}public void setData(List<T> data) {this.data = data;}public List<T> getError() {return error;}public void setError(List<T> error) {this.error = error;}public void setArg(String[] arg) {this.arg = arg;}
}

excelUtil工具类

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.xxx.ExcelModel;
import org.apache.poi.ss.usermodel.IndexedColors;import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;public class EasyExcelUtil<T extends ExcelModel> {/*** 导出excel* @param outputStream 输出流* @param dataList     导出的数据* @param classT        模板类* @param sheetName     sheetName* @param cellWriteHandlers    样式处理类*/public void writeExcelWithModel(OutputStream outputStream, List<T> dataList, Class<? extends ExcelModel> classT, String sheetName, CellWriteHandler... cellWriteHandlers) {// 头的策略WriteCellStyle headWriteCellStyle = new WriteCellStyle();// 单元格策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 初始化表格样式HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);ExcelWriterSheetBuilder excelWriterSheetBuilder = EasyExcel.write(outputStream, classT).sheet(sheetName).registerWriteHandler(horizontalCellStyleStrategy);if (null != cellWriteHandlers && cellWriteHandlers.length > 0) {for (CellWriteHandler cellWriteHandler : cellWriteHandlers) {excelWriterSheetBuilder.registerWriteHandler(cellWriteHandler);}}// 开始导出excelWriterSheetBuilder.doWrite(dataList);}/*** 使用 模型 来读取Excel* @param fileInputStream Excel的输入流* @param clazz 模型的类* @param arg 验证用的参数,可以没有* @return 返回 模型 的列表(为object列表,需强转)*/public EasyExcelListener<T> readExcelWithModel(InputStream fileInputStream, Class<?> clazz, String... arg) {EasyExcelListener<T> listener = new EasyExcelListener<>();listener.setArg(arg);ExcelReader excelReader = EasyExcel.read(fileInputStream, clazz, listener).build();ReadSheet readSheet = EasyExcel.readSheet(0).build();excelReader.read(readSheet);excelReader.finish();return listener;}public void createExcel(OutputStream os, List<T> data, T t, String sheetName) {// 指定标红色的列List<Integer> columns = t.getEmphasizeColumns();// 指定批注HashMap<Integer, String> annotationsMap = t.getAnnotationsMap();// 指定下拉选HashMap<Integer, String[]> dropDownMap = t.getDropDownMap();EasyExcelTitleHandler easyExcelTitleHandler = new EasyExcelTitleHandler(columns, IndexedColors.RED.index, annotationsMap, dropDownMap);writeExcelWithModel(os, data, t.getClass(), sheetName, easyExcelTitleHandler);}}

使用示例

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.xxx.ExcelModel;
import com.xxx.EasyExcelListener;
import com.xxx.EasyExcelUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;public class ExcelWriteTest {String[] clazzList = {"一年级1班", "一年级2班", "一年级3班"};/*** 测试excel导出*/@Testpublic void excelExport() throws IOException {// 输出流OutputStream outputStream = new FileOutputStream("D:\\test.xlsx");// 准备要导出的数据List<TestModel> data = new ArrayList<>();//获取excelUtil实例EasyExcelUtil<TestModel> excelUtil = new EasyExcelUtil<>();//设置导出时下拉选的内容TestModel testModel = new TestModel();//动态指定下拉选内容testModel.setClazzList(clazzList);//导出exceltry {excelUtil.createExcel(outputStream, data, testModel, "用户导入模板");}catch (Exception e) {//导出失败的处理e.printStackTrace();}}/*** 测试excel导入*/@Testpublic void excelImport() throws FileNotFoundException {InputStream inputStream;inputStream = new FileInputStream("D:\\test.xlsx");EasyExcelUtil<TestModel> easyExcelUtil = new EasyExcelUtil<>();//导入excel,clazzList为动态指定的校验列表EasyExcelListener<TestModel> listener =easyExcelUtil.readExcelWithModel(inputStream, TestModel.class, clazzList);System.out.println("格式正确的数据-data:----");listener.getData().forEach(System.out::println);System.out.println("格式异常的数据-error:----");listener.getError().forEach(System.out::println);}@EqualsAndHashCode(callSuper = true)@Datapublic static class TestModel extends ExcelModel {/*** 动态指定下拉选的内容,或校验时的内容*/@ExcelIgnoreString[] clazzList;/*** excel导出不需要的属性*/@ExcelIgnoreprivate String id;@ExcelProperty(value = {"班级", "班级"}, index = 0)private String clazz;/*** value对应excel表头,index对应excel列数,第一列为 0*/@ExcelProperty(value = {"姓名", "姓名"}, index = 1)private String name;@ExcelProperty(value = {"年龄", "年龄"}, index = 2)private String age;/*** 合并单元格的表头*/@ExcelProperty(value = {"成绩", "数学"}, index = 3)//excel映射实体使用string字段,避免excel数据类型和java数据类型转换问题private String scoreMath;@ExcelProperty(value = {"成绩", "英语"}, index = 4)private String scoreEnglish;@Overridepublic boolean validation(String... args) {//args为校验数据需要的变量,从listener中传入,如无需要可没有boolean result = true;//校验导入的数据if(StringUtils.isBlank(this.getClazz()) || !Arrays.asList(args).contains(this.getClazz())) {result = false;//错误信息的格式需要对应 错误信息处理时正则表达式的格式this.setClazz(this.getClazz() + "(错误:请使用下拉选的值或使用最新模板)");}return result;}@Overridepublic HashMap<Integer, String> getAnnotationsMap() {// 指定批注HashMap<Integer, String> annotationsMap = new HashMap<>();annotationsMap.put(0, "必填,只能使用下拉选中的值");return annotationsMap;}@Overridepublic HashMap<Integer, String[]> getDropDownMap() {HashMap<Integer, String[]> dropDownMap = new HashMap<>();// 指定下拉框String[] classList = this.clazzList;dropDownMap.put(0,classList);return dropDownMap;}@Overridepublic List<Integer> getEmphasizeColumns() {//标记比填列 —— excel并未做限制return Arrays.asList(0, 1, 3, 4);}}
}

动态设置表头和单元格移步下一篇文章:easyExcel实现动态表头设置以及单元格样式设置

springboot集成easyExcel实现文件导入导出相关推荐

  1. SpringBoot集成EasyPoi实现Excel导入导出

    作者介绍: 本人Java特工,代号:Cris Li : 中文名:克瑞斯理 简书地址: 消失的码农 - 简书 CSDN地址: https://blog.csdn.net/jianli95 个人纯洁版博客 ...

  2. Springboot 下 EasyExcel 的数据导入导出

    文章目录 1.环境准备 1.0. excel数据 1.1. pom 1.2. excle映射实体 1.3. 自定义日期转换器 1.4.自定义异常 2. 数据导出 3. 数据导入 3.1. excel解 ...

  3. SpringBoot 系列教程(十三):SpringBoot集成EasyPoi实现Excel导入导出

    "无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家.教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家.点人工智能教程可以跳转到教程. easyp ...

  4. SpringBoot整合Mybatis实现文件导入导出

  5. SpringBoot中使用Easyexcel实现Excel导入导出功能(三)

    导出的数据包含有图片 导出excel表格的数据包含有图片,这种场景比较少.通Easyexcel实现这样的需求,我认为最简便的方法就是使用前面提到的自定义转换器(com.alibaba.excel.co ...

  6. SpringBoot中使用Easyexcel实现Excel导入导出功能(一)

    目录 前言 1.常规导入 2.读取到指定的列 3.读取全部的sheet页 4.日期.数字及其他自定义格式的转换 5.表头有多行的表格读取 6.表头数据的读取 7.单元格内的备注内容读取 前言 exce ...

  7. EasyExcel实现Excel文件导入导出

    1 EasyExcel简介 EasyExcel是一个基于Java的简单.省内存的读写Excel的开源项目.在尽可能节约内存的情况下支持读写百M的Excel. github地址: https://git ...

  8. EasyPoi实现excel文件导入导出

    EasyPoi学习实践 1 简介 easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板 ...

  9. php laravel导入excel,Laravel 5使用Laravel Excel实现Excel/CSV文件导入导出的功能详解

    @H_404_0@ 1.简介 @H_404_0@本文主要给大家介绍了关于Laravel 5用Laravel Excel实现Excel/CSV文件导入导出的相关内容,下面话不多说了,来一起看看详细的介绍 ...

最新文章

  1. 2022-2028年全球与中国氢碘化物市场智研瞻分析报告
  2. 百练OJ:2808:校门外的树
  3. GHOST系统时出现“A:\GHOSTERR.TXT”的解决方法
  4. 亿佰特物联网dtu无线数传电台:新一代Lora无线模块通信技术
  5. 2021-08-12 画蜡烛线
  6. python excel数据可视化软件_excel是基础的数据分析与可视化工具
  7. sql2008安装时提示参数不能为空_PHP命令行脚本接收传入参数的三种方式
  8. Oracle大型数据库系统在AIX/UNIX上的实战详解
  9. Cannot delete or update a parent row: a foreign key constraint fails
  10. viper4android脉冲样本,v4a脉冲反馈样本官方版
  11. [EXP]CVE-2019-0604 Microsoft SharePoint RCE Exploit
  12. 网络编程:Socket编程从IPv4转向IPv6支持
  13. mysql mysql.sock连接_【MySQL】mysql.sock文件作用
  14. 风之大陆ios android账号互通,《风之大陆》安卓和ios互通吗
  15. 如何利用语音评测技术设计英语口语选择题
  16. Java毕业设计-公交路线查询管理系统
  17. IP地址和域名之间的转换
  18. Go语言环境配置 Sublime Text + GoSublime+ gocode + MarGo组合
  19. 字节跳动蚂蚁金服百度SRE社招面经
  20. 自动控制原理(根轨迹)

热门文章

  1. 雷达图的4种绘制方法
  2. scal 解析json字符串
  3. spring集成druid示例
  4. Ubuntu20.04安装vivado2018.2过程中卡在generating installed device list的解决办法
  5. Java拆解最多的素数之和_java - 计算并打印第n个素数 - 堆栈内存溢出
  6. Java编程基础小总结
  7. 如何查看mysql警告信息_查看MySQL的警告信息
  8. 2022年安全员-C证操作证考试题库及模拟考试
  9. widow10系统查找局域网网络计算机,Win10系统下让局域网内其他电脑通过IP访问自己电脑?...
  10. Springboot2.x+Websocket+js实现实时在线文本协同编辑,并展示协同用户