Springboot——整合EasyExcel简单读写和文件上传下载

Springboot——整合EasyExcel简单读写和文件上传下载

Lewis
2022-04-20 / 0 评论 / 54 阅读 / 正在检测是否收录...
前面的项目一直用的是easypoi来进行excel的上传下载,最近发现阿里的EasyExcel更好用,在这里分享一下,具体的可以在官网探索。
官网入口: 点击进入

一、添加依赖

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

二、测试代码准备

首先需要编写一个 数据接收类excel对应类

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String id;
    private String name;
    private String realName;
    private String sexName;
}
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class UserExcel {
    // index 会影响excel数据排列顺序

    @ExcelProperty(value = "编号",index = 1)
    private String id;
    @ExcelProperty(value = "别名",index = 2)
    private String name;
    @ExcelProperty(value = "名称",index = 4)
    private String realName;
    @ExcelProperty(value = "性别",index = 3)
    private String sexName;
}

三、示例代码

3.1 写文件

将数据信息写入 Excel 中:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import pojo.StartApplication;
import pojo.User;
import pojo.UserExcel;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@SpringBootTest(classes= StartApplication.class)
@RunWith(SpringRunner.class)
public class TestDemo1 {
    private List<User> users = new ArrayList<>();

    @Before
    public void before(){
        users.add(new User("1","xj1","bunana","1"));
        users.add(new User("2","xj2","bunana","2"));
        users.add(new User("3","xj3","bunana","1"));
        users.add(new User("4","xj4","bunana","1"));
    }

    /**
     * 将数据写入excel
     * @throws Exception
     */
    @Test
    public void testWrite() throws Exception {
        File file = new File("/test/test_w.xlsx");
        // 针对文件路径,获取文件所在路径之上的路径信息
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        // 判断文件是否存在
        if(!file.exists()){
            file.createNewFile();
        }
       EasyExcel.write(file, UserExcel.class).sheet("test").doWrite(users);
    }
}

运行测试:
l26v8d0b.png

3.2 读文件

由于没有excel文件,所以先说的写操作。接下来将写的excel再解析出来。

@Test
public void testRead() throws Exception {
    File file = new File("/test/test_w.xlsx");
    // 针对文件路径,获取文件所在路径之上的路径信息
    if(!file.getParentFile().exists()){
        file.getParentFile().mkdirs();
    }
    // 判断文件是否存在
    if(!file.exists()){
        file.createNewFile();
    }
    InputStream inputStream = new FileInputStream(file);
    EasyExcel.read(inputStream,UserExcel.class,new AnalysisEventListener<UserExcel>(){

        // 解析每条数据时触发
        @Override
        public void invoke(UserExcel userExcel, AnalysisContext analysisContext) {
            // 如果是需要将数据解析存数据库,建议放集合中再存,不要有一条就存一次
            System.out.println(userExcel);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            //System.out.println(analysisContext);
        }
        // 获取表头数据信息
        @Override
        public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
            System.out.println(headMap);
        }
    }).sheet("test").doRead();
}

l26v9a0n.png

四、注意事项

4.1 监听器的区别

本次读操作,采取read(InputStream inputStream, Class head, ReadListener readListener),配置有数据对应映射处理类。
l26va61i.png
如果使用read(InputStream inputStream, ReadListener readListener)
l26vakdy.png
此时监听器invoke(Object 0, AnalysisContext analysisContext)中的Object 是一个linkedhashmap数据类型!

4.2 关于UserExcel映射类

  属性上增加注解@ExcelProperty可以对数据信息进行配置,这里需要强调一点,index值是从 0 开始算的!!
本次这里配置为:
l26vbave.png
则让生成excel文件出现前面空列的问题:
l26vbljc.png
其次index值,影响字段在excel表中的顺序!

五、关于web的上传和下载

  由于上面的读写操作,采取将数据流信息写入文件操作,如果涉及到文件的上传和下载操作,可以直接将流信息填充。如下测试案例所示。
示例代码:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

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

@Api(value = "EasyExcel文件上传和下载测试类")
@RestController
public class FileUploadAndDownController {

    @ApiOperation(value = "Excel文件上传数据解析",notes = "test2")
    @PostMapping("/upload")
    public void upload(MultipartFile file) throws IOException {
        ArrayList<UserExcel> userExcels = new ArrayList<>();
        EasyExcel.read(file.getInputStream(),UserExcel.class,new AnalysisEventListener<UserExcel>(){

            @Override
            public void invoke(UserExcel userExcel, AnalysisContext analysisContext) {
                System.out.println("解析数据:"+userExcel);
                userExcels.add(userExcel);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {

            }
        }).sheet("test").doRead();

        userExcels.forEach(e->{
            System.out.println("存数据库!");
            System.out.println(e);
        });
    }


    @ApiOperation(value = "Excel文件下载",notes = "test2")
    @GetMapping("download")
    public void download(HttpServletResponse response) throws Exception {
        List<User> users = new ArrayList<>();
        users.add(new User("1","xj1","bunana","1"));
        users.add(new User("2","xj2","bunana","2"));
        users.add(new User("3","xj3","bunana","1"));
        users.add(new User("4","xj4","bunana","1"));

        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        
        // 绕过了创建临时文件,直接将数据读到流中传递至客户端
        EasyExcel.write(response.getOutputStream(), UserExcel.class).sheet("test").doWrite(users);
    }
}

上传测试:
l26vd41u.png
l26vd7x1.png

下载测试:
链接:http://localhost/download
l26vdrgp.png
l26vdv1o.png

六、文件上传到七牛云

有时候我们需要将生成的文件永久性存储,放在服务器显然不合适,可以上传到七牛云。

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.bdysoft.cloud.OSSFactory;
import com.bdysoft.common.dto.UploadResultDto;

import java.io.ByteArrayOutputStream;
import java.util.List;

/**
 * EasyExcel生成文件并上传七牛云
 *
 * @author lvwei
 */
public class EasyExcelUploadUtil {

    public static UploadResultDto uploadExcel(Integer storeId, Class<?> obj, List<?> list, String sheetName) {
        //字节流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        EasyExcel.write(bos, obj)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet(sheetName)
                .doWrite(list);
        // 调用七牛云的上传方法,上传成功,七牛云会将地址返回
        UploadResultDto resultDto = OSSFactory.build(storeId).uploadSuffix(bos.toByteArray(), ExcelTypeEnum.XLSX.getValue());
        resultDto.setFileSize(Long.parseLong(bos.size() + ""));
        return resultDto;
    }
}
0

评论 (0)

取消