Easy Excel的使用说明

Easy Excel 的使用说明

可直接使用的测试demo,建议使用前后看一下官方文档

官方文档地址1:https://www.yuque.com/easyexcel/doc

官方文档地址2:https://alibaba-easyexcel.github.io/index.html

01 导入依赖

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

<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.18.20</version>
</dependency>

02 写excel文件

数据的实体类

@Data
@TableName("excel_user")
public class ExcelUser {
    @TableId(value = "id", type = IdType.AUTO)
    @ExcelIgnore
    private Long id;
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("年龄")
    private Integer age;
    @ExcelProperty("身高")
    private Double height;
}

写excel的方法

/**
 * 写excel文件
 * @param excelFile
 *            导出的文件路径(测试用绝对地址)
 * @param ignoreFiledNames
 *            忽略的字段
 * @param template
 *            数据模板(数据的class)
 * @param sheetName
 *            sheet名
 * @param data
 *            数据
 */
public static void writeExcel(String excelFile, Set<String> ignoreFiledNames, Class template, String sheetName,
                              List<?> data) {
    ExcelWriterBuilder builder = EasyExcel.write(excelFile, template);
    if (ignoreFiledNames != null) {
        builder.excludeColumnFiledNames(ignoreFiledNames);
    }
    builder.sheet(sheetName).doWrite(data);
}

03 文件的下载

controller接口

@GetMapping("/download")
public void download(String filename,HttpServletResponse response) {
    ExcelFileUtils.downLoadFile(response,filename);
}

下载的方法

 

/**
 * 下载文件
 *
 * @param response
 *            相应response
 * @param filePath
 *            文件路径
 */
public static void downLoadFile(HttpServletResponse response, String filePath) {
    if (StringUtils.isBlank(filePath)) {
        return;
    }
    File file = new File(filePath);
    if (!file.exists()) {
        return;
    }
    OutputStream out = null;
    try {
        response.reset();
        response.setContentType("application/octet-stream; charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
        out = response.getOutputStream();
        out.write(Files.readAllBytes(file.toPath()));
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

04 文件的上传

监听器

package com.saiyou.entity;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.saiyou.service.ExcelUserService;
import lombok.extern.slf4j.Slf4j;

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

/**
 * @author : lyn
 * 技术点 :
 * @description: excel 的监听器
 * @date : 2021/12/4 14:43
 */
@Slf4j
public class ExcelUserListener extends AnalysisEventListener<ExcelUser> {

    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    List<ExcelUser> list = new ArrayList<ExcelUser>();
    /**
     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */
    private ExcelUserService excelUserService;

    public ExcelUserListener(){}

    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param excelUserService
     */

    public ExcelUserListener(ExcelUserService excelUserService) {
        this.excelUserService = excelUserService;
    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(ExcelUser data, AnalysisContext context) {
        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", list.size());
        //调用service保存到数据库
        excelUserService.saveBatch(list);
        log.info("存储数据库成功!");
    }
}

controller接口

@Autowired
private ExcelUserService excelUserService;
/**
 * 文件上传
 * <p>1. 创建excel对应的实体对象 参照{@link ExcelUser}
 * <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,
 * <p>3. 直接读即可
 */
@PostMapping("/upload")
public String upload(MultipartFile file) throws IOException {
    EasyExcel.read(file.getInputStream(), ExcelUser.class, new ExcelUserListener(excelUserService)).sheet().doRead();
    return "success";
}

05 Postman的上传文件

 

需要自己补充service和mapper

0 工具类

package com.saiyou.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.saiyou.entity.ExcelUser;
import com.saiyou.entity.ExcelUserListener;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * @author : lyn
 * 技术点 :
 * @description: excel的读写,上传和下载
 * @date : 2021/12/4 13:50
 */
@Slf4j
public class ExcelFileUtils {

    /**
     * 写excel文件
     * @param excelFile
     *            导出的文件路径
     * @param ignoreFiledNames
     *            忽略的字段
     * @param template
     *            数据模板
     * @param sheetName
     *            sheet名
     * @param data
     *            数据
     */
    public static void writeExcel(String excelFile, Set<String> ignoreFiledNames, Class template, String sheetName,
                                  List<?> data) {
        ExcelWriterBuilder builder = EasyExcel.write(excelFile, template);
        if (ignoreFiledNames != null) {
            builder.excludeColumnFiledNames(ignoreFiledNames);
        }
        builder.sheet(sheetName).doWrite(data);
    }

    /**
     * 读取excel文件,不能通用吗?
     * @param fileName
     */
    public static void readExcel(String fileName) {

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(fileName, ExcelUser.class, new ExcelUserListener() ).sheet().doRead();
    }

    /**
     * 下载文件
     *
     * @param response
     *            相应response
     * @param filePath
     *            文件路径
     */
    public static void downLoadFile(HttpServletResponse response, String filePath) {
        if (StringUtils.isBlank(filePath)) {
            return;
        }
        File file = new File(filePath);
        if (!file.exists()) {
            return;
        }
        OutputStream out = null;
        try {
            response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
            out = response.getOutputStream();
            out.write(Files.readAllBytes(file.toPath()));
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        ExcelUser user = new ExcelUser();
        user.setName("李四");
        user.setAge(56);
        user.setHeight(126.6);
        writeExcel("D:/excel-test.xlsx",null,ExcelUser.class,"表一", Arrays.asList(user));
    }


}

 

 

 

 

 

posted @ 2021-12-04 17:31  进击的小蔡鸟  阅读(2052)  评论(0编辑  收藏  举报