Easyexcel是阿里开源的, 简单, 可快速集成的excel文件导入导出工具, 能够有效的节省内存, 避免出现OOM问题. 原理: 不是一次性将内容全部读取, 而是一行行读取, 从而降低内存的使用.
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.7</version>
</dependency>
创建bean, 对应excel的表头名称及位置
@Data
@NoArgsConstructor
@AllArgsConstructor
public class WhitelistFileUploadRequest {
@ExcelProperty(value = "Phone", index = 0)
private String mobile;
@ExcelProperty(value = "Sourcecode", index = 1)
private String sourceCode;
}
创建Listener
@Component
public class WhitelistFileReadListener implements ReadListener<WhitelistFileUploadRequest>, ApplicationContextAware {
private static CardWhitelistFileService whitelistFileService;
private List<WhitelistFileUploadRequest> list = new ArrayList<>();
// 自定义属性
private String operatorId;
private String fileName;
public WhitelistFileReadListener() {
}
public WhitelistFileReadListener(String operatorId, String fileName) {
this.operatorId = operatorId;
this.fileName = fileName;
}
@Override
public void onException(Exception e, AnalysisContext analysisContext) throws Exception {
if (e instanceof ExcelDataConvertException) {
ExcelDataConvertException ce = (ExcelDataConvertException) e;
log.error("白名单上传解析异常: {} {}", ce.getRowIndex(), ce.getColumnIndex());
} else {
log.error("白名单上传解析异常: ", e);
}
}
@Override
public void invokeHead(Map<Integer, CellData> map, AnalysisContext analysisContext) {
log.info("白名单上传 头部: {}", JSON.toJSONString(map));
}
@Override
public void invoke(WhitelistFileUploadRequest whitelistFileRequest, AnalysisContext analysisContext) {
list.add(whitelistFileRequest);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
log.info("白名单上传解析完成: {} {}", fileName, list.size());
// TODO 对list进行操作入库
}
@Override
public boolean hasNext(AnalysisContext analysisContext) {
return true;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
whitelistFileService = applicationContext.getBean(CardWhitelistFileService.class);
}
}
文件上传及导入 入口
@PostMapping("/upload")
public Result upload(@RequestParam("file") MultipartFile file, @RequestAttribute(LoginConstant.TOKEN_UID) String operatorId) {
if (StringUtils.isEmpty(file.getOriginalFilename())) {
return new Result().failed("File is null");
}
try {
EasyExcel.read(
file.getInputStream(),
WhitelistFileUploadRequest.class,
new WhitelistFileReadListener(operatorId, file.getOriginalFilename())).sheet().doRead();
} catch (IOException | FailureException e) {
log.error("文件上传解析失败: ", e);
return new Result().failed("Save file failed");
}
return new Result<>().success(null);
}
创建bean, 定义表头名称及位置
@Data
@ApiModel("信息返回")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TestExportResponse implements Serializable {
@ApiModelProperty("sn")
@ExcelProperty(value = "SN", index = 0)
private String sn;
@ApiModelProperty("Name")
@ExcelProperty(value = "Name", index = 1)
private String name;
@ApiModelProperty("Phone")
@ExcelProperty(value = "Phone", index = 2)
private String Phone;
}
导出 入口
@PostMapping("/listExport")
@ApiOperation("列表导出")
public ResultVo listExport(HttpServletResponse response) {
try {
List<TestExportResponse> exportList = new ArrayList<>();
// TODO 添加数据
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("excel_list", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), TestExportResponse.class).sheet("excel_list").doWrite(exportList);
} catch (Exception e) {
throw CrmExceptionEnum.FAIL.throwCrmException();
}
return ResultVo.success();
}