使用过easyexcel框架的一些读者知道,每个导入功能都要写一个对应的Listener进行数据转换,在很多时间其实转换的逻辑都是类似的,不同的只不过是转换后数据处理的业务逻辑不一样。
「本开源项目的excel工具则利用Java中的泛型和Java8中的Consumer接口将相同的部分(转换逻辑)抽取出来,不同的部分则单独传入(数据处理的业务逻辑),这样就避免了每个导入都需要创建一个相类似的Listerner,减少了类的创建和提高了开发效率。」
「部分源码如下:」
/**
* 通用导入excel文件方法
*
* @param fileStream 导入的文件流
* @param rowDto 接收excel每行数据的实体
* @param rowAction 将接收到的实体进行自定义的业务处理逻辑方法
* @param 实体类型
*/
public static void importFile(InputStream fileStream, T rowDto, ThrowingConsumer> rowAction) {
// 获取excel通用监听器
ExcelImportCommonListener commonListener = new ExcelImportCommonListener<>(rowAction);
// 读取excel文件并导入
EasyExcel.read(fileStream, rowDto.getClass(), commonListener).sheet().doRead();
}
/**
* excel文件导出(可以包含多个sheet页),固定表头(通过实体指定属性的方式)
* @param response
* @param fileName 导出文件名
* @param head 导出表头(多个sheet页就是多个集合元素)
* @param exportData 需要导出数据
* @param sheetNames sheet页的名称,为空则默认以:sheet + 数字规则命名
*/
public static void exportFile(String fileName, List head, List> exportData, List sheetNames, HttpServletResponse response) {
if (Objects.isNull(response) || StrUtil.isBlank(fileName) || CollUtil.isEmpty(head)) {
log.info("ExcelExportUtil exportFile required param can't be empty");
return;
}
ExcelWriter writer = null;
try {
response.setContentType(ExportConstant.EXCEL_CONTENT_TYPE);
response.setCharacterEncoding(ExportConstant.UTF_8);
response.setHeader(ExportConstant.CONTENT_DISPOSITION, ExportConstant.ATTACHMENT_FILENAME + fileName + ExportConstant.XLSX_SUFFIX);
// 设置导出的表格样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = getExportDefaultStyle();
writer = EasyExcel.write(response.getOutputStream()).registerWriteHandler(horizontalCellStyleStrategy).build();
for (int itemIndex = 0; itemIndex < exportData.size(); itemIndex++) {
// 表头数据
Object headData = head.get(itemIndex);
// sheet页的数据
List list = exportData.get(itemIndex);
WriteSheet sheet = EasyExcel.writerSheet(itemIndex, CollUtil.isEmpty(sheetNames) ? ExportConstant.SHEET_NAME + itemIndex + 1 : sheetNames.get(itemIndex)).head(headData.getClass()).build();
writer.write(list, sheet);
}
} catch (Exception e) {
log.error("ExcelExportUtil exportFile in error:{}", e);
} finally {
if (null != writer) {
writer.finish();
}
}
}
「使用案例如下(在工具中每个项目都有具体的案例,不懂的还可以留言跟博主沟通):」
/**
* 导入用户数据案例
*
* @param file
*/
@Transactional(rollbackFor = Exception.class)
public void uploadUserListDemoWithExcel(MultipartFile file, String username) throws Exception {
// 此处先校验导入的文件类型是否为excel
String type = FileTypeUtil.getType(file.getInputStream());
if (StrUtil.isBlank(type) || type.contains(ImportConstant.XLS_TYPE) || type.contains(ImportConstant.XLSX_TYPE)) {
// 返回校验失败信息
return;
}
User user = new User();
user.setId(100);
user.setName("外层");
user.setPassword("外层");
userService.save(user);
// 调用统一导入方法
ExcelImportUtil.importFile(file.getInputStream(), new UserDto(), UserServiceImpl::saveUserList);
}
/**
* 导出案例
*
* @param response
*/
public void exportUserListDemoWithExcel(HttpServletResponse response) {
// 表头(使用excel中的注解定义,如果表头不固定,请使用ExcelExportUtil.exportWithDynamicData进行导出)
List