业务场景:N个Excel导入,实现动态加载,只需要定义Excel实体,即可实现功能开发,
核心代码
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
public abstract class ScreenImportService<E, L, M extends BaseMapper<E>, S extends ServiceImpl<M, E>> implements InitializingBean {
@Autowired
private S service;
@Override
public void afterPropertiesSet() {
String fileName = AnnotationUtil.getAnnotationValue(this.getExcelClass(), ExcelTarget.class, "value");
ScreenImportFactory.register(fileName, this);
}
/**
* 获取当前泛型-Excel
*/
public abstract Class<L> getExcelClass();
/**
* excel 转 entity 并补全参数
*/
public abstract List<E> excel2Entity(List<L> excelList);
/**
* 数据批量导入数据库
*/
public void dataImportDb(List<L> excelList) {
// 全量导入
service.remove(Wrappers.lambdaQuery());
// excel 转 entity 并补全参数
List<E> entityList = this.excel2Entity(excelList);
if (CollectionUtil.isNotEmpty(entityList)) {
service.saveBatch(entityList);
}
}
}
工厂类
import cn.hutool.core.util.StrUtil;
import java.util.HashMap;
import java.util.Map;
/**
* 大屏相关数据导入-工厂类
*
* @author jason
*/
public class ScreenImportFactory {
private static final Map<String, ScreenImportService<?, ?, ?, ?>> strategyMap = new HashMap<>();
public static ScreenImportService<?, ?, ?, ?> getInvokeStrategy(String name) {
return strategyMap.get(name);
}
public static void register(String name, ScreenImportService<?, ?, ?, ?> service) {
if (StrUtil.isBlank(name)) {
return;
}
if (service == null) {
return;
}
strategyMap.put(name, service);
}
public static Map<String, ScreenImportService<?, ?, ?, ?>> getStrategyMap() {
return strategyMap;
}
}
实现类-每个文件有不同的实现
import cn.hutool.core.bean.BeanUtil;
import com.luoan.biz.hansi.domain.ScreenDataCountExcel;
import com.luoan.biz.hansi.entity.ScreenDataCount;
import com.luoan.biz.hansi.mapper.ScreenDataCountMapper;
import com.luoan.biz.hansi.service.ScreenImportService;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* <p>
* 大屏数据导入-汇总表 服务实现类
* </p>
*
* @author luoan
* @since 2023-09-26
*/
@Service
public class ImportCountServiceImpl extends ScreenImportService<ScreenDataCount, ScreenDataCountExcel, ScreenDataCountMapper, ScreenDataCountServiceImpl> {
@Override
public Class<ScreenDataCountExcel> getExcelClass() {
return ScreenDataCountExcel.class;
}
@Override
public List<ScreenDataCount> excel2Entity(List<ScreenDataCountExcel> excelList) {
return Optional.ofNullable(excelList)
.orElse(new ArrayList<>())
.stream()
.filter(Objects::nonNull)
.map(excel -> {
ScreenDataCount entity = new ScreenDataCount();
BeanUtil.copyProperties(excel, entity);
// 参数补全
entity.setCreateTime(LocalDateTime.now());
entity.setCreateUserId(0);
entity.setUpdateTime(LocalDateTime.now());
entity.setUpdateUserId(0);
return entity;
})
.collect(Collectors.toList())
;
}
}
统一调用,后续扩展很方便,N个导入,这块不用动了
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import com.luoan.biz.hansi.service.ScreenImportFactory;
import com.luoan.biz.hansi.service.ScreenImportService;
import com.luoan.biz.hansi.utils.ExcelUtil;
import com.luoan.common.vo.Result;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.util.Optional;
/**
* <p>
* 大屏相关数据 前端控制器
* </p>
*
* @author luoan
* @since 2023-08-09
*/
@RestController
@RequestMapping("/admin/screen")
public class ScreenImportCommonController {
@ApiOperation(value = "批量导入")
@PostMapping("/batch_import")
public Result<Object> batchImport(@RequestPart(value = "files") MultipartFile[] files) {
Assert.notEmpty(files, "请检查上传的文件");
Arrays.stream(Optional.ofNullable(files).orElse(new MultipartFile[]{}))
.forEach(file -> {
String originalFilename = file.getOriginalFilename();
String fileName = FileUtil.mainName(file.getOriginalFilename());
ScreenImportService<?, ?, ?, ?> service = ScreenImportFactory.getInvokeStrategy(fileName);
Assert.notNull(service, "请检查文件名:{}", originalFilename);
service.dataImportDb(ExcelUtil.importExcel(file, service.getExcelClass()));
}
);
return Result.ok();
}
}