SpringBoot集成EasyExcel的应用场景分析

网友投稿 1124 2022-12-28

SpringBoot集成EasyExcel的应用场景分析

SpringBoot集成EasyExcel的应用场景分析

1、介绍

官网地址:https://yuque.com/easyexcel

特点:

1、java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是 非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或 者JVM频繁的full gc。

2、EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减 少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一 行行读取数据,逐个解析。

3、EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理 (AnalysisEventListener)。

2、应用场景

1、数据导入:减轻录入工作量

2、数据导出:统计信息归档

3、数据传输:异构系统之间数据传输

3、要实现的效果

sql

CREAWzqpqbnTE TABLE `edu_subject` (

`id` char(19) NOT NULL COMMENT '课程类别ID',

`title` varchar(10) NOT NULL COMMENT '类别名称',

`parent_id` char(19) NOT NULL DEFAULT '0' COMMENT '父ID',

`sort` int unsigned NOT NULL DEFAULT '0' COMMENT '排序字段',

`gmt_create` datetime NOT NULL COMMENT '创建时间',

`gmt_modified` datetime NOT NULL COMMENT '更新时间',

PRIMARY KEY (`id`),

KEY `idx_parent_id` (`parent_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=COMPACT COMMENT='课程科目';

转成->

3、使用

3.1、pom依赖导入

温馨提示:以下版本不能更换,换了可能会不行

com.alibaba

easyexcel

2.1.1

org.apache.poi

poi

3.17

org.apache.poi

poi-ooxml

3.17

3.2、controller

package com.zhz.serviceedu.controller;

import com.zhz.common.utils.R;

import com.zhz.serviceedu.service.EduSubjectService;

import io.swagger.annotations.Api;

import io.swagger.annotations.ApiOperation;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.CrossOrigin;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.multipart.MultipartFile;

/**

*

* 课程科目 前端控制器

*

*

* @author zhz

* @since 2021-07-03

*/

@RestController

@RequestMapping("/eduservice/subject")

@CrossOrigin

@Api(tags = "课程科目")

public class EduSubjectController {

@Autowired

private EduSubjectService eduSubjectService;

/**

* 添加课程分类,获取上传过来的文件,把文件内容读取出来

*/

@PostMapping("/addSubject")

@ApiOperation(value = "添加课程分类,获取上传过来的文件,把文件内容读取出来")

public R addSubject(MultipartFile file){

//上传过来的excel文件

eduSubjectService.saveSubject(file,eduSubjectService);

return R.ok();

}

}

3.3、interface

package com.zhz.serviceedu.service;

import com.zhz.serviceedu.entity.EduSubject;

import com.baomidou.mybatisplus.extension.service.IService;

import org.springframework.web.multipart.MultipartFile;

/**

*

* 课程科目 服务类

*

*

* @author zhz

* @since 2021-07-03

*/

public interface EduSubjectService extends IService {

/**

* 添加课程信息

*

* @author zhz

* @date 2021/07/02 02:18

* @param file 文件对象,用于获取excel文件

* @param eduSubjectService 方便-部分引用

*/

void saveSubject(MultipartFile file, EduSubjectService eduSubjectService);

}

3.4、impl

package com.zhz.serviceedu.service.impl;

import com.alibaba.excel.EasyExcel;

import com.zhz.serviceedu.entity.EduSubject;

import com.zhz.serviceedu.entity.excel.SubjectData;

import com.zhz.serviceedu.listener.SubjectExcelListener;

import com.zhz.serviceedu.mapper.EduSubjectMapper;

import com.zhz.serviceedu.service.EduSubjectService;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.springframework.stereotype.Service;

import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

/**

*

* 课程科目 服务实现类

*

*

* @author zhz

* @since 2021-07-03

*/

@Service

public class EduSubjectServiceImpl extends ServiceImpl implements EduSubjectService {

/**

* 添加课程信息

*

* @param file 文件对象,用于获取excel文件

* @param eduSubjectService

* @author zhz

* @date 2021/07/02 02:18

*/

@Override

public void saveSubject(MultipartFile file, EduSubjectService eduSubjectService) {

try {

//文件输入

InputStream in = file.getInputStream();

//调用方法进行读取

EasyExcel.read(in, SubjectData.class,new SubjectExcelListener(eduSubjectService)).sheet().doRead();

}catch (Exception e){

e.printStackTrace();

}

}

}

3.5、listener

package com.zhz.serviceedu.listener;

import com.alibaba.excel.context.AnalysisContext;

import com.alibaba.excel.event.AnalysisEventListener;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.zhz.servicebase.execptionhandler.GuliException;

import com.zhz.serviceedu.entity.EduSubject;

import com.zhz.serviceedu.entity.excel.SubjectData;

import com.zhz.serviceedu.service.EduSubjectService;

import lombok.extern.slf4j.Slf4j;

import org.springframework.util.StringUtils;

/**

* @author zhouhengzhe

* @Description: excel-

* @date 2021/7/3上午2:28

*/

@Slf4j

public class SubjectExcelListener extends AnalysisEventListener {

/**

* 创建有参数构造,传递subjectService用于操作数据库

* 因为SubjectExcelListener不能交给spring去管理,所以需要自己new,不能注入对象

* 此处一定要是public,不然永远获取不到对象

*/

public EduSubjectService eduSubjectService;

public SubjectExcelListener() {

}

public SubjectExcelListener(EduSubjectService eduSubjectService) {

this.eduSubjectService = eduSubjectService;

}

/**

* 读取excel内容,一行一行进行读取,此处全是业务处理

* @param subjectData

* @param analysisContext

*/

@Override

public void invoke(SubjectData subjectData, AnalysisContext analysisContext) {

log.info("进入方法调用");

if (StringUtils.isEmpty(subjectData)){

throw new GuliException(20001,"文件数据为空");

}

//一行一行去读取excel内容,每次读取有两个值,第一个值为一级分类,第二个值为二级分类

//判断一级分类是否重复

EduSubject existOneSubject = this.existOneSubject(eduSubjectService, subjectData.getOneSubjectName());

if (StringUtils.isEmpty(existOneSubject)){

existOneSubject=new EduSubject();

existOneSubject.setParentId("0");

//一级分类名称

existOneSubject.setTitle(subjectData.getOneSubjectName());

eduSubjectService.save(existOneSubject);

}

//获取一级分类的pid值

String pid=existOneSubject.getId();

//添加二级分类

// 判断二级分类是否重复

EduSubject existTwoSubject = this.existTwoSubject(eduSubjectService, subjectData.getTwoSubjectName(), pid);

if (StringUtils.isEmpty(existTwoSubject)){

existTwoSubject=new EduSubject();

existTwoSubject.setParentId(pid);

//二级分类名称

existTwoSubject.setTitle(subjectData.getTwoSubjectName());

eduSubjectService.save(existTwoSubject);

}

}

/**

* 读取完成后执行

*/

@Override

public void doAfterAllAnalysed(AnalysisContext analysisContext) {

}

/**

* 判断一级分类是否重复

* 因为课程的的parent_id为0时,代表是一级分类,并且一级分类数据不重复

* @param eduSubjectService

* @param name

* @return

*/

private EduSubject existOneSubject(EduSubjectService eduSubjectService,String name){

QueryWrapper wrapper=new QueryWrapper<>();

wrapper.eq("title",name);

wrapper.eq("parent_id","0");

EduSubject subject = eduSubjectService.getOne(wrapper);

return subject;

}

/**

* 判断二级分类是否重复

*

* @param eduSubjectService

* @param name

* @param pid

* @return

*/

private EduSubject existTwoSubject(EduSubjectService eduSubjectService,String name,String pid){

QueryWrapper wrapper=new QueryWrapper<>();

wrapper.eq("title",name);

wrapper.eq("parent_id",pid);

EduSubject eduSubject = eduSubjectService.getOne(wrapper);

return eduSubject;

}

}

3.6、小细节,实体类pojo

因为mybatisplus生成的实体类的主键生成策略是IdType.ID_WORKER,所以需要修改成IdType.ID_WORKER_STR,否则会有转换问题

package com.zhz.serviceedu.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;

import com.baomidou.mybatisplus.annotation.IdType;

import java.util.Date;

import com.baomidou.mybatisplus.annotation.TableField;

import com.baomidou.mybatisplus.annotation.TableId;

import java.io.Serializable;

import io.swagger.annotations.ApiModel;

import io.swagger.annotations.ApiModelProperty;

import lombok.Data;

import lombok.EqualsAndHashCode;

import lombok.experimental.Accessors;

/**

*

* 课程科目

*

*

* @author zhz

* @since 2021-07-03

*/

@Data

@EqualsAndHashCode(callSuper = false)

@Accessors(chain = true)

@ApiModel(value="EduSubject对象", description="课程科目")

public class EduSubject implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty(value = "课程类别ID")

@TableId(value = "id", type = IdType.ID_WORKER_STR)

private String id;

@ApiModelProperty(value = "类别名称")

private String title;

@ApiModelProperty(value = "父ID")

private String parentId;

@ApiModelProperty(value = "排序字段")

private Integer sort;

@ApiModelProperty(value = "创建时间")

@TableField(fill = FieldFill.INSERT)

private Date gmtCreate;

@ApiModelProperty(value = "更新时间")

@TableField(fill = FieldFill.INSERT_UPDATE)

private Date gmtModified;

}

3.7、其余,swagger集成,R类统一返回,统一日志等,请看我其他博客

统一日志:https://blog.csdn-/zhouhengzhe/article/details/118078080

统一返回值:https://blog.csdn-/zhouhengzhe/article/details/118065066

统一异常:https://blog.csdn-/zhouhengzhe/article/details/118064739

swagger集成:https://blog.csdn-/zhouhengzhe/article/details/118063779

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Elasticsearch 映射参数详解 fields
下一篇:组织部门一网通办(政务网一网通办)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~