EasyExcel实现多sheet文件分批导入

文章目录

  • EasyExcel
  • 引入依赖
  • 表结构
    • 学生表
    • 课程表
    • 教师表
  • 项目结构
    • DozerUtils工具类
    • 实体类
      • Student
      • Course
      • Teacher
    • Controller
    • 监听类
      • StudentListener
      • CourseListener
      • TeacherListener
    • Service
      • EasyExcelService
      • StudentService
      • CourseService
      • TeacherService
    • ServiceImpl
      • EasyExcelServiceImpl
      • StudentServiceImpl
      • CourseServiceImpl
      • TeacherServiceImpl
    • mapper
      • StudentMapper
      • CourseMapper
      • TeacherMapper
  • 启动项目
  • 测试
    • 测试数据
    • PostMan测试

EasyExcel

EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。
他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。

引入依赖

 	<dependency>
        <groupId>com.alibabagroupId>
        <artifactId>easyexcelartifactId>
        <version>3.1.3version> 
    dependency>

引入dozermapper依赖用于后续对象间类型转换

    <dependency>
        <groupId>com.github.dozermappergroupId>
        <artifactId>dozer-spring-boot-starterartifactId>
        <version>6.5.0version>
    dependency>

表结构

学生表

CREATE TABLE `student`  (
  `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '学生表ID',
  `sname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '学生姓名',
  `sno` bigint NOT NULL COMMENT '学号',
  `sex` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '性别',
  `age` int NOT NULL COMMENT '年龄',
  `is_deleted` tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除',
  PRIMARY KEY (`id`)
);

在这里插入图片描述

课程表

CREATE TABLE `course`  (
  `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '课程表ID',
  `cname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '课程名',
  `cno` bigint NOT NULL COMMENT '课程号',
  `tno` bigint NOT NULL COMMENT '任教教师编码',
  `is_deleted` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除',
  PRIMARY KEY (`id`)
);

EasyExcel实现多sheet文件分批导入_第1张图片

教师表

CREATE TABLE `teacher`  (
  `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '教师表ID',
  `tname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '教师姓名',
  `tno` bigint NOT NULL COMMENT '教师编号',
  `sex` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '性别',
  `age` int NOT NULL COMMENT '年龄',
  `is_deleted` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除',
  PRIMARY KEY (`id`)
);

在这里插入图片描述

项目结构

EasyExcel实现多sheet文件分批导入_第2张图片

DozerUtils工具类

public class DozerUtils {
    public static <T,S> List<T> mapList(final Mapper mapper, List<S> sourceList, Class<T> targetObjectClass){
        List<T> targetList=new ArrayList<T>();
        for(S s:sourceList){
            targetList.add(mapper.map(s,targetObjectClass));
        }
        return targetList;
    }
}

实体类

Student

@Data
public class Student {

    /**主键ID**/
    @ExcelIgnore
    private Long id;
    /**学生姓名**/
    @ExcelProperty(value = "姓名")
    private String sname;
    /**学号**/
    @ExcelProperty(value = "学号")
    private Long sno;
    /**性别**/
    @ExcelProperty(value = "性别")
    private String sex;
    /**年龄**/
    @ExcelProperty(value = "年龄")
    private Integer age;
    /**是否删除**/
    @ExcelIgnore
    private Integer isDeleted;

}

Course

@Data
public class Course {
    /**主键ID**/
    @ExcelIgnore
    private Long id;
    /**课程名**/
    @ExcelProperty(value = "课程名")
    private String cname;
    /**课程号**/
    @ExcelProperty(value = "课程号")
    private Long cno;
    /**任教教师编号**/
    @ExcelProperty(value = "任教教师编号")
    private Long tno;
    /**是否删除**/
    @ExcelIgnore
    private Integer isDeleted;
}

Teacher

@Data
public class Teacher {
    /**主键ID**/
    @ExcelIgnore
    private Long id;
    /**教师姓名**/
    @ExcelProperty(value = "姓名")
    private String tname;
    /**教师编号**/
    @ExcelProperty(value = "教师编号")
    private Long tno;
    /**性别**/
    @ExcelProperty(value = "性别")
    private String sex;
    /**年龄**/
    @ExcelProperty(value = "年龄")
    private Integer age;
    /**是否删除**/
    @ExcelIgnore
    private Integer isDeleted;
}

Controller

@RestController
@RequestMapping("/easyExcel")
public class EasyExcelController {

	@Resource
    private IEasyExcelService easyExcelService;

    @PostMapping("excelInput")
    public void excelInput(MultipartFile file){
        easyExcelService.excelInput(file);
    }

}

监听类

本次设置为1000条数据为一批导入,可根据实际情况调整为3000以内
本次导入未设置导入逻辑,如需设置逻辑,在监听类saveDate方法内调用按逻辑增加的service方法

StudentListener

public class StudentListener extends AnalysisEventListener<Student> {
    /**
     *单次缓存量为1000
     */
    private final int BATCH_SIZE = 1000;

    /**
     * 临时存储List
     */
    List<Student> cacheData = new ArrayList<Student>();
    private IStudentService studentService;
    private Mapper dozerMapper;

    public StudentListener(IStudentService studentService, Mapper dozerMapper){
        this.studentService = studentService;
        this.dozerMapper = dozerMapper;
    }
    @Override
    public void invoke(Student data, AnalysisContext analysisContext) {
        cacheData.add(data);
        if (cacheData.size() >= BATCH_SIZE){
            saveData();
            //每批存储完成后清空list
            cacheData.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (cacheData.size() > 0){
            saveData();
        }
    }

    /**
     * 加入数据库
     */
    private void saveData(){
        List<Student> students = DozerUtils.mapList(dozerMapper,cacheData,Student.class);
        studentService.saveBatch(students);
    }
}

CourseListener

public class CourseListener extends AnalysisEventListener<Course> {
    /**
     *单次缓存量为1000
     */
    private final int BATCH_SIZE = 1000;

    /**
     * 临时存储List
     */
    List<Course> cacheData = new ArrayList<Course>();
    private ICourseService courseService;
    private Mapper dozerMapper;

    public CourseListener(ICourseService courseService, Mapper dozerMapper){
        this.courseService = courseService;
        this.dozerMapper = dozerMapper;
    }
    @Override
    public void invoke(Course data, AnalysisContext analysisContext) {
        cacheData.add(data);
        if (cacheData.size() >= BATCH_SIZE){
            saveData();
            //每批存储完成后清空list
            cacheData.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (cacheData.size() > 0){
            saveData();
        }
    }

    /**
     * 加入数据库
     */
    private void saveData(){
        List<Course> courses = DozerUtils.mapList(dozerMapper,cacheData,Course.class);
        courseService.saveBatch(courses);
    }
}

TeacherListener

public class TeacherListener extends AnalysisEventListener<Teacher> {
    /**
     *单次缓存量为1000
     */
    private final int BATCH_SIZE = 1000;

    /**
     * 临时存储List
     */
    List<Teacher> cacheData = new ArrayList<Teacher>();
    private ITeacherService teacherService;
    private Mapper dozerMapper;

    public TeacherListener(ITeacherService teacherService, Mapper dozerMapper){
        this.teacherService = teacherService;
        this.dozerMapper = dozerMapper;
    }
    @Override
    public void invoke(Teacher data, AnalysisContext analysisContext) {
        cacheData.add(data);
        if (cacheData.size() >= BATCH_SIZE){
            saveData();
            //每批存储完成后清空list
            cacheData.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (cacheData.size() > 0){
            saveData();
        }
    }

    /**
     * 加入数据库
     */
    private void saveData(){
        List<Teacher> teachers = DozerUtils.mapList(dozerMapper,cacheData,Teacher.class);
        teacherService.saveBatch(teachers);
    }
}

Service

EasyExcelService

public interface IEasyExcelService {
    void excelInput(MultipartFile file);
}

StudentService

public interface IStudentService extends IService<Student> {
}

CourseService

public interface ICourseService extends IService<Course> {
}

TeacherService

public interface ITeacherService extends IService<Teacher> {
}

ServiceImpl

EasyExcelServiceImpl

@Service
public class EasyExcelServiceImpl implements IEasyExcelService {

    @Resource
    private ICourseService courseService;
    @Resource
    private ITeacherService teacherService;
    @Resource
    private IStudentService studentService;
    @Resource
    private Mapper dozerMapper;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void excelInput(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            ExcelReader excelReader = EasyExcel.read(inputStream).build();

            ReadSheet sheet = EasyExcel.readSheet("student").head(Student.class)
                    .registerReadListener(new StudentListener(studentService,dozerMapper))
                    .build();
            ReadSheet sheet1 = EasyExcel.readSheet("course").head(Course.class)
                    .registerReadListener(new CourseListener(courseService,dozerMapper))
                    .build();
            ReadSheet sheet2 = EasyExcel.readSheet("teacher").head(Teacher.class)
                    .registerReadListener(new TeacherListener(teacherService,dozerMapper))
                    .build();
            excelReader.read(sheet);
            excelReader.read(sheet1);
            excelReader.read(sheet2);
            excelReader.finish();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

StudentServiceImpl

@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {
}

CourseServiceImpl

@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
}

TeacherServiceImpl

@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> implements ITeacherService {
}

mapper

StudentMapper

public interface StudentMapper extends BaseMapper<Student> {
}

CourseMapper

public interface CourseMapper extends BaseMapper<Course> {
}

TeacherMapper

public interface TeacherMapper extends BaseMapper<Teacher> {
}

启动项目

EasyExcel实现多sheet文件分批导入_第3张图片

测试

测试数据

创建三个sheet测试文件,sheetming及各自内部列名均按照要求设置
EasyExcel实现多sheet文件分批导入_第4张图片
EasyExcel实现多sheet文件分批导入_第5张图片
EasyExcel实现多sheet文件分批导入_第6张图片

PostMan测试

form-data中设置格式为file
EasyExcel实现多sheet文件分批导入_第7张图片

选择需要上传的测试文件
EasyExcel实现多sheet文件分批导入_第8张图片
完成后查看数据库
EasyExcel实现多sheet文件分批导入_第9张图片
EasyExcel实现多sheet文件分批导入_第10张图片
EasyExcel实现多sheet文件分批导入_第11张图片

导入成功

你可能感兴趣的:(后端,java,数据库,springboot,后端)