前言
Java解析、生成Excel比较有名的框架有Apache poi、jxl。
但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。
easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。(是阿里大佬写的开源项目)
- github地址:https://github.com/alibaba/easyexcel
步骤
引pom
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.3</version>
</dependency>
建Model
【@ContentRowHeight(20)、@HeadRowHeight(20)、@ColumnWidth(15)用来调整表格样式,@ExcelProperty(value = “课程代码”, index = 0)index对应第一列,value对应标题名】
@EqualsAndHashCode(callSuper = true)
@Data
@ContentRowHeight(20)
@HeadRowHeight(20)
@ColumnWidth(15)
public class CourseExportTemplate extends BaseRowModel {
/**
* 课程代码
*/
@ExcelProperty(value = "课程代码", index = 0)
private String code ;
/**
* 课程名称
*/
@ExcelProperty(value = "课程名称", index = 1)
private String name;
/**
* 课程类别
*/
@ExcelProperty(value = "课程类别", index = 2)
private String courseCategory;
/**
* 课程类型
*/
@ExcelProperty(value = "课程类型", index = 3)
private String courseType;
/**
* 课程性质
*/
@ExcelProperty(value = "课程性质", index = 4)
private String courseNature;
/**
* 学院
*/
@ExcelProperty(value = "学院", index = 5)
private String academyName;
/**
* 学时
*/
@ExcelProperty(value = "学时", index = 6)
private String classHour;
/**
* 学分
*/
@ExcelProperty(value = "学分", index = 7)
private String classPoint;
/**
* 课程分数
*/
@ExcelProperty(value = "课程分数", index = 8)
private String score;
/**
* 错误原因
*/
@ExcelProperty(value = "错误原因", index = 9)
private String failReason;
}
建Excel工具类(用于导入Excel)
@Slf4j
public class ExcelListener extends AnalysisEventListener {
private List<Object> datas = new ArrayList<>();
@Override
public void invoke(Object object, AnalysisContext analysisContext) {
log.info("解析到一条数据:{}", JSON.toJSONString(object));
datas.add(object);
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("所有数据解析完成!");
}
public List<Object> getDatas(){
return datas;
}
public void setDatas(List<Object> datas){
this.datas = datas;
}
}
导出Excel
public boolean downLoadTemplate(HttpServletResponse response) {
CourseExportTemplate courseExportTemplate = new CourseExportTemplate();
courseExportTemplate.setAcademyName(academyName);
courseExportTemplate.setClassHour(classHour);
courseExportTemplate.setClassPoint(classPoint);
courseExportTemplate.setCode(code);
courseExportTemplate.setCourseCategory(courseCategory);
courseExportTemplate.setCourseNature(courseNature);
courseExportTemplate.setCourseType(courseType);
courseExportTemplate.setName(name);
courseExportTemplate.setScore(score);
List<CourseExportTemplate> list = new ArrayList<>();
list.add(courseExportTemplate);
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
try {
// URLEncoder.encode可以防止中文乱码
String cFileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + cFileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), CourseExportTemplate.class).sheet().doWrite(list);
} catch (IOException e) {
log.error("excel下载失败:错误信息:{}", e.toString());
return false;
}
return true;
}
导入Excel
public String importCourse(MultipartFile file) {
//获取导入Excel文件名
String fileName = file.getOriginalFilename();
if (StringUtils.isBlank(fileName)) {
log.error("导入失败,文件名为空");
}
ExcelListener listener = new ExcelListener();
try {
EasyExcel.read(file.getInputStream(), CourseExportTemplate.class, listener).sheet().doRead();
} catch (IOException e) {
log.error("Excel写入失败");
e.printStackTrace();
}
//获取解析后的课程数据
List<CourseExportTemplate> courseList = JSON.parseArray(JSON.toJSONString(listener.getDatas()), CourseExportTemplate.class);
//这里调用了通用Mapper方法存入数据库
//。。。。。可以加一些校验。。。。。
TtCourse ttCourse = new TtCourse();
BeanUtils.copyProperties(course, ttCourse);
//存库
courseDao.insert(ttCourse);
return "导入成功";
}