SpringBoot集成EasyExcel的应用场景分析
1、介绍
官网地址:https://www.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
CREATE 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依赖导入
温馨提示:以下版本不能更换,换了可能会不行
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.1</version>
</dependency>
<!--xls-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
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;
@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;
public interface EduSubjectService extends IService<EduSubject> {
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;
@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {
@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;
@Slf4j
public class SubjectExcelListener extends AnalysisEventListener<SubjectData> {
public EduSubjectService eduSubjectService;
public SubjectExcelListener() {
}
public SubjectExcelListener(EduSubjectService eduSubjectService) {
this.eduSubjectService = eduSubjectService;
}
@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) {
}
private EduSubject existOneSubject(EduSubjectService eduSubjectService,String name){
QueryWrapper<EduSubject> wrapper=new QueryWrapper<>();
wrapper.eq("title",name);
wrapper.eq("parent_id","0");
EduSubject subject = eduSubjectService.getOne(wrapper);
return subject;
}
private EduSubject existTwoSubject(EduSubjectService eduSubjectService,String name,String pid){
QueryWrapper<EduSubject> 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;
@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.net/zhouhengzhe/article/details/118078080
统一返回值:https://blog.csdn.net/zhouhengzhe/article/details/118065066
统一异常:https://blog.csdn.net/zhouhengzhe/article/details/118064739
swagger集成:https://blog.csdn.net/zhouhengzhe/article/details/118063779
到此这篇关于SpringBoot集成EasyExcel的应用场景的文章就介绍到这了,更多相关SpringBoot集成EasyExcel内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341