欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【EasyExcel】Excel操作(九):Excel读取写入一条龙

程序员文章站 2022-06-17 10:26:08
在之前的excel系列博客中给大家带来了Apace POI对excel的操作,今天给大家带来顾名思义炒鸡简单的EasyExcel对excel的操作!!!...
如果你想和别人制造牵绊,就要承受流泪的风险。

简单介绍

在之前的excel系列博客 [点击进入] 中给大家带来了Apace POI对excel的操作,今天给大家带来顾名思义炒鸡简单的EasyExcel对excel的操作!!!

那么什么是EasyExcel呢?我们来到它的github地址:https://github.com/alibaba/easyexcel,发现:
【EasyExcel】Excel操作(九):Excel读取写入一条龙
或者我们来到它的官方文档:https://www.yuque.com/easyexcel/doc/easyexcel
【EasyExcel】Excel操作(九):Excel读取写入一条龙
再点击 关于EasyExcel
【EasyExcel】Excel操作(九):Excel读取写入一条龙
我们就会发现:其实EasyExcel底层就是我们之前讲的Apache POI,但是又有着一些不同

至于更多精彩内容,大家可以自行通过以上我提供的EasyExcel的GitHub和文档地址去发掘。下面,我们就进入实战吧,让大家能够快速上手!!!

快速上手

所需依赖

		<!-- web的起步依赖 -->
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
		<!-- EasyExcel的依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.6</version>
        </dependency>
        <!-- 测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

所需实体类

EasyExcel是直接基于实体类读写的,使用它提供的注解即可,再也不用像以前POI那样麻烦了:

package start.excel.entity;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

import java.util.Date;

@Data // 若未使用lombok插件,请自行生成getter、setter以及toString方法
public class DemoData {

    @ExcelProperty("字符串标题")
    private String string;

    @ExcelProperty("日期标题")
    private Date date;

    @ExcelProperty("数字标题")
    private Double doubleData;
    
    /**
     * 忽略这个字段
     */
    @ExcelIgnore
    private String ignore;
}

以下是EasyExcel官方给的注解解释:
【EasyExcel】Excel操作(九):Excel读取写入一条龙

基本的写

直接上代码,解释见注释:

package start.excel.easyexcel;

import com.alibaba.excel.EasyExcel;
import org.junit.Test;
import start.excel.entity.DemoData;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName EasyExcelRead
 * @Description easyexcel本地生成文件演示
 * @Author 古阙月
 * @Date 2020/11/28 10:47
 * @Version 1.0
 */
public class EasyExcelWrite {

    /**
     * 需要写入的文件路径
     */
    private static final String PATH = "D:\\IdeaProjects\\my_study_demo\\src\\main\\java\\start\\excel\\easyexcel";

    /**
     * 数据部分 - 生成实体类集合
     * @return
     */
    private List<DemoData> data() {
        List<DemoData> list = new ArrayList<DemoData>();
        for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setString("字符串" + i);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }

    /**
     * 最简单的写
     */
    @Test
    public void simpleWrite() {

        String fileName = PATH + File.separator + "demo.xlsx";
        String sheetName = "模板";

        /**
         * fileName - 文件名(包含路径)
         * DemoData.class - 实体类的反射对象
         * sheetName - 工作表的名称
         * data() - 数据部分(实体类集合)
         */
        EasyExcel.write(fileName, DemoData.class).sheet(sheetName).doWrite(data());
    }
}

运行后到PATH的路径下找到名为demo.xlsx的excel文件查看:
【EasyExcel】Excel操作(九):Excel读取写入一条龙
写入成功!!!

基本的读

读入部分:

package start.excel.easyexcel;

import com.alibaba.excel.EasyExcel;
import org.junit.Test;
import start.excel.entity.DemoData;

import java.io.File;

/**
 * @ClassName EasyExcelRead
 * @Description easyexcel读取示范
 * @Author 古阙月
 * @Date 2020/11/28 11:01
 * @Version 1.0
 */
public class EasyExcelRead {

    /**
     * 读取的excel所在的路径
     */
    private static final String PATH = "D:\\IdeaProjects\\my_study_demo\\src\\main\\java\\start\\excel\\easyexcel";

    /**
     * 最简单的读
     * 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
     * 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
     */
    @Test
    public void simpleRead() {
        
        // 路径的文件名 - 即文件所在位置,通过它能找到这个文件
        String fileName = PATH + File.separator + "demo.xlsx";
        
        /**
         * fileName - 文件名(包含路径)
         * DemoData.class - 实体类的反射对象
         * new DemoDataListener() - 监听器
         * sheetName - 工作表的名称
         * data() - 数据部分(实体类集合)
         */
        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();

    }
}

在监听器里面拿到数据:

package start.excel.easyexcel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import start.excel.entity.DemoData;

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

// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
public class DemoDataListener extends AnalysisEventListener<DemoData> {

    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 6;
    
    List<DemoData> list = new ArrayList<DemoData>();

    /**
     * 这个每一条数据解析都会来调用
     * @param data
     * @param context
     */
    @Override
    public void invoke(DemoData data, AnalysisContext context) {

        System.out.println("解析到一条数据:" + JSON.toJSONString(data));
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {

            // 存储完成清理 list
            list.clear();
        }
    }
    /**
     * 所有数据解析完成了 都会来调用
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        System.out.println("最后一次解析了" + list.size() + "条数据!");
        System.out.println("所有数据解析完成!");
    }
}

运行得:
【EasyExcel】Excel操作(九):Excel读取写入一条龙
解析完成!这里在监听器DemoDataListener里面采取了分批处理数据,如我们现在总共有10条数据,我们选择一次解析6条,那么第2次还剩下4条数据也就是最后一次解析了4条数据。当然,如果我们想把数据存入数据库,在监听器DemoDataListener里面操作就好。

web端的写入

代码如下:

package start.excel.easyexcel;

import com.alibaba.excel.EasyExcel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import start.excel.entity.DemoData;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName EasyExcelWriteWeb
 * @Description Web中的写
 * @Author 古阙月
 * @Date 2020/12/8 21:38
 * @Version 1.0
 */
@RestController
@RequestMapping("excel")
public class EasyExcelWriteWeb {

    /**
     * 数据部分 - 生成实体类集合
     * @return
     */
    private List<DemoData> data() {
        List<DemoData> list = new ArrayList<DemoData>();
        for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setString("字符串" + i);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }

    /**
     * excel文件下载(失败了会返回一个有部分数据的Excel)
     */
    @GetMapping("download")
    public void download(HttpServletResponse response) throws IOException {
        // 使用swagger 会导致各种问题,请直接用浏览器或者用postman
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");

        // 文件名 - URLEncoder.encode可以防止中文乱码
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        // 工作表名称
        String sheetName = "测试";

        /**
         * DemoData.class  - 创建excel对应的实体对象
         * sheetName - 工作表名称
         * data() - 数据部分
         */
        EasyExcel.write(response.getOutputStream(), DemoData.class).sheet(sheetName).doWrite(data());
    }
}

本地启动SpringBoot应用程序,因为没有在配置文件application.yml中配置端口,所以端口默认为8080
【EasyExcel】Excel操作(九):Excel读取写入一条龙
在浏览器输入:http://localhost:8080/excel/download
【EasyExcel】Excel操作(九):Excel读取写入一条龙
点开左下角的excel文件:
【EasyExcel】Excel操作(九):Excel读取写入一条龙
完美!!!

本文地址:https://blog.csdn.net/Qizhi_Hu/article/details/110748817