使用easy excel进行简单的导入导出表格

1. 创建项目,导入easy excel的依赖

<!--  easy excel 依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.0.5</version>
</dependency>

<!-- mybatis 依赖 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.7</version>
</dependency>

<!-- lombok依赖 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.0</version>
    <scope>provided</scope>
</dependency>

<!--mybatis-plus 依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
</dependency>

2. 配值application.yml文件

server:
  port: 8081

# 配置数据库连接
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/portdemo?serverTimezone=UTC&characterEncoding=utf-8
    username: root
    password: 123456
  application:
    name: demoExport
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 配置mybatis-plus 打印控制台日志

3.创建数据库表实体

/**
 * @Description 用户表对应实体
 * @Author small Geng
 * @Data 2022/11/17 12:59
 */
@Data
@TableName("sys_user")
@ContentRowHeight(18)//内容行高
@HeadRowHeight(25)//标题行高
@ColumnWidth(20)//列宽,可设置成员变量上
public class User {

    @ExcelProperty(index = 0, value = "申请人ID")
    private Integer userId;

    @ExcelProperty(index = 1, value = "申请人姓名")
    private String userName;

    @ExcelProperty(index = 2, value = "申请人身份证号")
    private String userCard;

    @ExcelProperty(index = 3, value = "申请人班级")
    private String userClass;

    @ExcelProperty(index = 4, value = "申请人邮箱")
    private String userMail;

}

4. 业务逻辑

4.1 导出excel
/**
* 导出excel
* @param response
*/
@GetMapping("downLoad")
public void downLoad(HttpServletResponse response) throws IOException {

    List<User> users = exportService.list();

    exportService.downLoad(response, users);

}

// serviceImpl实现
@Override
public void downLoad(HttpServletResponse response, List<User> users) throws IOException {
    // 设置响应内容
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    // 设置编码格式
    response.setCharacterEncoding("UTF-8");
    //设置文件名
    String fileName = URLEncoder.encode("userExcel", "UTF-8").replaceAll("\\+", "%20");
    //设置响应头
    response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    //获取写出流
    ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), User.class).build();
    // 创建sheet
    WriteSheet writeSheet = EasyExcel.writerSheet("学生记录").build();
    // 读出
    excelWriter.write(users, writeSheet);
    // 关闭流
    excelWriter.finish();

}
4.2 导入excel
/**
* 导入excel
* @param response
*/
@PostMapping("upload")
public String upload(@RequestPart("file")MultipartFile file) throws IOException {
    exportService.upload(file);
    return "success";
}

// serviceImpl 实现
@Override
public void upload(MultipartFile file) throws IOException {
    // 读取excel
    ExcelReader reader = EasyExcel.read(file.getInputStream(), User.class,
                                        new ExportListener(exportMapper)).build();
    ReadSheet sheet = EasyExcel.readSheet(0).build();// 读取第一个sheet
    // 读取
    reader.read(sheet);
    // 关闭流
    reader.finish();
}
4.3 工具类 ExportListener
/**
 * @Description 导入excel的监听器
 * @Author small Geng
 * @Data 2022/11/17 14:03
 */
@Slf4j
public class ExportListener extends AnalysisEventListener<User> {

    // 每隔一百条数据存储数据库 然后清理list 方便内存回收
    private static final int BATCH_COUNT = 100;
    // 缓存的数据
    private List<User> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    private ExportMapper exportMapper;

    public ExportListener(ExportMapper exportMapper) {
        this.exportMapper = exportMapper;
    }

    // 每解析一条数据都会进行调用
    @Override
    public void invoke(User user, AnalysisContext context) {
        log.info("解析到一条数据:{}", JSON.toJSONString(user));
        // 将解析的数据添加到缓存集合中
        user.setUserId(null);
        cachedDataList.add(user);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
            // 向数据库中插入数据
            exportMapper.insert(user);
            // 清理一次list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 所有数据解析完成之后就会调用该方法
     * 防止出现数据量没有达到BATCH_COUNT条的时候,依然进行数据库插入操作
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 数据保存到数据库中
        saveData();
        log.info("所有数据解析完成,进入doAfterAllAnalysed方法");
    }

    /**
     * 保存数据
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库...", cachedDataList.size());
        for (User user : cachedDataList) {
            exportMapper.insert(user);
        }
        log.info("存储数据完成!!");
    }
}
posted @ 2022-11-21 18:43  莫离欢  阅读(180)  评论(0编辑  收藏  举报