EasyExcel实现多sheet文件分批导入

news2024/11/17 1:52:11

文章目录

  • 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.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.1.3</version> 
    </dependency>

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

    <dependency>
        <groupId>com.github.dozermapper</groupId>
        <artifactId>dozer-spring-boot-starter</artifactId>
        <version>6.5.0</version>
    </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`)
);

在这里插入图片描述

教师表

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`)
);

在这里插入图片描述

项目结构

在这里插入图片描述

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> {
}

启动项目

在这里插入图片描述

测试

测试数据

创建三个sheet测试文件,sheetming及各自内部列名均按照要求设置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

PostMan测试

form-data中设置格式为file
在这里插入图片描述

选择需要上传的测试文件
在这里插入图片描述
完成后查看数据库
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

导入成功

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/920812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

入行嵌入式,未来能干啥?

嵌入式技术近些年来发展迅猛&#xff0c;已经广泛应用于各个领域。那么&#xff0c;如果选择入行嵌入式&#xff0c;未来能够从事哪些有趣且有前景的工作呢&#xff1f; 1. 智能家居领域 随着物联网技术的快速发展&#xff0c;智能家居成为了人们追求便利和舒适的新时尚。作为嵌…

LeetCode 1267. 统计参与通信的服务器

【LetMeFly】1267.统计参与通信的服务器 力扣题目链接&#xff1a;https://leetcode.cn/problems/count-servers-that-communicate/ 这里有一幅服务器分布图&#xff0c;服务器的位置标识在 m * n 的整数矩阵网格 grid 中&#xff0c;1 表示单元格上有服务器&#xff0c;0 表…

<kernel>kernel 6.4 USB-之-usb_new_device()分析

&#xff1c;kernel&#xff1e;kernel 6.4 USB-之-usb_new_device()分析 kernel 6.4 USB系列文章如下&#xff1a; &#xff1c;kernel&#xff1e;kernel 6.4 USB-之-hub_event()分析 &#xff1c;kernel&#xff1e;kernel 6.4 USB-之-port_event()分析 &#xff1c;kernel…

​直播预告丨特邀中国人寿Soul专家分享APP合规与稳定性治理经验

由软件绿色联盟主办的月度技术活动将于7月28日19点进行线上直播。本次直播以“APP安全合规与稳定性治理”为主题&#xff0c;特邀中国人寿、Soul的专家&#xff0c;分别为大家带来《中国人寿寿险APP合规之路经验分享》、《Soul Android 端稳定性治理》议题直播。赶紧预约↑吧&a…

JAVA JNA 调用C接口的三种方式

文章目录 1. 准备一个共享库文件2. JNA姿势1—继承Library接口3. JNA姿势2—直接NativeLibrary.getInstance3. JNA姿势3—Native方法 1. 准备一个共享库文件 test.c #include <stdio.h> int test(char *input){printf("input:%s\n",input);return 0; }libtes…

智能离子风棒联网监控静电消除器的主要特点和功能

智能离子风棒联网监控静电消除器是一种利用互联网技术实现远程监测和控制的设备。它可以通过传感器感知静电水平&#xff0c;并将数据传输到云端服务器进行处理和存储。用户可以通过手机、电脑等终端设备&#xff0c;通过互联网接入平台&#xff0c;实时查看静电水平、工作状态…

EasyExcel实现Excel导出

文章目录 EasyExcel引入依赖项目结构导出模板类ControllerServiceServiceImplmapper 启动项目PostMan测试 EasyExcel EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。 他能让你在不用考虑性能、内存的等因素的情况下&#xff0c;快速完成Excel的…

SQL 数据库

安装配置 【1】 MySQL安装配置教程&#xff08;超级详细、保姆级&#xff09; 【2】 MySQLNavicat安装配置教程&#xff08;超级详细、保姆级&#xff09; 学习资料 【戴师兄】SQL入门免费教程 刷题链接&#xff1a;https://share.mubu.com/doc/4BHMMbbvIMb 学习笔记&#xf…

【无标题】CloudOS:物联网开发平台,云上开发,边端交付

什么是物联网&#xff1f; 物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;是指通过各种信息传感器、射频识别技术、全球定位系统、红外感应器、激光扫描器等各种装置与技术&#xff0c;实时采集任何需要监控、 连接、互动的物体或过程&#xff0c;采集…

RFID数据采集设备怎么选择?

RFID技术具有非接触识别的特性&#xff0c;可对贴有RFID标签的物体进行远距离非接触的批量识别&#xff0c;也是当下发展成熟的数据采集技术之一。RFID数据采集设备可对标签信息进行处理&#xff0c;并将读取到的标签信息传输到上位机中&#xff0c;针对不同的应用场景&#xf…

Linux系统root用户使用mv命令移动“/“根目录所有文件恢复方法

在使用mv命令对文件进行移动时&#xff0c;由于操作失误移动了根目录&#xff0c;导致除了cd命令&#xff0c;其他命令都无法使用。此时可以使用./ tab键查看当前目录下的文件此时无法再通过mv命令移动回去&#xff0c;因为执行mv命令的脚本ld-linux-x86-64.so.2找不到了。 正…

代码实现判断程序是32位还是64位

nuget 引入 Vanara.PInvoke.Kernel32 测试程序&#xff1a; using Vanara.PInvoke;var isExe Kernel32.GetBinaryType("C:\Windows\notepad.exe", out var type); if (!isExe) {return; } Console.WriteLine(type); // SCS_64BIT_BINARY如果是 32 位程序&#xff0…

学习JAVA打卡第三十六天

应用举例 例子&#xff1a;熟悉带finally子语句的try-catch语句&#xff0c;语句格式如下&#xff1a; 其执行机制是&#xff1a;在执行try-catch语句后执行finally语句&#xff0c;也就是说无论在try部分是否发生异常finally语句都会被执行。 但需要注意以下两种特殊情况&am…

Python“牵手”速卖通商品详情API接口运用场景及功能介绍

速卖通电商API接口是针对速卖通提供的电商服务平台&#xff0c;为开发人员提供了简单、可靠的技术来与速卖通电商平台进行数据交互&#xff0c;实现一系列开发、管理和营销等操作。其中包括商品详情API接口&#xff0c;通过这个API接口商家可以获取商品的详细信息&#xff0c;包…

【C++】C++11中比较重要的内容介绍

C11 前言正式开始统一的初始化列表{ }初始化对象{ }为容器初始化赋值运算符重载也支持{} 声明autodecltypenullptr STL中一些变化arrayforward_listunordered_map 和 unordered_set 右值引用表达式左值和右值左值右值 右值引用的使用场景移动构造和移动赋值重载右值分类移动构造…

使用 OpenTelemetry 构建可观测性 05 - 传播和行李(Propagation Baggage)

我们开发的应用程序可能具有不同的形态和架构&#xff1a;有些是单体应用&#xff0c;有些是微服务。为单体应用程序添加遥测数据相对来说简单&#xff0c;因为所有数据都在同一进程中。然而对于微服务应用程序&#xff0c;情况可能会更具挑战性。 通常&#xff0c;分布式微服…

C++信息学奥赛1135:配对碱基链

#include <iostream> #include <string> using namespace std;int main() {string arr;cin >> arr; // 输入字符串for (int i 0; i < arr.length(); i) {if (arr[i] A) {cout << "T"; // 如果当前字符是A&#xff0c;则输出T}else if…

PPPoE vs 静态:网络中的最佳选择

在企业网络中&#xff0c;选择适合的网络连接方式对于网络性能和安全至关重要。今天我将和大家分享关于PPPoE和静态IP地址的知识&#xff0c;探讨它们在企业网络中的优劣和最佳选择。本文将为您提供详细的分析和解决方案&#xff0c;帮助您在选择网络连接方式时做出明智的决策。…

【论文阅读】自动驾驶安全的研究现状与挑战

文章目录 摘要1.引言1.1.自动驾驶安全1.2.攻击面1.3.内容和路线图 2.自动驾驶技术2.1.组成2.2.技术 3.传感器安全3.1.照相机3.2.GNSS&#xff08;全球导航系统&#xff09;/IMU&#xff08;惯性测量单元&#xff09;3.3.超声波传感器3.4.毫米波雷达3.5.激光雷达3.6.多传感器交叉…

psycopg2 使用dbutils 工具封装

1.什么是dbutils Dbutils是一套工具&#xff0c;可为数据库提供可靠&#xff0c;持久和汇总的连接&#xff0c;该连接可在各种多线程环境中使用。 2.使用代码记录 db_config.py 数据库配置类&#xff1a; # -*- coding: UTF-8 -*- import psycopg2# 数据库信息 DB_TEST_HO…