GitHub地址参照:https://github.com/alibaba/easyexcel
写操作(将数据写入到excel文件)
1.引入依赖
<dependencies> <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --> <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> </dependencies>
2.创建实体类,这里用的lombok生成get和set。
package com.stu.codeGenerator.excel; import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; @Data public class DemoDataExcel { //设置Excel表头名称 @ExcelProperty("学生编号") private Integer sno; @ExcelProperty("学生姓名") private String sname; }
3.测试方法(两种方式都可以)
方法1
package com.stu.codeGenerator.excel; import com.alibaba.excel.EasyExcel; import java.util.ArrayList; import java.util.List; public class DemoEasyExcel { public static void main(String[] args) {
//写法1 //实现excel写的操作(生成一个excel文件,并且有内容) //1.设置写入文件地址和excel文件名称,如果路径是C盘可能会报错。 String fileName = "F:\write.xlsx"; //2.调用easyexcel里面的方法实现写操作 //write有两个参数,第一个参数是文件路径名称,第二个参数是实体类class,doWrite里需要传递一个集合 EasyExcel.write(fileName,DemoDataExcel.class).sheet("学生列表").doWrite(getData()); } private static List<DemoDataExcel> getData(){ List<DemoDataExcel> list = new ArrayList<>(); for(int i = 0;i<10;i++){ DemoDataExcel data = new DemoDataExcel(); data.setSno(i); data.setSname("Excel"+i); list.add(data); } return list; } }
方法2
public static void main(String[] args) throws Exception { // 写法2,方法二需要手动关闭流 String fileName = "F:\112.xlsx"; // 这里 需要指定写用哪个class去写 ExcelWriter excelWriter = EasyExcel.write(fileName, DemoDataExcel.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet("写入方法二").build(); excelWriter.write(data(), writeSheet); /// 千万别忘记finish关闭流 excelWriter.finish(); }
4.执行main方法,excel效果如下。
读操作基本示例(从excel文件把数据读出来)
1.创建实体类(注解多了一个value和index)
package com.stu.codeGenerator.excel; import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; @Data public class DemoDataExcel { //设置Excel表头名称 //0表示第一列 @ExcelProperty(value = "学生编号",index = 0) private Integer sno; //1表示第二列 @ExcelProperty(value = "学生姓名",index = 1) private String sname; }
2.创建一个监听器类继承AnalysisEventListener,进行excel文件读取,他是一行一行的读取
package com.stu.codeGenerator.excel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import java.sql.SQLOutput; import java.util.Map; public class ExcelListener extends AnalysisEventListener<DemoDataExcel> { //一行一行读取excel内容,第一行表头不会读取 @Override public void invoke(DemoDataExcel demoDataExcel, AnalysisContext analysisContext) { System.out.println("++++行内容++++="+demoDataExcel); } //读取表头内容 @Override public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { System.out.println("+++表头+++++="+headMap); } //读取完成之后 @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { System.out.println("++++++++="+analysisContext); } }
3.测试方法(两个方法)
方法1
package com.stu.codeGenerator.excel; import com.alibaba.excel.EasyExcel; import java.util.ArrayList; import java.util.List; public class DemoEasyExcel { public static void main(String[] args) { // //实现excel写的操作(生成一个excel文件,并且有内容) // //1.设置写入文件地址和excel文件名称 // String fileName = "F:\write.xlsx"; // // //2.调用easyexcel里面的方法实现写操作 // //write有两个参数,第一个参数是文件路径名称,第二个参数是实体类class // EasyExcel.write(fileName,DemoDataExcel.class).sheet("学生列表").doWrite(getData()); String fileName = "F:\write.xlsx"; EasyExcel.read(fileName,DemoDataExcel.class,new ExcelListener()).sheet().doRead(); } private static List<DemoDataExcel> getData(){ List<DemoDataExcel> list = new ArrayList<>(); for(int i = 0;i<10;i++){ DemoDataExcel data = new DemoDataExcel(); data.setSno(i); data.setSname("Excel"+i); list.add(data); } return list; } }
方法2
public static void main(String[] args) throws Exception { // 写法1: String fileName = "F:\01.xlsx"; // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 EasyExcel.read(fileName, ReadData.class, new ExcelListener()).sheet().doRead(); // 写法2: InputStream in = new BufferedInputStream(new FileInputStream("F:\01.xlsx")); ExcelReader excelReader = EasyExcel.read(in, ReadData.class, new ExcelListener()).build(); ReadSheet readSheet = EasyExcel.readSheet(0).build(); excelReader.read(readSheet); // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的 excelReader.finish(); }
控制台输出:
+++表头+++++={0=学生编号, 1=学生姓名} ++++行内容++++=DemoDataExcel(sno=0, sname=Excel0) ++++行内容++++=DemoDataExcel(sno=1, sname=Excel1) ++++行内容++++=DemoDataExcel(sno=2, sname=Excel2) ++++行内容++++=DemoDataExcel(sno=3, sname=Excel3) ++++行内容++++=DemoDataExcel(sno=4, sname=Excel4) ++++行内容++++=DemoDataExcel(sno=5, sname=Excel5) ++++行内容++++=DemoDataExcel(sno=6, sname=Excel6) ++++行内容++++=DemoDataExcel(sno=7, sname=Excel7) ++++行内容++++=DemoDataExcel(sno=8, sname=Excel8) ++++行内容++++=DemoDataExcel(sno=9, sname=Excel9) ++++++++=com.alibaba.excel.context.AnalysisContextImpl@491666ad Process finished with exit code 0
读操作--保存到数据示例(从excel文件把数据读出来,保存到数据库)
SubJectData实体类封装
package com.stu.eduservice.entity.excel; import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; @Data public class SubJectData { @ExcelProperty(index = 0) private String oneSubjectName; @ExcelProperty(index = 1) private String twoSubjectName; }
controller层
package com.stu.eduservice.controller; import com.stu.commonutils.ResultData; import com.stu.eduservice.entity.EduSubject; import com.stu.eduservice.entity.subject.Subject; import com.stu.eduservice.service.IEduSubjectService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; /** * <p> * 课程科目 前端控制器 * </p> * * @author stu * @since 2021-05-24 */ @RestController @RequestMapping("/eduservice/subject") @CrossOrigin public class EduSubjectController { @Autowired private IEduSubjectService eduSubjectService; //添加课程分类 //获取上传的excel文件,把文件的内容读取出来 @PostMapping("addSubJect") public ResultData addSubJect(MultipartFile file){ //上传过来的excel文件 eduSubjectService.addSubJect(file,eduSubjectService); return ResultData.success(); } //课程分类列表(树形) @GetMapping("getAllSubJect") public ResultData getAllSubJect(){ List<Subject> list = eduSubjectService.getAllSubJect(); return ResultData.success().data("list",list); } }
service接口
package com.stu.eduservice.service; import com.stu.eduservice.entity.EduSubject; import com.baomidou.mybatisplus.extension.service.IService; import com.stu.eduservice.entity.subject.Subject; import org.springframework.web.multipart.MultipartFile; import java.util.List; /** * <p> * 课程科目 服务类 * </p> * * @author stu * @since 2021-05-24 */ public interface IEduSubjectService extends IService<EduSubject> { void addSubJect(MultipartFile file,IEduSubjectService eduSubjectService); List<Subject> getAllSubJect(); }
service实现类
package com.stu.eduservice.service.impl; import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.stu.eduservice.entity.EduSubject; import com.stu.eduservice.entity.excel.SubJectData; import com.stu.eduservice.entity.subject.Subject; import com.stu.eduservice.listener.SubJectExcelListener; import com.stu.eduservice.mapper.EduSubjectMapper; import com.stu.eduservice.service.IEduSubjectService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * <p> * 课程科目 服务实现类 * </p> * * @author stu * @since 2021-05-24 */ @Service public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements IEduSubjectService { @Override public void addSubJect(MultipartFile file,IEduSubjectService eduSubjectService) { try { //文件输入流 InputStream in = file.getInputStream(); //调用读方法,通过监听类把数据保存到数据库 EasyExcel.read(in, SubJectData.class,new SubJectExcelListener(eduSubjectService)).sheet().doRead(); } catch (Exception e) { e.printStackTrace(); } } @Override public List<Subject> getAllSubJect() { List<Subject> root = new ArrayList<Subject>(); QueryWrapper<EduSubject> wrapper = new QueryWrapper<>(); List<EduSubject> permissionList = baseMapper.selectList(wrapper);//根菜单 List<Subject> subjectList = new ArrayList<>(); Map<String,Subject> map = new HashMap<String,Subject>(); for(EduSubject bean :permissionList){ Subject subject = new Subject(); BeanUtils.copyProperties(bean,subject); map.put(bean.getId(), subject); subjectList.add(subject); } for(Subject bean :subjectList){ Subject children = bean; if(bean.getParentId().equals("0")){ root.add(bean); }else{ Subject parent = map.get(children.getParentId()); parent.getChildren().add(children); } } return root; } }
监听类继承AnalysisEventListener,通过invoke方法把数据保存到数据库
package com.stu.eduservice.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.stu.eduservice.entity.EduSubject; import com.stu.eduservice.entity.excel.SubJectData; import com.stu.eduservice.service.IEduSubjectService; import com.stu.servicebase.exceptionHandler.GuliException; public class SubJectExcelListener extends AnalysisEventListener<SubJectData> { //因为SubJectExcelListener不能交给spring进行管理,需要自己new,不能注入其他对象 //不能实现数据库操作 new mapper public IEduSubjectService eduSubjectService; //让对象可以使用start,创建一个有参构造和一个无参构造 public SubJectExcelListener(){} public SubJectExcelListener(IEduSubjectService eduSubjectService){ this.eduSubjectService = eduSubjectService; } //让对象可以使用end @Override public void invoke(SubJectData subJectData, AnalysisContext analysisContext) { if(subJectData == null ){ throw new GuliException(20001,"数据为空"); } //一行一行读取,每次读取有两个值,一级分类和二级分类 EduSubject eduSubjectOne =this.checkOne(eduSubjectService,subJectData.getOneSubjectName()); if(eduSubjectOne == null ){ eduSubjectOne = new EduSubject(); eduSubjectOne.setParentId("0"); eduSubjectOne.setTitle(subJectData.getOneSubjectName()); eduSubjectService.save(eduSubjectOne); } //取得一级分类的id,作为二级分类的父id,pid String pid = eduSubjectOne.getId(); EduSubject eduSubjectTwo =this.checkTwo(eduSubjectService,subJectData.getTwoSubjectName(),pid); if(eduSubjectTwo == null ){ eduSubjectTwo = new EduSubject(); eduSubjectTwo.setParentId(pid); eduSubjectTwo.setTitle(subJectData.getTwoSubjectName()); eduSubjectService.save(eduSubjectTwo); } } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } //判断一级分类不能重复 private EduSubject checkOne(IEduSubjectService eduSubjectService,String name){ QueryWrapper<EduSubject> wrapper = new QueryWrapper<>(); wrapper.eq("title",name); wrapper.eq("parent_id",0); EduSubject eduSubject = eduSubjectService.getOne(wrapper); return eduSubject; } //判断二级分类不能重复 private EduSubject checkTwo(IEduSubjectService 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; } }