EasyExcel使用

EasyExcel使用–导入导出服务器为例

上传文件读取

@Operation(summary = "物理机导入上传文件")
    @PostMapping(value = "/import/machine")
    public String importFile(@RequestBody MultipartFile multipartFile) {
        return serverUploadService.upload(multipartFile);
    }
private static final String SEPARATOR = "/";
    private static final Logger logger = LoggerFactory.getLogger(ServerUploadServiceImpl.class);

@Override
    public String upload(MultipartFile multipartFile) {
        String fileName = Objects.requireNonNull(multipartFile.getOriginalFilename())
                .substring(0, multipartFile.getOriginalFilename().lastIndexOf("."));
        String fileSuffix = Objects.requireNonNull(multipartFile.getOriginalFilename())
                .substring(multipartFile.getOriginalFilename().lastIndexOf("."));
        String newFileName = fileName + UUID.randomUUID() + fileSuffix;
        String filePath = String.join(SEPARATOR, "D:\\upload", newFileName);
        File file = new File(filePath);

        try {
            multipartFile.transferTo(file);
        } catch (Exception e) {
            logger.error("文件上传异常", e);
            throw new SystemException("文件上传异常");
        }

        String uploadUid = UUID.randomUUID().toString();

        ServerExcelImportBo temp = new ServerExcelImportBo();
        temp.setUploadUid(uploadUid);
        temp.setStatus(ServerImportStatus.WAIT);
        temp.setFilePath(filePath);
        metaControllerProcessMap.put(uploadUid, temp);

        String tenantId = LoginUserUtil.getTenantId();
        String userUid = LoginUserUtil.getUserUid();

        //异步执行
        CompletableFuture.runAsync(() -> getCheck(uploadUid,tenantId,userUid));

        return uploadUid;
    }
//并发HashMap
private final ConcurrentHashMap<String, ServerExcelImportBo> metaControllerProcessMap = new ConcurrentHashMap<String, ServerExcelImportBo>(8){
        @Override
        public ServerExcelImportBo get(Object key) {
            ServerExcelImportBo temp = super.get(key);
            if(ServerImportStatus.SUCCESS.equals(temp.getStatus())){
                super.remove(key);
            }
            clearMap();
            return temp;
        }

        private void clearMap(){
            if(super.size() > 5){
                super.forEach((key, value) -> {
                    if(ServerImportStatus.SUCCESS.equals(value.getStatus())){
                        logger.info(String.format("remove key:%s",key));
                        super.remove(key);
                    }
                });
            }
        }

        @Override
        public ServerExcelImportBo put(String key, ServerExcelImportBo value) {
            clearMap();
            return super.put(key, value);
        }

    };
@Async
    public void getCheck(String uploadUid,String tenantId,String userUid){

        ServerExcelImportBo currentImport = metaControllerProcessMap.get(uploadUid);
        if(currentImport == null){
            logger.warn("未找到任务:"+uploadUid);
            return;
        }

        currentImport.setStatus(ServerImportStatus.RUNNING);
        metaControllerProcessMap.put(uploadUid, currentImport);

        DataReadListener<MachineBasicInfoSheet> dataReadListener = (DataReadListener<MachineBasicInfoSheet>) machineBasicInfoDataReader;
        dataReadListener.setUploadUid(uploadUid);
        ((MachineBasicInfoDataReader) dataReadListener).setTenantId(tenantId);
        ((MachineBasicInfoDataReader) dataReadListener).setUserUid(userUid);
        ReadSheet readSheet = EasyExcel.readSheet(dataReadListener.sheetName())
                .head(dataReadListener.getSheetClass())
                .headRowNumber(dataReadListener.getHeadRowNumber())
                .registerReadListener(dataReadListener)
                .build();

        ExcelReader excelReader = EasyExcel.read(currentImport.getFilePath())
                .registerConverter(new StringToListConverter())
                .registerConverter(new StringToListNameRelValueConverter())
                .build();

        try {
            excelReader.read(readSheet);
        } catch (Exception e) {
            logger.error("读取 Excel 文件时发生错误:" + e.getMessage());
        } finally {
            if(excelReader != null){
                excelReader.finish();
            }
        }

        boolean error = false;
        File errorExcel = new File("D:\\errorExcel.xlsx");
        if(!errorExcel.exists()){
            try {
                errorExcel.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        List<?> errorData = dataReadListener.getErrorData();
        currentImport.setErrorNum(errorData.size());
        currentImport.setTotal(dataReadListener.getTotal());
        if(!ObjectUtils.isEmpty(errorData)){
            error = true;
        }

        if(!ObjectUtils.isEmpty(errorData)){
            WriteSheet writeSheet = EasyExcelFactory.writerSheet(0,dataReadListener.getSheetName())
                    .head(dataReadListener.getSheetClass())
                    .build();
            ExcelWriter excelWritter = EasyExcel.write(errorExcel)
                    .excelType(ExcelTypeEnum.XLSX)
                    .registerConverter(new StringToListConverter())
                    .registerConverter(new StringToListNameRelValueConverter())
                    .build();
            excelWritter.write(errorData,writeSheet);
            excelWritter.finish();
        }

        if(error){
            FileInfo errorFile = new FileInfo(errorExcel.getName(), errorExcel.getPath());
            errorFile.setFileType(FileType.EXCEL);
            errorFile.setFileSize(String.valueOf(currentImport.getErrorNum()));
            currentImport.setErrorDataFile(errorFile);
        }
        currentImport.setStatus(ServerImportStatus.SUCCESS);
        metaControllerProcessMap.put(uploadUid, currentImport);

    }

监听器

package com.sugon.rest.application.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author zhang.wp
 * @date 2024/4/17 16:05
 */
public abstract class DataReadListener<T> extends AnalysisEventListener<T> {

    protected final List<T> errorData = new ArrayList<>();
    private final List<T> dataList = new ArrayList<>(100);
    private Integer total = 0;
    private Integer currentRow = 0;
    private String uploadUid;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    public String getUploadUid() {
        return uploadUid;
    }

    public void setUploadUid(String uploadUid) {
        this.uploadUid = uploadUid;
    }

    public Integer getTotal() {
        return total;
    }

    public List<T> getErrorData() {
        return errorData;
    }

    public String getSheetName() {
        return sheetName();
    }

    public Class<?> getSheetClass() {
        return sheetClass();
    }

    public Integer getHeadRowNumber() {
        return headRowNumber();
    }

    @Override
    public void invoke(T data, AnalysisContext context) {
        if (total == 0) {
            this.total = context.readSheetHolder().getApproximateTotalRowNumber() - getHeadRowNumber();
        }
        if (dataList.size() < 100) {
            dataList.add(data);
        } else {
            read(dataList);
            this.currentRow = this.currentRow + dataList.size();
            dataList.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (!ObjectUtils.isEmpty(dataList)) {
            read(dataList);
            this.currentRow = this.currentRow + dataList.size();
            String finishNum = Optional.ofNullable(redisTemplate.opsForValue().get(getUploadUid())).orElse("0");
            int temp = Integer.parseInt(finishNum) + 1;
            redisTemplate.opsForValue().set(getUploadUid(), Integer.toString(temp), 30, TimeUnit.MINUTES);
        }
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        dataList.clear();
        super.onException(exception, context);
    }

    public abstract void read(List<T> data);

    public abstract String sheetName();

    public abstract Class<?> sheetClass();

    public abstract Integer headRowNumber();
}
package com.sugon.rest.application.listener;

import com.sugon.core.application.enums.LabelGroup;
import com.sugon.core.application.manager.PhysicalMachineManager;
import com.sugon.core.application.manager.ServerClusterManager;
import com.sugon.core.application.pojo.po.PhysicalMachine;
import com.sugon.core.application.pojo.po.ServerCluster;
import com.sugon.core.auth.pojo.po.Label;
import com.sugon.core.auth.manager.LabelManager;
import com.sugon.core.auth.util.LoginUserUtil;
import com.sugon.core.common.util.UuidUtil;
import com.sugon.rest.application.entity.excel.server.MachineBasicInfoSheet;
import com.sugon.rest.application.entity.form.MachineSaveForm;
import com.sugon.rest.application.service.ServerService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java
上一篇:鸿蒙系统(HarmonyOS)介绍


下一篇:Java复习42(PTA)