easyexcel讀取excel合併單元格數據-讀取完成-自動補全

普通的excel列表,easyexcel讀取是沒有什麼問題的。但是,如果有合併單元格,那麼它讀取的時候,能獲取數據,但是數據是不完整的

 像這個,讀取的第一行的”一級菜單“有值"A頁面”,第二行的”一級菜單“就是null,被合併的表格只有左上角是有值的,需要手動補全

Dto

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@EqualsAndHashCode
public class ImportPermissionTableDto {

//1、實體需要增加註解索引值: @ExcelProperty(value = "一級菜單",index = 0) private String 一級菜單; @ExcelProperty(value = "二級菜單",index = 1) private String 二級菜單; @ExcelProperty(value = "三級菜單",index = 2) private String 三級菜單; }

 自定義讀取監聽器

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import com.xd.asset.admin.v2soft.dto.ImportPermissionTableDto;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class AdminPermissionImportTableAnalysisEventListener extends AnalysisEventListener<ImportPermissionTableDto> {


    public AdminPermissionImportTableAnalysisEventListener() {
    }

    private List<ImportPermissionTableDto> list = new ArrayList<>();

    private List<CellExtra> cellExtraList = new ArrayList<>();

    @Override
    public void invoke(ImportPermissionTableDto excelData, AnalysisContext analysisContext) {
        log.info(" data -> {}", excelData);
        list.add(excelData);
    }

    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        log.info(" extra -> {}", extra);
        CellExtraTypeEnum type = extra.getType();
        switch (type) {
            case MERGE: {
                if (extra.getRowIndex() >= HEAD_ROW_NUM) {
                    cellExtraList.add(extra);
                }
                break;
            }
            default:{
            }
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info(" doAfterAllAnalysed");

        //讀取完成 填充合併過的單元格
        if (cellExtraList != null && cellExtraList.size() > 0) {
            mergeExcelData(list, cellExtraList, HEAD_ROW_NUM);
        }
    }

    public List<ImportPermissionTableDto> getList() {
        return list;
    }

    public List<CellExtra> getCellExtraList() {
        return cellExtraList;
    }



    private static final int HEAD_ROW_NUM = 1;

    private void mergeExcelData(List<ImportPermissionTableDto> excelDataList, List<CellExtra> cellExtraList, int headRowNum) {
        cellExtraList.forEach(cellExtra -> {
            int firstRowIndex = cellExtra.getFirstRowIndex() - headRowNum;
            int lastRowIndex = cellExtra.getLastRowIndex() - headRowNum;
            int firstColumnIndex = cellExtra.getFirstColumnIndex();
            int lastColumnIndex = cellExtra.getLastColumnIndex();
            //獲取初始值 合併單元格左上角的值
            Object initValue = getInitValueFromList(firstRowIndex, firstColumnIndex, excelDataList);
            //設置值 把合併單元格左上角的值 設置到合併區域的每一個單元格
            for (int i = firstRowIndex; i <= lastRowIndex; i++) {
                for (int j = firstColumnIndex; j <= lastColumnIndex; j++) {
                    setInitValueToList(initValue, i, j, excelDataList);
                }
            }
        });
    }

    private void setInitValueToList(Object filedValue, Integer rowIndex, Integer columnIndex, List<ImportPermissionTableDto> data) {
        ImportPermissionTableDto object = data.get(rowIndex);

        for (Field field : object.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
            if (annotation != null) {
                if (annotation.index() == columnIndex) {
                    try {
                        field.set(object, filedValue);
                        break;
                    } catch (IllegalAccessException e) {
                        log.error("設置合併單元格的值異常:{}", e.getMessage());
                    }
                }
            }
        }
    }

    private Object getInitValueFromList(Integer firstRowIndex, Integer firstColumnIndex, List<ImportPermissionTableDto> data) {
        Object filedValue = null;
        ImportPermissionTableDto object = data.get(firstRowIndex);
        for (Field field : object.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
            if (annotation != null) {
                if (annotation.index() == firstColumnIndex) {
                    try {
                        filedValue = field.get(object);
                        break;
                    } catch (IllegalAccessException e) {
                        log.error("設置合併單元格的初始值異常:{}", e.getMessage());
                    }
                }
            }
        }
        return filedValue;
    }
}

 使用

  @PostMapping("/importPermissionTableV1")
  @Transactional
  public List<ImportPermissionTableDto> importPermissionTableV1(@RequestParam("permissionTable") MultipartFile file) throws InvalidProtocolBufferException, ParseException {
    List<ImportPermissionTableDto> permissionList=new ArrayList<>();

    try {

      AdminPermissionImportTableAnalysisEventListener listener = new AdminPermissionImportTableAnalysisEventListener();
      EasyExcel.read(file.getInputStream(), ImportPermissionTableDto.class, listener).extraRead(CellExtraTypeEnum.MERGE).sheet().doRead();
      permissionList = listener.getList();

     //todo check-->do--->save--->result
    

    } catch (IOException e) {
      e.printStackTrace();
      throw new IllegalArgumentException(e.getMessage());
    }
    return permissionList;

  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章