ExcelUtil.java 16.5 KB
package com.skua.modules.equipment.util;

import com.skua.core.context.SpringContextUtils;
import com.skua.core.util.DateUtils;
import com.skua.modules.equipment.dto.EquipmentDTO;
import com.skua.modules.equipment.pojo.Equipment;
import com.skua.modules.equipment.entity.EquipmentAsset;
import com.skua.modules.equipment.entity.EquipmentExt;
import com.skua.modules.equipment.entity.EquipmentInfo;
import com.skua.redis.util.CustomRedisUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.jeecgframework.poi.excel.annotation.Excel;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author sonin
 * @date 2021/10/8 14:49
 */
public class ExcelUtil {

    public static Workbook exportEquipment(List<Map<String, Object>> mapList) {
        // 获取 enName => zhName 映射
        Field[] equipmentFields = Equipment.class.getDeclaredFields();
        Map<String, String> equipmentAssetMap = new LinkedHashMap<>();
        Map<String, String> equipmentInfoMap = new LinkedHashMap<>();
        Map<String, String> equipmentExtMap = new LinkedHashMap<>();
        // 需要转换的字段: index => fieldName
        Map<Integer, String> convertMap = new HashMap<>();
        Map<String, String> tmpExcelMap = null;
        for (Field equipmentField : equipmentFields) {
            Class subClazz = equipmentField.getType();
            Field[] subFields = subClazz.getDeclaredFields();
            if (subClazz == EquipmentAsset.class) {
                tmpExcelMap = equipmentAssetMap;
            } else if (subClazz == EquipmentInfo.class) {
                tmpExcelMap = equipmentInfoMap;
            } else if (subClazz == EquipmentExt.class) {
                tmpExcelMap = equipmentExtMap;
            }
            for (Field subField : subFields) {
                Excel excel = subField.getAnnotation(Excel.class);
                if (excel != null && !"".equals(excel.name())) {
                    tmpExcelMap.put(subField.getName(), excel.name());
                }
            }
        }
        // 创建excel
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
        // 设置 居中样式
        CellStyle cellStyle = hssfWorkbook.createCellStyle();
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 创建sheet
        HSSFSheet hssfSheet = hssfWorkbook.createSheet("sheet0");
        // 创建第一行 => 合并单元格信息
        HSSFRow title = hssfSheet.createRow(0);
        // 合并equipmentAsset
        for (int i = 0; i < equipmentAssetMap.size(); i++) {
            HSSFCell cell = title.createCell(i);
            if (i == 0) {
                cell.setCellValue("资产信息");
                cell.setCellStyle(cellStyle);
            }
        }
        CellRangeAddress eaCellRangeAddress = new CellRangeAddress(0, 0, 0, equipmentAssetMap.size() - 1);
        hssfSheet.addMergedRegion(eaCellRangeAddress);
        // 合并equipmentInfo
        for (int i = equipmentAssetMap.size(); i < equipmentAssetMap.size() + equipmentInfoMap.size(); i++) {
            HSSFCell cell = title.createCell(i);
            if (i == equipmentAssetMap.size()) {
                cell.setCellValue("设备信息");
                cell.setCellStyle(cellStyle);
            }
        }
        CellRangeAddress eiCellRangeAddress = new CellRangeAddress(0, 0, equipmentAssetMap.size(), equipmentAssetMap.size() + equipmentInfoMap.size() - 1);
        hssfSheet.addMergedRegion(eiCellRangeAddress);
        // 合并equipmentExt
        for (int i = equipmentAssetMap.size() + equipmentInfoMap.size(); i < equipmentAssetMap.size() + equipmentInfoMap.size() + equipmentExtMap.size(); i++) {
            HSSFCell cell = title.createCell(i);
            if (i == equipmentAssetMap.size() + equipmentInfoMap.size()) {
                cell.setCellValue("设备扩展信息");
            }
        }
        // 目前设备扩展equipmentExt无字段,因此需要判空
        if (!equipmentExtMap.isEmpty()) {
            CellRangeAddress eeCellRangeAddress = new CellRangeAddress(0, 0, equipmentAssetMap.size() + equipmentInfoMap.size(), equipmentAssetMap.size() + equipmentInfoMap.size() + equipmentExtMap.size() - 1);
            hssfSheet.addMergedRegion(eeCellRangeAddress);
        }
        // 创建第2行 => zhName展示
        HSSFRow subTitle = hssfSheet.createRow(1);
        int column = 0;
        for (Map.Entry<String, String> item : equipmentAssetMap.entrySet()) {
            HSSFCell cell = subTitle.createCell(column++);
            cell.setCellValue(item.getValue());
            if ("assetType".equals(item.getKey())) {
                // 资产类型需要转换
                convertMap.put(column - 1, item.getKey());
            }
        }
        for (Map.Entry<String, String> item : equipmentInfoMap.entrySet()) {
            HSSFCell cell = subTitle.createCell(column++);
            cell.setCellValue(item.getValue());
            if ("departId".equals(item.getKey())) {
                // 货主组织需要转换
                convertMap.put(column - 1, item.getKey());
            } else if ("equipmentType".equals(item.getKey())) {
                // 设备类型需要转换
                convertMap.put(column - 1, item.getKey());
            } else if ("installPosition".equals(item.getKey())) {
                // 安装位置需要转换
                convertMap.put(column - 1, item.getKey());
            }
        }
        for (Map.Entry<String, String> item : equipmentExtMap.entrySet()) {
            HSSFCell cell = subTitle.createCell(column++);
            cell.setCellValue(item.getValue());
        }
        // assetType: enName => zhName
        Map<String, String> assetTypeVal2KeyMap = EquipmentUtils.convertFunc("assetType", false);
        // equipmentType: enName => zhName
        Map<String, String> equipmentTypeVal2KeyMap = EquipmentUtils.convertFunc("equipmentType", false);
        // installPosition enName => zhName
        Map<String, String> installPositionVal2KeyMap = EquipmentUtils.convertFunc("installPosition", false);
        // 从第三行开始,展示数据
        int row = 2;
        column = 0;
        for (Map<String, Object> map : mapList) {
            HSSFRow rowData = hssfSheet.createRow(row++);
            for (Map.Entry<String, String> item : equipmentAssetMap.entrySet()) {
                HSSFCell cell = rowData.createCell(column++);
                Object cellVal = map.get("EquipmentAsset_" + item.getKey());
                if (cellVal != null) {
                    // 转换字段 enName => zhName
                    if (convertMap.get(column - 1) != null) {
                        if ("assetType".equals(convertMap.get(column - 1))) {
                            cell.setCellValue("" + assetTypeVal2KeyMap.getOrDefault(cellVal.toString(), cellVal.toString()));
                        }
                    } else {
                        cell.setCellValue(cellVal.toString());
                    }
                }
            }
            for (Map.Entry<String, String> item : equipmentInfoMap.entrySet()) {
                HSSFCell cell = rowData.createCell(column++);
                Object cellVal = map.get("EquipmentInfo_" + item.getKey());
                if (cellVal != null) {
                    // 转换字段 enName => zhName
                    if (convertMap.get(column - 1) != null) {
                        if ("departId".equals(convertMap.get(column - 1))) {
                            CustomRedisUtil customRedisUtil = (CustomRedisUtil) SpringContextUtils.getBean("customRedisUtil");
                            cell.setCellValue("" + customRedisUtil.hget("sys_depart", cellVal.toString(), "id", "depart_name"));
                        } else if ("equipmentType".equals(convertMap.get(column - 1))) {
                            cell.setCellValue("" + equipmentTypeVal2KeyMap.getOrDefault(cellVal.toString(), cellVal.toString()));
                        } else if ("installPosition".equals(convertMap.get(column - 1))) {
                            cell.setCellValue("" + installPositionVal2KeyMap.getOrDefault(cellVal.toString(), cellVal.toString()));
                        }
                    } else {
                        cell.setCellValue(cellVal.toString());
                    }
                }
            }
            for (Map.Entry<String, String> item : equipmentExtMap.entrySet()) {
                HSSFCell cell = rowData.createCell(column++);
                Object cellVal = map.get("EquipmentExt_" + item.getKey());
                if (cellVal != null) {
                    cell.setCellValue(cellVal.toString());
                }
            }
            column = 0;
        }
        return hssfWorkbook;
    }

    public static List<EquipmentDTO> importEquipment(Sheet sheet) throws Exception {
        List<EquipmentDTO> equipmentDTOList = new ArrayList<>();
        // 获取 zhName => enName 映射
        Map<String, String> equipmentAssetMap = new LinkedHashMap<>();
        Map<String, String> equipmentInfoMap = new LinkedHashMap<>();
        Map<String, String> equipmentExtMap = new LinkedHashMap<>();
        Map<String, String> tmpExcelMap = null;
        Field[] equipmentFields = Equipment.class.getDeclaredFields();
        for (Field equipmentVOField : equipmentFields) {
            Class subClazz = equipmentVOField.getType();
            Field[] subFields = subClazz.getDeclaredFields();
            if (subClazz == EquipmentAsset.class) {
                tmpExcelMap = equipmentAssetMap;
            } else if (subClazz == EquipmentInfo.class) {
                tmpExcelMap = equipmentInfoMap;
            } else if (subClazz == EquipmentExt.class) {
                tmpExcelMap = equipmentExtMap;
            }
            for (Field subField : subFields) {
                Excel excel = subField.getAnnotation(Excel.class);
                if (excel != null && !"".equals(excel.name())) {
                    tmpExcelMap.put(excel.name(), subField.getName());
                }
            }
        }
        // 获取第0行数据
        Row row0 = sheet.getRow(0);
        // 标题 => 长度 的映射
        Map<String, Integer> title2LenMap = new LinkedHashMap<>();
        int cur = 0, prev = 0;
        Queue<String> titleQueue = new LinkedList<>();
        while (cur < row0.getLastCellNum()) {
            Cell cell = row0.getCell(cur);
            if (cell != null) {
                String title = cell.getStringCellValue();
                if (StringUtils.isNotEmpty(title)) {
                    titleQueue.offer(title);
                    if (cur != 0) {
                        title2LenMap.put(titleQueue.poll(), cur - prev);
                        prev = cur;
                    }
                }
            }
            cur++;
        }
        title2LenMap.put(titleQueue.poll(), cur - prev);
        // 资产信息: [0, len0)
        int len0 = title2LenMap.get("资产信息");
        // 设备信息: [len0, len0 + len1)
        int len1 = title2LenMap.get("设备信息");
        // 设备扩展信息: [len0 + len1, len0 + len1 + len2)
        int len2 = 0;
        if (title2LenMap.get("设备扩展信息") != null) {
            len2 = title2LenMap.get("设备扩展信息");
        }
        // 获取第1行数据, 设置index => enName的映射
        Row row1 = sheet.getRow(1);
        Map<Integer, String> index2enNameMap = new HashMap<>(10);
        for (int i = 0; i < len0 + len1 + len2; i++) {
            if (i < len0) {
                index2enNameMap.put(i, equipmentAssetMap.get(row1.getCell(i).getStringCellValue()));
            } else if (i < len0 + len1) {
                index2enNameMap.put(i, equipmentInfoMap.get(row1.getCell(i).getStringCellValue()));
            } else if (i < len0 + len1 + len2) {
                index2enNameMap.put(i, equipmentExtMap.get(row1.getCell(i).getStringCellValue()));
            }
        }
        // assetType
        Map<String, String> assetTypeKey2ValMap = EquipmentUtils.convertFunc("assetType", true);
        // equipmentType
        Map<String, String> equipmentTypeKey2ValMap = EquipmentUtils.convertFunc("equipmentType", true);
        // depart
        Map<String, String> departKey2ValMap = EquipmentUtils.convertFunc("depart", true);
        // installPosition
        Map<String, String> installPositionKey2ValMap = EquipmentUtils.convertFunc("installPosition", true);
        // 从第2行开始读取数据
        for (int i = 2; i <= sheet.getLastRowNum(); i++) {
            Row curRow = sheet.getRow(i);
            EquipmentDTO equipmentDTO = new EquipmentDTO();
            EquipmentAsset equipmentAsset = EquipmentAsset.class.newInstance();
            EquipmentInfo equipmentInfo = EquipmentInfo.class.newInstance();
            EquipmentExt equipmentExt = EquipmentExt.class.newInstance();
            for (int j = 0; j < len0 + len1 + len2; j++) {
                String enName = index2enNameMap.get(j);
                Field field = null;
                Object tmpObj = null;
                if (j < len0) {
                    field = EquipmentAsset.class.getDeclaredField(enName);
                    tmpObj = equipmentAsset;
                } else if (j < len0 + len1) {
                    field = EquipmentInfo.class.getDeclaredField(enName);
                    tmpObj = equipmentInfo;
                } else if (j < len0 + len1 + len2) {
                    field = EquipmentExt.class.getDeclaredField(enName);
                    tmpObj = equipmentExt;
                }
                field.setAccessible(true);
                if (field.getType() == Integer.class) {
                    try {
                        curRow.getCell(j).setCellType(Cell.CELL_TYPE_STRING);
                        String tmpVal = curRow.getCell(j).getStringCellValue();
                        if (!"".equals(tmpVal)) {
                            field.set(tmpObj, Integer.parseInt(tmpVal));
                        }
                    } catch (Exception e) {
                        throw new RuntimeException("第" + i + 1 + "行的第" + j + 1 + "的单元格数据应使用整数类型");
                    }
                } else  if (field.getName().contains("Date")) {
                    try {
                        //curRow.getCell(j).setCellType(Cell.CELL_TYPE_NUMERIC);
                        Date tmpVal = curRow.getCell(j).getDateCellValue();
                        String tmpValFormat = DateUtils.format(tmpVal, "yyyy-MM-dd");

                        if (!"".equals(tmpValFormat)) {
                            field.set(tmpObj, String.valueOf(tmpValFormat));
                        }
                    } catch (Exception e) {
                        throw new RuntimeException("第" + i + 1 + "行的第" + j + 1 + "的单元格数据应使用年月日期类型");
                    }
                }else {
                    if (curRow.getCell(j) != null) {
                        try {
                            // 转换成String类型格式
                            curRow.getCell(j).setCellType(Cell.CELL_TYPE_STRING);
                            field.set(tmpObj, curRow.getCell(j).getStringCellValue());
                        } catch (Exception e) {
                            throw new RuntimeException("第" + i + 1+"行的第" + j + 1+"的单元格数据应使用字符类型");
                        }

                    }
                }
                field.setAccessible(false);
            }
            // 资产类型 zhName => enName
            equipmentAsset.setAssetType("" + assetTypeKey2ValMap.getOrDefault(equipmentAsset.getAssetType(), ""));
            // 货主组织 zhName => enName
            equipmentInfo.setDepartId("" + departKey2ValMap.getOrDefault(equipmentInfo.getDepartId(), ""));
            // 设备类型 zhName => enName
            equipmentInfo.setEquipmentType("" + equipmentTypeKey2ValMap.getOrDefault(equipmentInfo.getEquipmentType(), ""));
            // 安装位置 zhName => enName
            equipmentInfo.setInstallPosition("" + installPositionKey2ValMap.getOrDefault(equipmentInfo.getInstallPosition(), ""));
            equipmentDTO.setEquipmentAsset(equipmentAsset);
            equipmentDTO.setEquipmentInfo(equipmentInfo);
            //equipmentDTO.setEquipmentExt(equipmentExt);
            equipmentDTOList.add(equipmentDTO);
        }
        return equipmentDTOList;
    }

    /**
     * 判断上传的excel文件版本(xls为2003,xlsx为2017)
     *
     * @param fileName 文件路径
     * @return excel2007及以上版本返回true,excel2007以下版本返回false
     */
    public static boolean judgeExcelEdition(String fileName) {
        return !fileName.matches("^.+\\.(?i)(xls)$");
    }

}