SpringBoot怎么整合EasyExcel
这篇文章主要介绍“SpringBoot怎么整合EasyExcel”,在日常操作中,相信很多人在SpringBoot怎么整合EasyExcel问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringBoot怎么整合EasyExcel”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
为什么要用EasyExcel
由于apache poi和jxl,excelPOI都有一个严重的问题,就是非常消耗内存,特别处理数据量多时,速度慢并且时有异常发生,所以改用由阿里研发的easyExcel更可靠一些,它的官方建议对于1000行以内的采用原来poi的写法一次读写,但于1000行以上的数据,有用了一行行进行解析的方案,这样避免了内存的溢出。
1.EasyExcel简介
Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或 者JVM频繁的full gc。
EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一 行行读取数据,逐个解析。
EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理 (AnalysisEventListener)
2.使用EasyExcel实现写
2.1 创建实体类
创建与Excel对应的实体类
@Datapublic class DemoData { //设置excel表头名称,index表示对应的第几列 @ExcelProperty(value = "学生编号",index = 0) private Integer sno; @ExcelProperty(value = "学生姓名",index = 1) private String sname;}
ExcelProperty:指定当前字段对应excel中的那一列。可以根据名字或者Index去匹配。当然也可以不写,默认第一个字段就是index=0,以此类推。
2.2 测试写Excel
public class TestWriteExcel { public static void main(String[] args) { //实现excel写的操作 //1.设置写入文件夹的地址和excel文件名称 String fileName = "D:\\write.xlsx"; //2.调用easyexcel里面方法实现写操作 //传入:文件存放的路径+对应的实体类class EasyExcel.write(fileName, DemoData.class).sheet("学生列表").doWrite(getData()); } //创建方法返回list集合(测试数据) private static List<DemoData> getData() { List<DemoData> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { DemoData data = new DemoData(); data.setSno(i); data.setSname("lucy" + i); list.add(data); } return list; }}
结果如下
3.使用EasyExcel实现读
3.1 创建读取操作的监听器
public class ExcelListener extends AnalysisEventListener<DemoData> { @Override public void invoke(DemoData data, AnalysisContext analysisContext) { System.out.println("****" + data); } @Override public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { System.out.println("表头:"+headMap); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { }}
3.2 测试读Excel
public class TestReadExcel { public static void main(String[] args) { //读取文件的路径 String fileName = "D:\\write.xlsx"; //传入三个参数:文件路径+封装的类的class+监听器 EasyExcel.read(fileName, DemoData.class,new ExcelListener()) .sheet() .doRead(); }}
控制台输出如下
4.springboot项目实践EasyExcel
通过在后台管理上传excel文件添加课程分类(一共两级分类)
4.1 pom中引入相关依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.0.5</version></dependency>
4.2 创建数据库表及添加数据
这里创建一个课程表用EasyExcel实现课程的分类
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(10) 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 ROW_FORMAT=COMPACT COMMENT='课程科目';
INSERT INTO `edu_subject` VALUES ('1178214681118568449','后端开发','0',1,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681139539969','Java','1178214681118568449',1,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681181483010','前端开发','0',3,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681210843137','JavaScript','1178214681181483010',4,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681231814658','云计算','0',5,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681252786178','Docker','1178214681231814658',5,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681294729217','Linux','1178214681231814658',6,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681324089345','系统/运维','0',7,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681353449473','Linux','1178214681324089345',7,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681382809602','Windows','1178214681324089345',8,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681399586817','数据库','0',9,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681428946945','MySQL','1178214681399586817',9,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681454112770','MongoDB','1178214681399586817',10,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681483472898','大数据','0',11,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681504444418','Hadoop','1178214681483472898',11,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681529610242','Spark','1178214681483472898',12,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681554776066','人工智能','0',13,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681584136193','Python','1178214681554776066',13,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681613496321','编程语言','0',14,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681626079234','Java','1178214681613496321',14,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178585108407984130','Python','1178214681118568449',2,'2019-09-30 16:19:22','2019-09-30 16:19:22'),('1178585108454121473','HTML/CSS','1178214681181483010',3,'2019-09-30 16:19:22','2019-09-30 16:19:22');
4.3 实体类
@Datapublic class SubjectData { @ExcelProperty(index = 0) private String oneSubjectName; @ExcelProperty(index = 1) private String twoSubjectName;}
@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;}
4.4 Controller层
@Autowiredprivate EduSubjectService subjectService;//添加课程分类//获取前端上传过来的excel文件,把文件内容读取出来保存到数据库@PostMapping("addSubject")public R addSubject(MultipartFile file){ subjectService.saveSubject(file,subjectService); return R.ok();}
4.5 Service层
//添加课程分类@Overridepublic void saveSubject(MultipartFile file, EduSubjectService subjectService) { try { //得到文件的输入流 InputStream in = file.getInputStream(); //调用方法进行读取 EasyExcel.read(in, SubjectData.class, new SubjectExcelListener(subjectService)).sheet().doRead(); } catch (Exception e) { e.printStackTrace(); }}
4.6 创建监听器(核心部分)
@Componentpublic class SubjectExcelListener extends AnalysisEventListener<SubjectData> { public EduSubjectService subjectService; public SubjectExcelListener(EduSubjectService subjectService) { this.subjectService = subjectService; } public SubjectExcelListener() { } //读取excel内容,一行一行读取 @Override public void invoke(SubjectData subjectData, AnalysisContext analysisContext) { if (subjectData == null) { throw new GuliException(20001, "文件数据为空"); } //一行一行读取,第一个值为一级分类,第二个值为二级分类 //先判断一级分类是否重复 EduSubject existOneSubject = this.existOneSubject(subjectData.getOneSubjectName(), subjectService); //没有相同的一级分类 if(existOneSubject==null){ existOneSubject=new EduSubject(); existOneSubject.setParentId("0"); existOneSubject.setTitle(subjectData.getOneSubjectName()); subjectService.save(existOneSubject); } //获取一级分类的id值 String pid=existOneSubject.getId(); //判断二级分类是否重复 EduSubject existTwoSubject = this.existTwoSubject(subjectData.getTwoSubjectName(), subjectService, pid); if(existTwoSubject==null){ existTwoSubject=new EduSubject(); existTwoSubject.setParentId(pid); existTwoSubject.setTitle(subjectData.getTwoSubjectName()); subjectService.save(existTwoSubject); } } //判断一级分类不能重复添加 private EduSubject existOneSubject(String name, EduSubjectService subjectService) { LambdaQueryWrapper<EduSubject> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(EduSubject::getTitle, name) .eq(EduSubject::getParentId, "0"); EduSubject oneSubject = subjectService.getOne(queryWrapper); return oneSubject; } //判断二级分类不能重复添加 private EduSubject existTwoSubject(String name, EduSubjectService subjectService,String pid) { LambdaQueryWrapper<EduSubject> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(EduSubject::getTitle, name) .eq(EduSubject::getParentId, pid); EduSubject twoSubject = subjectService.getOne(queryWrapper); return twoSubject; } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { }}
4.7 结果展示
Excel模板如下
上传后数据库数据如下
到此,关于“SpringBoot怎么整合EasyExcel”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341