为什么说EasyExcel可以让你告别easypoi呢?在说这个问题之前我们先来了解下easypoi
easypoi
easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法
这是easypoi官方给出的定义,使用这个工具后发现在进行excel的导入导出时,的确很方便。特别是一些简单的excel
比如这种简单的excel,easypoi的确是不二选择,只需要引入mavn依赖,添加一个pojo,加一个注解,然后就可以导出。 但是在遇到一些比较复杂的excel,比如下面这种:
类似与这种比较复杂的表头,一个sheet多张表,多个sheet,合并单元格各种复杂的情况下,easypoi处理起来就比较复杂了,反观easyExcel就比较拿手。
easyExcel处理简单的excel和easypoi一样简单,处理复杂的excel也完全可以通过注解的方式一步到位。开发者只需要编写很少的style代码就能直接达到自己想要的效果,下面就让我们一起来看看easyExcel的强大之处
引入maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.10</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
新建实体
@Data
@Accessors(chain = true)
@FieldNameConstants
@HeadRowHeight(value = 25)
@ContentRowHeight(value = 18)
@ColumnWidth(value = 20)
@HeadStyle(fillBackgroundColor = 64)
@HeadFontStyle(bold = false)
@ContentStyle(borderTop= BorderStyle.THIN,borderLeft = BorderStyle.THIN,borderRight = BorderStyle.THIN,borderBottom = BorderStyle.THIN)
public class ComplexSubjectEasyExcel {
@ExcelProperty(value = {"科目余额表","编制单位: 测试单位321412","科目编码","科目编码"},index = 0)
private String subjectId;
@ExcelProperty(value = {"科目余额表","编制单位: 测试单位321412","科目名称","科目名称"},index = 1)
private String subjectName;
@HeadFontStyle(bold = true)
@ExcelProperty(value = {"科目余额表","编制单位: 测试单位321412","期初余额","借方"},index = 2)
private BigDecimal firstBorrowMoney;
@HeadFontStyle(bold = true)
@ExcelProperty(value = {"科目余额表","编制单位: 测试单位321412","期初余额","贷方"},index = 3)
private BigDecimal firstCreditMoney;
@HeadFontStyle(bold = true)
@ExcelProperty(value = {"科目余额表","2021年9月至2021年9月","本期发生额","借方"},index = 4)
private BigDecimal nowBorrowMoney;
@HeadFontStyle(bold = true)
@ExcelProperty(value = {"科目余额表","2021年9月至2021年9月","本期发生额","贷方"},index = 5)
private BigDecimal nowCreditMoney;
@HeadFontStyle(bold = true)
@ExcelProperty(value = {"科目余额表","2021年9月至2021年9月","本年累计发生额","借方"},index = 6)
private BigDecimal yearBorrowMoney;
@HeadFontStyle(bold = true)
@ExcelProperty(value = {"科目余额表","2021年9月至2021年9月","本年累计发生额","贷方"},index = 7)
private BigDecimal yearCreditMoney;
@HeadFontStyle(bold = true)
@ExcelProperty(value = {"科目余额表","单位:元","期末余额","借方"},index = 8)
private BigDecimal endBorrowMoney;
@HeadFontStyle(bold = true)
@ExcelProperty(value = {"科目余额表","单位:元","期末余额","贷方"},index = 9)
private BigDecimal endCreditMoney;
}
@ExcelProperty 注解的value是个数组,按照index从上到下,相同的值头部会进行合并。这种合并头部的方式相比easypoi的实体嵌套显得直观多了,更加方便。我们对页面列表的数据查询后,也不用进行数组对象嵌套组装,省了很多的工作量,如果希望头部的标题是动态的也可以设置成#{title}的方式(当然这是我自己封装的)
导出工具
下面我封装的easyExcel导出工具,使用的话可以直接复制,并自己做些适当的调整
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.builder.ExcelWriterTableBuilder;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import org.springframework.util.Assert;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.*;
/**
* easyExcel工具
*/
public class EasyExcelUtilsV1 {
public static final String FILE_PATH = "/home/easy/excel/";
public static final Map<String,List<ExcelAnnotationValue>> annotationValues = new HashMap<>();
private static String outputStream(String fileName){
try {
String path = FILE_PATH+new Date().getTime() +"/";
String filePath = path+fileName+".xls";
File dir = new File(path);
if(!dir.exists()){
dir.mkdirs();
}
File file = new File(filePath);
if(file.exists()){
file.deleteOnExit();
}
file.createNewFile();
return filePath;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 默认导出方式 单个sheet
*/
public static String defaultE