项目中对Excel批量导入导出是一个经常用在项目,使用原生的POI对Excel进行操作,一方面很繁琐,另一方面也不容易复用,而阿里开源了EasyExcel项目,很方便的对Excel进行读取和写入,只用简单的几步就好
上传重要的一点是对监听器的创建,创建完成后,使用mybatis-plus的saveBatch方法,就可以将Excel中的数据写入到数据库中
controller层
@Autowired
private IStudentService iStudentService;
@Autowired
private ExcelListener excelListener;
@PostMapping("/uploadExcel")
public String uploadExcel(@RequestParam MultipartFile multipartFile) throws IOException {
//上传并解析Excel
EasyExcel.read(multipartFile.getInputStream(),Student.class,excelListener).sheet().doRead();
return "good";
}
监听器,参数中要求要传的值
@Component
public class ExcelListener extends AnalysisEventListener<Student> {
private static final Logger LOGGER = LoggerFactory.getLogger(ExcelListener.class);
private static final int BATCH_COUNT = 5;
List<Student> list = new ArrayList<Student>();
@Autowired
private IStudentService iStudentService;
@Override
public void invoke(Student data, AnalysisContext analysisContext) {
LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
list.add(data);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if (list.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
list.clear();
}
}
private void saveData() {
iStudentService.saveBatch(list);
LOGGER.info("所有数据解析完成!");
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
LOGGER.info("{}条数据,开始存储数据库!", list.size());
saveData();
LOGGER.info("存储数据库成功!");
}
}
@GetMapping("downLoadExcel")
public void downLoadExcel(HttpServletResponse response) throws Exception {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20") + ".xlsx");
//response.setHeader("Content-Disposition", "attachment; filename=" + new String(("测试.xlsx").getBytes("GBK"),"ISO-8859-1"));
List<Student> list = iStudentService.list();
EasyExcel.write(response.getOutputStream(), Student.class).sheet("模板").doWrite(list);
}
下载的话,可能使用文件名会出现,中文乱码的情况,使用下面任意两句都可以防止中文乱码的出现
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20") + ".xlsx");
response.setHeader("Content-Disposition", "attachment; filename=" + new String(("测试.xlsx").getBytes("GBK"),"ISO-8859-1"));
需要说明一点的是如果是日期格式的转换可以使用@JsonFormat或者@DateTimeFormat,@DateTimeFormat记得是com.alibaba.excel.annotation.format下的注解,
entity为String时,记得加在字段上加@ExcelProperty(converter = StringImageConverter.class)
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.4</version>
</dependency>