目录

Easy Excel

所需依赖

准备一个excel文件

对excel的读取

创建对应的实体类

创建EasyExcelUtil类

修改实体类

对excel的写入

在EasyExcelUtil类中加入写方法

对excel的填充

在EasyExcelUtil类中加入填充方法

 整合为工具类


Easy Excel

EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。
他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。

所需依赖

    <dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<!--lombok依赖可以不加,只是之后要手动的写get,set方法-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.24</version>
			<scope>provided</scope>
		</dependency>

		<!--easyexcel-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>easyexcel</artifactId>
			<version>2.1.6</version>
		</dependency>
		<!--slf4j 日志-->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.30</version>
		</dependency>
	</dependencies>

准备一个excel文件

内容如下:

id姓名年龄
1小明12
2小红13
3小刚13
4小美11
5小智10

对excel的读取

创建对应的实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String id;
    private String name;
    private Integer age;
}

如果没有导入lombok依赖需要手动加入get,set方法和构造方法

创建EasyExcelUtil类

package com.li.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.SyncReadListener;
import com.li.pojo.DemoData;
import com.li.pojo.User;

import java.util.ArrayList;
import java.util.List;

public class EasyExcelUtil {

    public static void main(String[] args) {
        EasyExcelUtil.read1();
    }

    private static void read1() {
        final List list = new ArrayList();
        //使用EasyExcel读取test1.xlsx文件
        EasyExcel.read("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class, new SyncReadListener() {
            //EasyExcel在读取excel表格时,每读取到一行,就会调用一次这个方法,
            //并且将读取到的行数据,封装到指定类型(User)的对象中,传递给我们(Object object)
            /*
            此问题可能出现在低版本的easyExcel中,出现时可以按照下列方式解决
                如果表格数据不是顶行写的,需要通过headRowNumber指定表头行的数量
                如果表格数据不是顶列写的,需要在封装的实体属性上通过@ExcelProperty将实体属性和表格列名进行对应
             */
            @Override
            public void invoke(Object object, AnalysisContext context) {
                System.out.println(object);
                list.add(object);
            }
        }).doReadAll();

        //获取读取到的数据
        for (Object object : list) {
            User user = (User) object;
            System.out.println(user);
        }
    }
}

运行main后效果如下:

添加一个方法后再次运行

package com.li.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.event.SyncReadListener;
import com.li.pojo.DemoData;
import com.li.pojo.User;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class EasyExcelUtil {

    public static void main(String[] args) {
        EasyExcelUtil.read2();
    }

    private static void read1() {
        final List list = new ArrayList();
        //使用EasyExcel读取test1.xlsx文件
        EasyExcel.read("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class, new SyncReadListener() {
            //EasyExcel在读取excel表格时,每读取到一行,就会调用一次这个方法,
            //并且将读取到的行数据,封装到指定类型(User)的对象中,传递给我们(Object object)
            /*
            此问题可能出现在低版本的easyExcel中,出现时可以按照下列方式解决
                如果表格数据不是顶行写的,需要通过headRowNumber指定表头行的数量
                如果表格数据不是顶列写的,需要在封装的实体属性上通过@ExcelProperty将实体属性和表格列名进行对应
             */
            @Override
            public void invoke(Object object, AnalysisContext context) {
                System.out.println(object);
                list.add(object);
            }
        }).doReadAll();

        //获取读取到的数据
        for (Object object : list) {
            User user = (User) object;
            System.out.println(user);
        }
    }

    private static void read2() {
        final List list = new ArrayList();
        //使用EasyExcel读取test1.xlsx文件
        EasyExcel.read("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class, new AnalysisEventListener<User>() {
                    //重写子类方法
                    @Override
                    public void invoke(User user, AnalysisContext analysisContext) {
                        list.add(user);
                    }

                    //重写子类方法
                    @Override
                    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

                    }

                    @Override
                    public void invokeHeadMap(Map headMap, AnalysisContext context) {
                        System.out.println(headMap);
                    }
                }
        ).doReadAll();

        //获取读取到的数据
        for (Object o : list) {
            User user = (User) o;
            System.out.println(user);
        }
    }

}

运行效果如下:

这次的方法可以获取到表头

修改实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @ExcelProperty(index = 0)
    private String id;
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty(index = 3)
    private Integer age;
}

 @ExcelProperty注解中的index表示excel表中的列,默认是0,下标从0开始。默认的name,也就是名字,表示该列的表头。

不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配。

用名字去匹配,需要注意,如果名字重复,会导致只有一个字段读取到数据。

如果有一个index的列向后移动了一列,那么之后的属性默认会获取向后移动一列的数据

修改好后运行结果如下

这里可以看到age没有获取到值,因为我们将他的index设置的3,是没有值的列。

 将其修改为2后就会恢复正常

对excel的写入

在EasyExcelUtil类中加入写方法

private static void write1() {
        List list = new ArrayList();
        list.add(new User("1", "大明", 1));
        list.add(new User("2", "大红", 1));
        list.add(new User("3", "大刚", 1));
        //1.
        EasyExcel
                .write("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class)
                .sheet(1)//可以在其中写入数字,将其设置为sheet页的名称,不写默认是0
                .doWrite(list);
    }
    
    public static void write2(){
        List list = new ArrayList();
        list.add(new User("1", "大明", 1));
        list.add(new User("2", "大红", 1));
        list.add(new User("3", "大刚", 1));
        //2.
        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class).build();
            WriteSheet writeSheet = EasyExcel.writerSheet("sheet名称").build();
            excelWriter.write(list, writeSheet);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }

然后在main方法中运行后查看excel表

 运行write2()效果

 在对表进行写的时候,表头默认是属性名,也可以使用注解进行更改。

对excel的填充

在EasyExcelUtil类中加入填充方法

private static void write_template_multi() {
        List list = new ArrayList();
        /*list.add(new User("1", "大明", 1));
        list.add(new User("2", "大红", 1));
        list.add(new User("3", "大刚", 1));*/
        EasyExcel
                .write("C:\\Users\\lenovo\\Desktop\\user.xlsx", User.class)
                .withTemplate("C:\\Users\\lenovo\\Desktop\\user_template.xlsx")
                .sheet()
                .doFill(list);
    }

 该方法会将user_template.xlsx中的内容复制到user.xlsx中

创建一个user_template.xlsx文件,内容如下:

 

id姓名age
1name18

 然后在main中运行方法结果如下

user.xlsx的内容和user_template.xlsx一样了。

可以通过修改实体类的注解来改变表格中的样式

@Data
@AllArgsConstructor
@NoArgsConstructor
@HeadRowHeight(30) //表头行高
@ContentRowHeight(20) //数据行高
@ColumnWidth(25) //列宽
public class User {
    @ExcelProperty("id")
    private String id;
    @ExcelProperty({"个人信息","姓名"})
    private String name;
    @ExcelProperty({"个人信息","年龄"})
    private Integer age;
}

重新创建表格后的结果如下

 整合为工具类

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.event.SyncReadListener;
import com.alibaba.excel.write.metadata.WriteSheet;

import java.io.File;
import java.util.*;

public class EasyExcelUtil {

    /**
     * 读取excel表格
     * @param file 目标文件
     * @param head 文件读出后所对应的类
     * @return 返回读出数据的集合
     */
    private static List readExcel(File file,Class head) {
        final List list = new ArrayList();
        //使用EasyExcel读取.xlsx文件
        EasyExcel.read(file, head, new SyncReadListener() {
            @Override
            public void invoke(Object object, AnalysisContext context) {
                list.add(object);
            }
        }).doReadAll();
        return list;
    }

    /**
     * 读取excel表格
     * @param file 目标文件
     * @param head 文件读出后所对应的类
     * @return 返回一个Map,其中有数据的集合list,还有一个表格中的标题map
     */
    private static Map<String, Object> readExcelTitle(File file, Class head){
        //使用EasyExcel读取.xlsx文件
        List list=new ArrayList();
        Map<String,Object> map=new HashMap<>();
        EasyExcel.read(file,head, new AnalysisEventListener<Object>() {
                    //重写子类方法
                    @Override
                    public void invoke(Object object, AnalysisContext analysisContext) {
                        list.add(object);
                    }
                    //重写子类方法
                    @Override
                    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                    }

                    @Override
                    public void invokeHeadMap(Map headMap, AnalysisContext context) {
                        //headMap,中存放着表格标题
                        map.put("title",headMap);//将标题存放到定义的map中
                        System.out.println(headMap);
                    }
                }
        ).doReadAll();
        map.put("data",list);//将数据存放到定义的map中
        return map;
    }

    /**
     * 将数据写入到表格中,如果不存在则会创建一个表格
     * @param file 目标文件
     * @param list 要写入的数据
     * @param head 数据对应的实体类
     */
    private static void writeExcel(File file, List list, Class head) {
        EasyExcel
                .write(file, head)
                .sheet()
                .doWrite(list);
    }

    /**
     * 将数据写入到表格中,如果不存在则会创建一个表格
     * @param file 目标文件
     * @param list 要写入的数据
     * @param head 数据对应的实体类
     * @param sheetName sheet页的名字
     */
    private static void writeExcel(File file, List list, Class head,String sheetName) {
        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(file, head).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
            excelWriter.write(list, writeSheet);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }

    /**
     * 将模板数据写入到表格中
     * @param file 对应的表格文件
     * @param fileTemplate 模板文件
     * @param head 对应的实体类
     */
    private static void write_template_multi(File file,File fileTemplate,Class head) {
        List list = new ArrayList();
        EasyExcel
                .write(file, head)
                .withTemplate(fileTemplate)
                .sheet()
                .doFill(list);
    }

}

以上就是使用Easy Excel对excel的快速读写

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐