EasyExcel专题 Excel 读取写入上传和下载

Posted Dream_it_possible!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EasyExcel专题 Excel 读取写入上传和下载相关的知识,希望对你有一定的参考价值。

一、将10万条数据从Excel读取出来

        读取支持多标题,我们只需要指定最后一行的标题的行号即可,例如上述excel标题的行号为1,因此需要设置headRowNumber为1。  

        定义User 类,使用User类映射excel单条记录, 使用ExcelProperty注解标注excel里的字段名称。

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

@Data
@ToString
public class User 

    @ExcelProperty("id")
    private String id;

    @ExcelProperty("用户名")
    private String userName;

    @ExcelProperty("地址")
    private String address;


FileUtil:

public class FileUtil 


    public static String getResourcePath() 
        return FileUtil.class.getResource("/").getPath();
    



执行读取,指定read方法的三个重要参数: file对象, 映射的pojo对象,读取监听器

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.read.listener.PageReadListener;
import lombok.Data;
import lombok.ToString;
import org.junit.Test;

import java.io.File;

public class ExcelReadWriteTest


    @Test
    public void readData() 
        File file = new File(FileUtil.getResourcePath() + "demo.xlsx");
        if (file.exists()) 
            long start = System.currentTimeMillis();
            EasyExcel.read(file, User.class, new PageReadListener<User>(dataList -> 
                for (User user : dataList) 
                    System.out.println(user);
                
            )).headRowNumber(1).sheet().doRead();
            System.out.println("总耗时:" + (System.currentTimeMillis() - start) / 1000 + " s");
        
    

检查第一条数据是否正确:

总耗时1S:

 二、将10万条数据写入到Excel

先看下写入的效果,单标题和多标题的区别。

1. 单标题

 2. 多标题

完整代码 

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ExcelReadWriteTest 


    @Test
    public void readData() 
        File file = new File(FileUtil.getResourcePath() + "demo.xlsx");
        if (file.exists()) 
            long start = System.currentTimeMillis();
            EasyExcel.read(file, User.class, new PageReadListener<User>(dataList -> 
                for (User user : dataList) 
                    System.out.println(user);
                
            )).headRowNumber(1).sheet().doRead();
            System.out.println("总耗时:" + (System.currentTimeMillis() - start) / 1000 + " s");
        
    

    @Test
    public void WriteData() throws IOException 
        File file = new File(FileUtil.getResourcePath() + "test01.xlsx");
        if (!file.exists()) 
            file.createNewFile();
        

        EasyExcel.write(file, User.class).head(head()).sheet("用户表").doWrite(() -> data());
    

    @Test
    public void WriteData0() throws IOException 
        File file = new File(FileUtil.getResourcePath() + "test02.xlsx");
        if (!file.exists()) 
            file.createNewFile();
        

        EasyExcel.write(file, User.class).head(manyHead()).sheet("用户表").doWrite(() -> data());
    

    //单行标题
    private List<List<String>> head() 
        List<List<String>> head = new ArrayList<>();
        head.add(Arrays.asList("id"));
        head.add(Arrays.asList("用户名"));
        head.add(Arrays.asList("地址"));
        return head;
    

    // 多行标题
    private List<List<String>> manyHead() 
        List<List<String>> head = new ArrayList<>();
        head.add(Arrays.asList("用户", "id"));
        head.add(Arrays.asList("用户", "用户名"));
        head.add(Arrays.asList("用户", "地址"));
        return head;
    

    private List<User> data() 
        List<User> userList = new ArrayList<>();

        for (int i = 0; i < 100000; i++) 
            User user = new User();
            user.setId(i + "");
            user.setUserName("zhangsan" + i);
            user.setAddress("shanghai" + i);
            userList.add(user);
        
        return userList;
    



三、上传和下载excel

可以新建一个SpringBoot工程,使用接口测试上传和下载功能。

1. 上传10万条数据

写要给upLoad接口,同时指定下excel里的标题所在行号。

   @PostMapping("/upLoad")
    public String uploadExcel(MultipartFile file, Integer headRowNumber) throws IOException 
        //指定headRowNumber
        EasyExcel.read(file.getInputStream(), User.class, new UploadListener(userService)).headRowNumber(headRowNumber).sheet().doRead();
        return "success";
    

指定一个上传监听器,用于文件的回调处理。

package com.example;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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


public class UploadListener implements ReadListener<User> 

    private static Logger logger = LoggerFactory.getLogger(UploadListener.class);


    private UserService userService;

    private List<User> cacheLists = new ArrayList<>(100);


    public UploadListener(UserService userService) 
        this.userService = userService;
    

    @Override
    public void invoke(User data, AnalysisContext context) 
        logger.info("解析到一条数据: ", JSON.toJSONString(data));
        cacheLists.add(data);
        if (cacheLists.size() > 100) 
            saveData();
            cacheLists = ListUtils.newArrayListWithExpectedSize(100);
        
    

    private void saveData() 
        logger.info("存储数据" + cacheLists.size() + "条!");
    

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) 
        if (CollectionUtils.isNotEmpty(cacheLists)) 
            saveData();
            logger.info("所有数据解析完成!");
        
    

用postman测试 

 查看第一条数据id为0, 说明上传正确。

2. 下载10万条数据

指定sheet名称,同时将URL用UTF-8编码,防止文件名导出出现乱码的情况。

    @PostMapping("/downLoad")
    public String downloadExcel(HttpServletResponse response) throws IOException 

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        // 如果指定了ExcelProperty,那么可以不用不用指定head,到处的excel仍然含有标题,如果想要多标题,那么就需要指定
        EasyExcel.write(response.getOutputStream(), User.class).sheet("用户表").doWrite(data());
        return "success";
    

用postman测试

 保存到本地,可以打开说明下载正确! 

代码地址: https://gitee.com/bingbing-123456/easyexcel_practice

如果链接打不开,可私信找我。

以上是关于EasyExcel专题 Excel 读取写入上传和下载的主要内容,如果未能解决你的问题,请参考以下文章

EasyExcel专题 Excel 读取写入上传和下载

01-使用EasyExcel读取和写入Excel文件

easy Excel是分片写入嘛

SpringBoot基于EasyExcel解析Excel实现文件导出导入读取写入

POI和EasyExcel

EasyExcel快速读写Excel数据