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

Springboot集成Easyexcel

程序员文章站 2024-03-21 13:06:40
...

java后端导入、导出excel,因此在此记录学习一下如何使用Springboot整合easyExcel。

JAVA解析Excel工具Easyexcel

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

pom

在pom文件中添加依赖

<!-- easyexcel相关依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>1.1.1</version>
        </dependency>

excel导出

(1)user实体类

//@Data是lombok的一个注解,加上它会自动生成getter、setter方法
@Data
public class User extends BaseRowModel {
    @ExcelProperty(value = "ID", index = 0)
    private String id;
    @ExcelProperty(value = "姓名", index = 1)
    private String name;
    @ExcelProperty(value = "年龄", index = 2)
    private Integer age;
}

(2)Usercontroller

@GetMapping("/user/excel")
    public void excelExport(HttpServletResponse response) throws IOException {
        userService.excelExport(response);
    }

(3)Userservice

//导出excle
    public void excelExport(HttpServletResponse response) throws IOException {
        ExcelWriter writer = null;
        // 文件输出位置
        OutputStream out = null;
        try {
            List<User> userList = userMapper.getAllUser();
            out = response.getOutputStream();
            writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
            String fileName = "用户信息表格";
            // 写仅有一个 Sheet 的 Excel 文件, 此场景较为通用
            Sheet sheet = new Sheet(1, 0, User.class);
            // 第一个 sheet 名称
            sheet.setSheetName("用户信息");
            // 写数据到 Writer 上下文中
            // 入参1: 数据库查询的数据list集合
            // 入参2: 要写入的目标 sheet
            writer.write(userList, sheet);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xlsx").getBytes(), "ISO8859-1"));
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                // 将上下文中的最终 outputStream 写入到指定文件中
                writer.finish();
            }
            if (out != null) {
                try {
                    // 关闭流
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

excel导入

(1)Usercontroller

//导入excle
    @PostMapping("/user/excelImport")
    public String excelImport(@RequestParam("file") MultipartFile file) throws IOException {
        userService.excelImport(file);
        return "success";
    }

(2)Userservice

//导入excle
    public void excelImport(MultipartFile file) throws IOException {
        if(!file.getOriginalFilename().equals("用户名单.xls") && !file.getOriginalFilename().equals("用户名单.xlsx") ){
            return;
        }
        InputStream inputStream = new BufferedInputStream(file.getInputStream());
        //实例化实现了AnalysisEventListener接口的类
        ExcelListener excelListener = new ExcelListener(userMapper);
        ExcelReader reader = new ExcelReader(inputStream,null,excelListener);
        //读取信息
        reader.read(new Sheet(1,1,User.class));
    }

(3)ExcelListener

public class ExcelListener extends AnalysisEventListener<User> {
    private List<User> datas = new ArrayList<>();
    private static final int BATCH_COUNT = 3000;
    private UserMapper userMapper;

    public ExcelListener(UserMapper userMapper){
        this.userMapper = userMapper;
    }

    @Override
    public void invoke(User user, AnalysisContext analysisContext) {
        //数据存储到datas,供批量处理,或后续自己业务逻辑处理。
        datas.add(user);
        //达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if(datas.size() >= BATCH_COUNT){
            saveData();
            // 存储完成清理datas
            datas.clear();
        }
    }

    private void saveData() {
        for(User user : datas){
            userMapper.insert(user);
        }
    }

    public List<User> getDatas() {
        return datas;
    }

    public void setDatas(List<User> datas) {
        this.datas = datas;
    }

    /**
     * 所有数据解析完成了 都会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();//确保所有数据都能入库
    }
}

参考链接:https://blog.csdn.net/Felix_ar/article/details/103480950

相关标签: Easyexcel