EasyExcel的系列操作

发布于 2023-06-03  1.82k 次阅读


1. EasyExcel的介绍

EasyExcel是由阿里开源的excel解析读取写入框架,生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便

官方网站:

16M内存23秒读取75M(46W行25列)的Excel(3.2.1+版本):

总结:EasyExcel是快速、简单、避免OOM的java处理Excel工具

注意:这个工具操作方法官方文档提供的非常详细,甚至连需求如何写的代码都有对应案例

2. EasyExcel写操作

2.1 写操作基本使用

引入依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.1</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
</dependency>

使用步骤:

  • 新建Excel模板类
  • 通过工具操作类进行读写操作
① Excel模板类
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@EqualsAndHashCode
public class exceluserpojo {

    @ExcelProperty("用户编号")
    private Integer userId;

    @ExcelProperty("姓名")
    private String userName;

    @ExcelProperty("性别")
    private String gender;

    @ExcelProperty("工资")
    private Double salary;

    @ExcelProperty("入职时间")
    private Date hireDate;
}
  • @ExcelProperty:这个注解的作用是描述设置Excel表格的头名称

② 写法一:使用链式调用写法

@Test
public void test01(){
    //创建Excel文档
    String fileName = "user1.xlsx";
    //根据exceluserpojo模板构建数据
    List<exceluserpojo> exceluserpojos = new ArrayList<exceluserpojo>();
    exceluserpojos.add(new exceluserpojo(1,"空想家","男",4000.99,new Date()));
    exceluserpojos.add(new exceluserpojo(2,"晴天","女",6000.99,new Date()));
    exceluserpojos.add(new exceluserpojo(3,"项庄","男",3000.99,new Date()));
    //向Excel表格中写数据
    EasyExcel.write(fileName,exceluserpojo.class).sheet("用户信息表").doWrite(exceluserpojos);
}
  • write():文件写入的位置和对应模板类
  • sheet():表对象设置,有参为表名称
  • doWrite():具体写入什么数据,传入Collection的子类

③ 写法二:使用普通的对象写法

@Test
public void test02(){
    //创建Excel文档
    String fileName = "user1.xlsx";
    //根据exceluserpojo模板构建数据
    List<exceluserpojo> exceluserpojos = new ArrayList<exceluserpojo>();
    exceluserpojos.add(new exceluserpojo(1,"玄门","男",4000.99,new Date()));
    exceluserpojos.add(new exceluserpojo(2,"晴天","女",6000.99,new Date()));
    exceluserpojos.add(new exceluserpojo(3,"项庄","男",3000.99,new Date()));
    //获取ExcelWriterBuilder对象
    ExcelWriter execlWrite = EasyExcel.write(fileName, exceluserpojo.class).build();
    //创建sheet对象
    WriteSheet sheet = EasyExcel.writerSheet("用户信息").build();
    //将数据写入sheet标签中
    execlWrite.write(exceluserpojos,sheet);
    //关闭流,文件流手动关闭
    execlWrite.finish();
}

2.2 写操作高级使用

高级写法有:

  1. 排除某些字段写入
  2. 只允许某些字段写入
  3. 设置excel表格中列的顺序
  4. 复杂头写入
  5. 写入不同的sheet中
  6. 日期数字格式化
  7. 将图片写入excel

2.2.1 排除字段写入

步骤:

  1. 创建需要排除的属性集合,将表头名称传入
  2. 调用EasyExcel的excludeColumnFieldNames()方法排除对应的属性

演示:

//排除字段写入
@Test
public void test03(){
    //创建Excel文档
    String fileName = "excludeuser.xlsx";
    //根据exceluserpojo模板构建数据
    List<exceluserpojo> exceluserpojos = new ArrayList<exceluserpojo>();
    exceluserpojos.add(new exceluserpojo(1,"空想家","男",4000.99,new Date()));
    exceluserpojos.add(new exceluserpojo(2,"晴天","女",6000.99,new Date()));
    exceluserpojos.add(new exceluserpojo(3,"项庄","男",3000.99,new Date()));
    //设置排除的属性集合
    Set<String> set = new HashSet<>();
    set.add("salary");
    set.add("gender");


    //向Excel表格中写数据
    EasyExcel.write(fileName,exceluserpojo.class)
            //排除属性
            .excludeColumnFieldNames(set)
            .sheet("用户信息表")
            .doWrite(exceluserpojos);
}

2.2.2 允许字段写入

步骤和排除字段写入相似:

  • 创建需要写入的属性集合,将表头名称传入
  • 调用EasyExcel的includeColumnFieldNames()方法排除对应的属性
演示:
//只允许字段写入
@Test
public void test04(){
    //创建Excel文档
    String fileName = "includeuser.xlsx";
    //根据exceluserpojo模板构建数据
    List<exceluserpojo> exceluserpojos = new ArrayList<exceluserpojo>();
    exceluserpojos.add(new exceluserpojo(1,"空想家","男",4000.99,new Date()));
    exceluserpojos.add(new exceluserpojo(2,"晴天","女",6000.99,new Date()));
    exceluserpojos.add(new exceluserpojo(3,"项庄","男",3000.99,new Date()));
    //设置排除的属性集合
    Set<String> set = new HashSet<>();
    set.add("userName");
    set.add("gender");

    //向Excel表格中写数据
    EasyExcel.write(fileName,exceluserpojo.class)
            //只包含属性
            .includeColumnFieldNames(set)
            .sheet("用户信息表")
            .doWrite(exceluserpojos);
}

2.2.3 设置列的顺序

列的顺序设置通过模板类的@ExcelProperty中的index设置优先级

例:

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@EqualsAndHashCode
public class exceluserpojo {

    @ExcelProperty(value = "用户编号",index = 1)
    private Integer userId;

    @ExcelProperty(value = "姓名",index = 0)
    private String userName;

    @ExcelProperty(value = "性别",index = 2)
    private String gender;

    @ExcelProperty(value = "工资",index = 4)
    private Double salary;

    @ExcelProperty(value = "入职时间",index = 3)
    private Date hireDate;
}

写出测试:

2.2.4 复杂头写入

复杂头指的是多级表头,复杂头的设置在@ExcelProperty的value属性,value通过{}包含多个表头,第一个值为后面值的父表头

例:

@NoArgsConstructor
@ToString
@Data
@EqualsAndHashCode
public class themeuserpojo {
    @ExcelProperty(value = {"用户信息","用户编号"})
    private Integer userId;


    @ExcelProperty(value = {"用户信息","姓名"})
    private String userName;


    @ExcelProperty(value = {"其他信息","性别"})
    private String gender;


    @ExcelProperty(value = {"其他信息","工资"})
    private Double salary;
}

2.2.5 写入不同的sheet中

写不同的sheet需要使用对象式的写法,将sheet提取出来进行批量不同写入

例:

@Test//写入不同的sheet
public void test07(){
    //创建Excel文档
    String fileName = "diffsheet.xlsx";
    //根据exceluserpojo模板构建数据
    List<exceluserpojo> exceluserpojos = new ArrayList<exceluserpojo>();
    exceluserpojos.add(new exceluserpojo(1,"空想家","男",4000.99,new Date()));
    exceluserpojos.add(new exceluserpojo(2,"晴天","女",6000.99,new Date()));
    //获取ExcelWriter对象
    ExcelWriter excelWriter = EasyExcel.write(fileName, exceluserpojo.class).build();

    for(int i=0;i<4;i++){
        WriteSheet build = EasyExcel.writerSheet("用户表" + i).build();
        excelWriter.write(exceluserpojos,build);
    }
    excelWriter.finish();
}

2.2.6 日期数字格式化

格式化涉及到两个注解:

  • @NumberFormat:数字格式化(使用#为占位符)
  • @DateTimeFormat:日期格式化(yyyy MM dd等格式)

例:

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@EqualsAndHashCode
public class dataformatpojo {

    @NumberFormat("#.##")
    @ExcelProperty(value = "工资")
    private Double salary;

    @DateTimeFormat("yyyy年MM月dd日")
    @ExcelProperty(value = "入职时间")
    private Date hireDate;
}

2.2.7 将图片写入excel

将文件写入excel可以使用多种对象方式:

  • 抽象文件类表示(File)
  • 输入流表示(InputStream)
  • String表示
  • 二进制数据保存一张图片
  • url保存一张图片

例:

① 模板类

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
public class ImageData {
    //使用抽象文件表示一个图片
    private File file;

    //使用输入流保存一个文件
    private InputStream inputStream;

    //使用String类型表示保存一个图片,需要使用StringImageConverter转换器
    @ExcelProperty(converter = StringImageConverter.class)
    private String imgStr;

    //使用二进制数据保存为一种图片
    private  byte[] byteArray;

    //使用网络链接保存一个图片
    private URL url;
}

② 写入操作

@Test
public void test() throws IOException {

    String name = "imageuser.xlsx";

    ArrayList<ImageData> arrayList = new ArrayList<>();
    ImageData imageData = new ImageData();
    imageData.setFile(new File("wql.jpg"));
    imageData.setInputStream(new FileInputStream(new File("wql.jpg")));
    imageData.setImgStr("wql.jpg");
    imageData.setUrl(new URL("https://wql.luoqin.ltd/wp-content/uploads/2022/06/1-2.jpg"));


    byte[] b = new byte[(int)new File("wql.jpg").length()];
    FileInputStream fileInputStream = new FileInputStream("wql.jpg");
    fileInputStream.read(b,0,(int)new File("wql.jpg").length());
    imageData.setByteArray(b);
    //添加到集合
    arrayList.add(imageData);

    EasyExcel.write(name,ImageData.class).sheet("图片写入表").doWrite(arrayList);
}

3. EasyExcel读操作

3.1 简单读操作

简单读操作两种写法:

  • 链式调用写法
  • 对象式写法

    和写一样读操作需要指定需要读的文件地址、接收的模板对象(如果xslx一样写入模板可以和读取模板一样),最后最重要的是使用AnalysisEventListener回调函数(可以单独声明也可以使用匿名内部类)

读入的xslx:

接收的模板对象:和写模板一样

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
public class exceluserpojo {

    private Integer userId;

    private String userName;

    private String gender;

    private Double salary;

    private Date hireDate;
}

例:

① 第一种写法:链式调用,最后需要指定sheet并提供doread触发读取

@Test
public void easyreadtest() throws IOException {

    String filepathname = "G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx";

    EasyExcel.read("G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx", exceluserpojo.class, new AnalysisEventListener<exceluserpojo>() {
        @Override
        public void invoke(exceluserpojo o, AnalysisContext analysisContext) {
            System.out.println(o);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {

        }
    }).sheet().doRead();
}

② 第二种写法:对象调用

@Test
public void easyreadtest2() throws IOException {
    String filepathname = "G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx";


    ExcelReader excelReader = EasyExcel.read("G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx", exceluserpojo.class, new AnalysisEventListener<exceluserpojo>() {
        @Override
        public void invoke(exceluserpojo o, AnalysisContext analysisContext) {
            System.out.println(o);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("全部读取完毕!");
        }
    }).build();

    //创建sheet对象,并读取excel的第1个sheet(下标从0开始)
    ReadSheet sheet = EasyExcel.readSheet(0).build();
    excelReader.read(sheet);
    //关闭流操作,在读取文件时会创建临时文件,如果不关闭,磁盘会爆掉
    excelReader.finish();
}

3.2 高级读操作

高级读操作有:

  • 通过列名称或者下标获取指定列
  • 读取数据进行格式化
  • 读取全部的sheet表格
  • 读取指定sheet表格

3.2.1 读取指定列

    读取指定列指的是将对应列读取到对应模板类的属性中,这个也是借助@ExcelProperty它不仅可以在写中使用在读取中也需要通过它进行匹配性的读入

指定列读取:

  • @ExcelProperty(value=""):通过名称读入指定列到指定类属性
  • @ExcelProperty(index=""):通过下标读入指定列到指定类属性

读入的xslx:

模板:

@EqualsAndHashCode
@Data
public class exceluserpojo {

    @ExcelProperty(value = "用户编号")
    private Integer userId;

    @ExcelProperty(value = "姓名")
    private String userName;

    @ExcelProperty(value = "性别")
    private String gender;

    @ExcelProperty(value = "工资")
    private Double salary;

    @ExcelProperty(value = "入职时间")
    private Date hireDate;

}

例:

@Test
public void easyreadtest() throws IOException {

    String filepathname = "G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx";

    EasyExcel.read("G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx", exceluserpojo.class, new AnalysisEventListener<exceluserpojo>() {
        @Override
        public void invoke(exceluserpojo o, AnalysisContext analysisContext) {
            System.out.println(o);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("全部读取完毕!");
        }
    }).sheet().doRead();
}

3.2.2 读取格式化数据

    读取格式化数据也依赖EasyExcel的@NumberFormat和@DateTimeFormat注解,当读取的excel内容数据是格式化的时,通过这个两个注解去匹配格式化数据进行读取不然读取时就会报错

注:当格式化读取数值类型时@NumberFormat失效,建议将类型换成String在读取后再转换成Double,不建议总结使用Double

读取数据内容格式:

读取模板:

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@EqualsAndHashCode
public class exceluserpojo {

    @ExcelProperty(value = "用户编号")
    private Integer userId;

    @ExcelProperty(value = "姓名")
    private String userName;

    @ExcelProperty(value = "性别")
    private String gender;

    @ExcelProperty(value = "工资")
    @NumberFormat("#.##")
    private String salary;

    @ExcelProperty(value = "入职时间")
    @DateTimeFormat("yyyy年MM月dd日")
    private Date hireDate;
}

例:

@Test
public void easyreadtest() throws IOException {

    String filepathname = "G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx";

    EasyExcel.read("G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx", exceluserpojo.class, new AnalysisEventListener<exceluserpojo>() {
        @Override
        public void invoke(exceluserpojo o, AnalysisContext analysisContext) {
            System.out.println(o);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("全部读取完毕!");
        }
    }).sheet().doRead();
}

3.2.3 读取全部sheet表格

读取全部的sheet表格不需要指定sheet表格,但需要注意的是要保证所有的sheet使用的模板是一样的,不然如果某一个模板不匹配就会报错

  • 全部读取是使用doReadAll()方法

读取的多个sheet数据:

模板:和读取格式化数据模板一样

例:每结束读取一个sheet会触发一次doAfterAllAnalysed()方法

@Test
public void Allreadtest() throws IOException {

    String filepathname = "G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx";

    EasyExcel.read("G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx", exceluserpojo.class, new AnalysisEventListener<exceluserpojo>() {
        @Override
        public void invoke(exceluserpojo o, AnalysisContext analysisContext) {
            System.out.println(o);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("全部读取完毕!");
        }
    }).doReadAll();
}

3.2.4 读取指定sheet表格

读取指定的sheet表格,可能每一个sheet数据模板不一样需要单独指定模板,EasyExcel提供了方便只需要创建一次ExcelReader对象,手动指定sheet和模板

指定读取sheet数据:

模板对象:

① exceluserpojo

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@EqualsAndHashCode
public class exceluserpojo {

    @ExcelProperty(value = "用户编号")
    private Integer userId;

    @ExcelProperty(value = "姓名")
    private String userName;

    @ExcelProperty(value = "性别")
    private String gender;

    @ExcelProperty(value = "工资")
    @NumberFormat("#.##")
    private String salary;

    @ExcelProperty(value = "入职时间")
    @DateTimeFormat("yyyy年MM月dd日")
    private Date hireDate;
}

② excludepojo

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@EqualsAndHashCode
public class excludepojo {
    @ExcelProperty(value = "用户编号")
    private Integer userId;

    @ExcelProperty(value = "姓名")
    private String userName;

    @ExcelProperty(value = "性别")
    private String gender;
}

例:

@Test
public void zhidreadtest() throws IOException {

    String filepathname = "G:\\Java-Dome\\EasyExcel-Dome\\user1.xlsx";

    ExcelReader excelReader = EasyExcel.read(filepathname).build();

    //读取第一个sheet
    ReadSheet readSheet1 = EasyExcel.readSheet(0).head(exceluserpojo.class).registerReadListener(new AnalysisEventListener<exceluserpojo>() {
        @Override
        public void invoke(exceluserpojo o, AnalysisContext analysisContext) {
            System.out.println(o);
        }
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("sheet1全部读取完毕!");
        }
    }).build();

    //读取第二个sheet
    ReadSheet readSheet2 = EasyExcel.readSheet(1).head(excludepojo.class).registerReadListener(new AnalysisEventListener<excludepojo>() {
        @Override
        public void invoke(excludepojo o, AnalysisContext analysisContext) {
            System.out.println(o);
        }


        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            System.out.println("sheet2全部读取完毕!");
        }
    }).build();

    //批量读取两个sheet
    excelReader.read(readSheet1,readSheet2);
    //关闭流
    excelReader.finish();
}

4.EasyExcel其他操作

4.1 样式设置

EasyExcel写入时的样式设置包括:

  1. 列宽、行高、内容高度设置
  2. 头背景、头字体设置
  3. 内容背景、内容字体设置

4.1.1 列宽行高设置

列宽行高内容高度涉及到三个注解:

  • @ContentRowHeight():设置内容高度
  • @HeadRowHeight():设置标题高度
  • @ColumnWidth():设置列宽

    这些注解可标记在类上也可以标记的在属性上,标记在类上的注解可以控制属性的行高,标记在属性上的注解可以覆盖类上的控制

例:

① 模板类

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@ContentRowHeight(30)//设置内容高度
@HeadRowHeight(40)//设置标题高度
@ColumnWidth(25)//设置列宽
public class WidthAndHeighpojo {

    @ExcelProperty(value = "字符标题")
    private String title;

    @ExcelProperty(value = "内容")
    private String content;

    @ExcelProperty(value = "图片",converter= StringImageConverter.class)
    private String image;
}

② 操作

@DisplayName("列宽行高演示")
public class WidthAndHeighTest {
    @Test
    public void test() throws IOException {
        ArrayList<WidthAndHeighpojo> widthAndHeighpojos = new ArrayList<WidthAndHeighpojo>();
        widthAndHeighpojos.add(new WidthAndHeighpojo("空想家","中二少年不少年","wql.jpg"));

        EasyExcel.write("WidthAndHeigh.xlsx",WidthAndHeighpojo.class).sheet("列宽行高").doWrite(widthAndHeighpojos);

    }

4.1.2 样式设置

 excel样式设置包括的注解:

  • @HeadStyle:头背景颜色样式
  • @HeadFontStyle:头字体样式
  • @ContentStyle:内容的背景设置
  • @ContentFontStyle:内容字体数字

     这些注解可标记在类上也可以标记的在属性上,标记在类上的注解可以控制属性的行高,标记在属性上的注解可以覆盖类上的控制

    其中在设置颜色时选择FillPatternTypeEnum.SOLID_FOREGROUND,EasyExcle提供IndexedColors颜色枚举类,在fillForegroundColor属性中输入对应的颜色标记即可

例:

① 模板类

//头背景设置成红色
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,fillForegroundColor =10)
//头字体大小设置成20
@HeadFontStyle(fontHeightInPoints = 20)
//设置内容背景颜色为蓝色
@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,fillForegroundColor =4)
//内容字体设置成20
@ContentFontStyle(fontHeightInPoints = 20)
public class stylepojo {
    @ExcelProperty(value = "字符标题")
    private String title;

    @ExcelProperty(value = "内容")
    private String content;
}

② 操作

@Test
public void test() throws IOException {
    ArrayList<stylepojo> stylepojos = new ArrayList<stylepojo>();
    stylepojos.add(new stylepojo("空想家","中二少年不少年"));

    EasyExcel.write("WidthAndHeigh.xlsx",stylepojo.class).sheet("样式").doWrite(stylepojos);
}

4.2 合并单元格

合并单元格的注解:

  • @ContentLoopMerge:每列对行的合并
  • @OnceAbsoluteMerge:列的合并,指定从那一行开始,那一行结束,那一列开始,那一列结束,参数如下
    • firstRowIndex:起始行的索引,从0开始
    • lastRowIndex:结束行索引
    • firstColumnIndex:起始列索引
    • lastColumnIndex:结束列索引

例:

① 模板类

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
//将第2-3行的2-3列合并成一个单元格
@OnceAbsoluteMerge(firstRowIndex = 2,lastRowIndex = 3,firstColumnIndex = 1,lastColumnIndex = 2)
public class mergerowpojo {

    @ExcelProperty(value = "字符串标题")
    private String str;

    //这一列每隔2行合并单元格
    @ContentLoopMerge(eachRow = 2)
    @ExcelProperty(value = "日期标题")
    private Date date;

    @ExcelProperty(value = "数字标题")
    private Double aDouble;
}

②操作

@DisplayName("合并单元格")
public class mergeTest {
    @Test
    public void test() throws IOException {
        ArrayList<mergerowpojo> mergerowpojo = new ArrayList<mergerowpojo>();
        mergerowpojo.add(new mergerowpojo("空想家",new Date(),100.0));
        mergerowpojo.add(new mergerowpojo("晴天",new Date(),100.0));
        mergerowpojo.add(new mergerowpojo("栖息",new Date(),100.0));
        mergerowpojo.add(new mergerowpojo("道德",new Date(),100.0));

        EasyExcel.write("mergerow.xlsx",mergerowpojo.class).sheet("样式").doWrite(mergerowpojo);
    }
}

4.3 数据填充

EasyExcel数据填充的步骤:

  1. 创建填充的excel模板
  2. 创建填充对象类
  3. 进行填充操作

填充模板也是一个Excel,它里面可以写通配占位符:通过{}包裹

  • {name}:填充类对象的name属性(单对象填充)
  • {.name}:表示填充列表中的所有类中的name属性(多对象填充)
  • 如果{}仅仅只表示符号可以通过\进行转义

4.3.1 单对象填充

模板excel:

实体类:

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class fullexcelpojo {

    private String nickname;

    private Integer age;
}

操作:

@Test
public void dangfulleasttest(){
    String exceltempalate = "G:\\Java-Dome\\EasyExcel-Dome\\TemplateExcel.xlsx";
    String filepath = "G:\\Java-Dome\\EasyExcel-Dome\\tptoExcel.xlsx";


    fullexcelpojo fullexcelpojo = new fullexcelpojo();
    fullexcelpojo.setNickname("空想家");
    fullexcelpojo.setAge(18);
    EasyExcel.write(filepath).withTemplate(exceltempalate).sheet().doFill(fullexcelpojo);
}
  • write:写入的文件路径
  • withTemplate:关联的模板
  • doFill:填充的类对象

4.3.2 多对象填充

模板Excel:

实体类:和单对象时一样

操作:

@Test
public void duofulleasttest(){
    String exceltempalate = "G:\\Java-Dome\\EasyExcel-Dome\\TemplateExcel.xlsx";
    String filepath = "G:\\Java-Dome\\EasyExcel-Dome\\tptoExcel.xlsx";

    ArrayList<fullexcelpojo> arrayList = new ArrayList<>();
    arrayList.add(new fullexcelpojo("空想家",18));
    arrayList.add(new fullexcelpojo("晴天",20));
    arrayList.add(new fullexcelpojo("火狐",12));
    arrayList.add(new fullexcelpojo("烤肉",2));
    EasyExcel.write(filepath).withTemplate(exceltempalate).sheet().doFill(arrayList);
}

5. EasyExcel文件操作

5.1 文件下载

下载过程:

  • 构建execl模板对象
  • 设置HttpServletResponse的响应信息和头信息
  • EasyExcel写操作,输出流使用HttpServletResponse获取流

HttpServletResponse需要做的操作:

  • 响应类型和编码
  • 下载文件方式(1.附件下载 2.在当前浏览器打开)
  • 获取输出流response.getOutputStream()

① 数据模板类

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@EqualsAndHashCode
public class exceluserpojo {

    @ExcelProperty(value = "用户编号")
    private Integer userId;

    @ExcelProperty(value = "姓名")
    private String userName;

    @ExcelProperty(value = "性别")
    private String gender;

    @ExcelProperty(value = "工资")
    @NumberFormat("#.##")
    private String salary;

    @ExcelProperty(value = "入职时间")
    @DateTimeFormat("yyyy年MM月dd日")
    private Date hireDate;
}

② 下载实现类

@Controller
public class downloadcontroll {

    @RequestMapping("/downloadexcel")
    public void downloadexcel(HttpServletResponse response) throws IOException {

        //设置响应类型和编码
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");

        //下载的文件名
        String filename = "测试表.xlsx";

        //文件名的中文名称编码设置
        filename = URLEncoder.encode(filename,"utf-8");

        //下载文件方式(1.附件下载 2.在当前浏览器打开)
        response.setHeader("Content-dispostion","attachment="+filename+".xlsx");

        //根据exceluserpojo模板构建数据
        List<exceluserpojo> exceluserpojos = new ArrayList<exceluserpojo>();
        exceluserpojos.add(new exceluserpojo(1,"空想家","男","4000.99",new Date()));
        exceluserpojos.add(new exceluserpojo(2,"晴天","女","6000.99",new Date()));
        exceluserpojos.add(new exceluserpojo(3,"项庄","男","3000.99",new Date()));

        //输出流使用HttpServletResponse获取
        EasyExcel.write(response.getOutputStream(),exceluserpojo.class).sheet().doWrite(exceluserpojos);
    }
}

③ 简单下载网页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>下载上传页面</title>
</head>
<body>
    <a href="http://127.0.0.1:8080/">Excel下载</a>
</body>
</html>

5.2 文件上传

上传过程:

  • 导入commons-fileupload文件上传依赖
  • 使用MultipartFile接收上传文件
  • EasyExcel读取MultipartFile.getInputStream()输入流
  • EasyExcel读取数据后的逻辑处理

上传文件:

① 模板对象(和下载一样)

②读取操作

@Controller
public class uploadcontroll {

    @RequestMapping(value = "/uploadexcel",method = RequestMethod.POST )
    @ResponseBody
    public String uploadexcel(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        EasyExcel.read(multipartFile.getInputStream(), exceluserpojo.class, new AnalysisEventListener<exceluserpojo>() {
            @Override
            public void invoke(exceluserpojo exceluserpojo, AnalysisContext analysisContext) {
                System.out.println(exceluserpojo);
            }


            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                System.out.println("上传文件读取完成");
            }
        }).sheet().doRead();

        return "上传成功";
    }
}

③ 上传html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传页面</title>
</head>
<body>
    <form action="/uploadexcel" enctype="multipart/form-data"  method="post"  >
        <input type="file" name="file">
        <input type="submit" value="Excel上传">
    </form>
</body>
</html>


路漫漫其修远兮,吾将上下而求索