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`)
);
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`)
);
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;
}
}
@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;
}
@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;
}
@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;
}
@RestController
@RequestMapping("/easyExcel")
public class EasyExcelController {
@Resource
private IEasyExcelService easyExcelService;
@PostMapping("excelInput")
public void excelInput(MultipartFile file){
easyExcelService.excelInput(file);
}
}
本次设置为1000条数据为一批导入,可根据实际情况调整为3000以内
本次导入未设置导入逻辑,如需设置逻辑,在监听类saveDate方法内调用按逻辑增加的service方法
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);
}
}
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);
}
}
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);
}
}
public interface IEasyExcelService {
void excelInput(MultipartFile file);
}
public interface IStudentService extends IService<Student> {
}
public interface ICourseService extends IService<Course> {
}
public interface ITeacherService extends IService<Teacher> {
}
@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();
}
}
}
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {
}
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
}
@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> implements ITeacherService {
}
public interface StudentMapper extends BaseMapper<Student> {
}
public interface CourseMapper extends BaseMapper<Course> {
}
public interface TeacherMapper extends BaseMapper<Teacher> {
}
创建三个sheet测试文件,sheetming及各自内部列名均按照要求设置
导入成功