業務場景: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 {@Autowiredprivate S service;@Overridepublic 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> {@Overridepublic Class<ScreenDataCountExcel> getExcelClass() {return ScreenDataCountExcel.class;}@Overridepublic 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();}}