使用EasyExcel实现导入导出功能

一、导出

1.使用ideal新建一个maven项目,并在pom.xml文件中引入EasyExcel依赖

<!--easyexcel实现导入导出-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>

2.新建数据库mybatis,并创建用户表user,如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lc9n7t40-1656483454988)(E:\Desktop\笔记\使用EasyExcel实现导入导出功能\image-20220629111613277.png)]

3.新建实体类User,代码如下:

package com.example.demo.pojo;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/*
*
* 加了@Data注解的类,编译后会自动给我们加上下列方法:
    所有属性的get和set方法
    toString 方法
    hashCode方法
    equals方法
*
* @AllArgsConstructor :有参构造方法
* @NoArgsConstructor :无参构造方法
* */
@Data
@AllArgsConstructor
@NoArgsConstructor
@ContentRowHeight(18)//内容行高
@HeadRowHeight(25)//标题行高
@ColumnWidth(20)//列宽,可设置成员变量上
public class User implements Serializable {
    //index表示第几列(从0开始,表示第一列),value表示标题(表头)
    @ExcelProperty(value = "用户id",index = 0)
    private Integer id;

    @ExcelProperty(value = "用户名",index = 1)
    private String name;

    @ExcelProperty(value = "用户密码",index = 2)
    private String pwd;

    @ExcelProperty(value = "用户介绍",index = 3)
    private String userIntroduce;
}

4.新建controller接口,实现导出功能,代码如下:

/**
     * 导出本地用户userId与聚力对应userId
     * @return 是否导出成功
     * @throws Exception
     */
@GetMapping("/exportJuLiData")
@ResponseBody
public void exportJuLiData(HttpServletResponse response) throws Exception
{
    String operName = "fengzihao"; // 操作人
    userService.exportJuLiData(response, operName);
}

5.具体的实现代码如下:

/**
     * 导出
     * @param response
     * @param operName 操作人
     * @return 是否成功
     * @throws IOException
     */
@Override
public void exportJuLiData(HttpServletResponse response, String operName) throws IOException {
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); //设置响应内容类型
    response.setCharacterEncoding("utf-8");//编码
    // 设置文件名, ps:把字符串中所有的'+'替换成'%20',在URL中%20代表空格
    String fileName = URLEncoder.encode("用户表", "UTF-8").replaceAll("\\+", "%20");
    response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");//设置响应头

    List<User> applicantByPage = userService.listUser();// 获取全部用户数据
    ExcelWriter writer = EasyExcel.write(response.getOutputStream(), User.class).build();//获取写出流
    WriteSheet sheet = EasyExcel.writerSheet("用户").build();//创建表格,设置表格页名称
    writer.write(applicantByPage, sheet);//读出
    writer.finish();//关闭流
}

6.之后启动项目,在浏览器中输入地址即可导出数据到excel,导出的excel如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RYgMcypu-1656483454990)(E:\Desktop\笔记\使用EasyExcel实现导入导出功能\image-20220629113039544.png)]

二、导入

1.在controller添加导入接口,代码如下:

/**
     * 导入本地用户userId与聚力对应userId
     * @param file 导入文件
     * @param updateSupport 是否更新支持,如果已存在,则进行更新数据
     * @return 是否导入成功
     * @throws Exception
     */
@PostMapping("/importJuLiData")
@ResponseBody
public Boolean importJuLiData(@RequestParam MultipartFile file, @RequestParam boolean updateSupport) throws Exception
{
    String operName = "fengzihao"; // 操作人
    Boolean flag = userService.importJuLiData(file, updateSupport, operName);
    return flag;
}

2.具体的实现,代码如下:

/**
     * 导入
     * @param file 导入文件
     * @param updateSupport 是否更新支持,如果已存在,则进行更新数据
     * @param operName 操作人
     * @return 是否成功
     * @throws IOException
     */
@Override
public Boolean importJuLiData(MultipartFile file, boolean updateSupport, String operName) throws IOException {
    UserListener excelListener = new UserListener(userService, updateSupport, operName);
    // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
    //EasyExcel.read(哪个文件).sheet(那张sheet表).head(表头什么样子).headRowNumber(表头占几行).registerReadListener(处理数据的监听器类).doRead()
    EasyExcel.read(file.getInputStream(), User.class, excelListener).sheet(0).head(User.class).headRowNumber(1).doRead();
    System.out.println(excelListener.getSet_fail());
    System.out.println(excelListener.getSuccess());
    System.out.println(excelListener.getFail());
    return true;
}

需要注意的是,这里我们使用到了监听器UserListener,用来读取excel中的数据并保存到数据库,具体的监听器代码如下:

package com.example.demo.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.example.demo.pojo.User;
import com.example.demo.service.UserService;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@SuppressWarnings("ALL")
@Component
@Scope("prototype")	// 作者要求每次读取都要使用新的Listener
public class UserListener extends AnalysisEventListener<User> {
    private UserService userService;
    private Boolean updateSupport;
    private String operName;

    private Set<User> juliSet_fail = new HashSet<>(); // 插入失败的数据
    private int success = 0; // 统计插入成功的条数
    private int fail = 0; // 统计插入失败的条数

    // 获取插入失败的数据
    public Set<User> getSet_fail(){
        return juliSet_fail;
    }

    // 获取插入成功的条数
    public int getSuccess(){
        return success;
    }

    // 获取插入失败的条数
    public int getFail(){
        return fail;
    }

    /**
     *
     * @param userService
     * @param updateSupport 是否更新支持,如果已存在,则进行更新数据
     * @param operName 操作人
     */
    public UserListener(UserService userService, Boolean updateSupport, String operName){
        this.userService = userService;
        this.updateSupport = updateSupport;
        this.operName = operName;
    }


    /**
     * 读的时候,每读取excel一行记录就会调用监听器的invoke()方法
     * @param user
     * @param analysisContext
     */
    @Override
    public void invoke(User user, AnalysisContext analysisContext) {
        System.out.println("读的时候,每读取excel一行记录就会调用监听器的invoke()方法");
        User user_new = userService.queryUserById(user.getId());
        if (updateSupport){ // 更新支持,如果已存在,则进行更新数据
            if (user_new != null){ // 如果要插入的数据已存在
                boolean update = userService.updateUser(user);
                if (update){
                    ++success;
                }else {
                    juliSet_fail.add(user);
                    ++fail;
                }
            }else { // 如果要插入的数据不存在
                boolean save = userService.addUser(user);
                if (save){ // 插入成功
                    ++ success;
                }else {// 插入失败
                    juliSet_fail.add(user);
                    ++fail;
                }
            }
        }else {
            if (user_new != null) { // 如果要插入的数据已存在
                juliSet_fail.add(user_new);
            }else {
                boolean save = userService.addUser(user);
                if (save) {// 插入成功
                    ++success;
                } else {// 插入失败
                    juliSet_fail.add(user);
                    ++fail;
                }
            }
        }

    }

    /**
     * 整个过程结束后执行该方法
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        System.out.println("整个过程结束后执行该方法");
    }


    /**
     * 读取excel表头信息
     * @param headMap
     * @param context
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        System.out.println("表头信息"+headMap);
    }
}

3.启动项目,使用postman进行测试,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sgo4aAOS-1656483454991)(E:\Desktop\笔记\使用EasyExcel实现导入导出功能\image-20220629140509068.png)]

三、源码获取

至此,我们的使用EasyExcel实现导入导出就讲解完成了。源码和数据库文件可以通过关注我的微信公众号我爱学习呀嘻嘻 ,回复关键字EasyExcel实现导入导出进行获取哦。

image-20211108230322493

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐