【POI】Excel数据导入

 

Postman请求方式:

【POI】Excel数据导入

 

Controller接口代码:

    /**
     * /partImport/part/importUpload
     * @param importFile
     * @return
     */
    @PostMapping("/part/importUpload")
    public Map<String, Object> importUpload(@RequestParam(value = "file") MultipartFile importFile) {
        return partMainDataImportService.importUpload(importFile);
    }

对象类型:

import org.springframework.web.multipart.MultipartFile;

 

逻辑思路:

1、Excel转变可获取数据

2、数据结果集插入DB

    @Override
    public Map<String, Object> importUpload(MultipartFile importFile) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Map<String, Object> resultMap = new HashMap<>();

        List<Map<Integer, String>> partMainDatas = null; // Sheet1 配件主数据信息
        List<Map<Integer, String>> partExclusivePrice = null; // Sheet2 配件专属价格
        List<Map<Integer, String>> partReplacements = null; // Sheet3 配件替换件

        try {
            // 获取数据集合对象 getDataListFromImportExcel导出方法
            partMainDatas = getDataListFromImportExcel(importFile, resultMap, 0);
            partExclusivePrice = getDataListFromImportExcel(importFile, resultMap, 1);
            partReplacements = getDataListFromImportExcel(importFile, resultMap, 2);

            Integer integer = insertPartMainData(partMainDatas);
            resultMap.put("partMainDatas", integer);

            if (!CollectionUtils.isEmpty(partExclusivePrice)) {
                Integer integer2 = insertExclusivePrice(partExclusivePrice);
                resultMap.put("partOwnPrices", integer2);
            } else {
                resultMap.put("partOwnPrices", 0);
            }
            if (!CollectionUtils.isEmpty(partReplacements)) {
                Integer integer3 = insertReplacements(partReplacements);
                resultMap.put("partShifts", integer3);
            } else {
                resultMap.put("partShifts", 0);
            }

        } catch (Exception exception) {
            exception.printStackTrace();
            return resultMap;
        } finally {
            stopWatch.stop();
            resultMap.put("execTime", stopWatch.getTotalTimeSeconds() + '秒');
        }
        resultMap.put("200", "导入成功");
        return resultMap;
    }

 

Excel转换到数据逻辑部分:

    /**
     * 提供给配件主数据导入处理
     * @param importFile
     * @param map 响应结果,如果报错异常,则在这里设置
     * @return
     */
    private List<Map<Integer, String>> getDataListFromImportExcel(MultipartFile importFile, Map<String, Object> map, Integer sheetIndex) throws Exception {

        Workbook workbook = null; // Excel工作薄
        Sheet sheet = null; // Excel表单 Sheet页
        Row row = null; // 行
        Map<Integer, String> dataMap = null; // 表单中的一行数据
        List<Map<Integer, String>> dataList = null; // 表单中的所有数据
        boolean isValidRow = false; // Excel行中是否是有效数据行

        InputStream inputStream = importFile.getInputStream(); // 文件流
        String filename = importFile.getOriginalFilename(); // 文件名


        // 获取Excel工作簿对象
        if ("xls".equalsIgnoreCase(filename.substring(filename.lastIndexOf(".") + 1, filename.length()))) {
            workbook = new HSSFWorkbook(inputStream);
        } else {
            workbook = new XSSFWorkbook(inputStream);
        }

        sheet = workbook.getSheetAt(sheetIndex); // 获取指定Sheet页来处理
        Boolean flag = false; // 标记,如果检测到空行为true
        Integer num = 0;
        dataList = new ArrayList<>();

        int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
        for (int i = 1 /* 从表单第二行开始读取数据,读取整个表单中的数据 */; i < physicalNumberOfRows; i++) {
            num = 0;
            if(flag){
                break;
            }
            row = sheet.getRow(i);
            if (null != row) {
                dataMap = new HashMap<>();

                int physicalNumberOfCells = sheet.getRow(0).getPhysicalNumberOfCells();

                for (int j = 0; j < physicalNumberOfCells; j++) {

                    if(null != row.getCell(j) && !StringUtils.isNullOrEmpty(row.getCell(j).getStringCellValue())){
                        num ++;
                        break;
                    }else if(sheet.getRow(0).getPhysicalNumberOfCells() - 1  == j && num == 0){
                        flag = true; // true结束
                        break;
                    }
                }
                    // 根据模板表头长度,读取一行数据
                for (int j = 0; j < sheet.getRow(0).getPhysicalNumberOfCells(); j++) {
                    if(flag){
                        break;
                    }
                    // 属于零件主数据导入的判断逻辑, sheet主数据 且下标是这个集合内的,判断空则抛出空异常
                    if (
                            sheetIndex.equals(0) &&
                                    this.validateColumnIndexListForMainData.contains(j) &&
                                    null == row.getCell(j)
                    ) {
                        map.put("5002", "导入的Excel数据(Sheet1配件主数据)必填字段存在空值!!!");
                        throw new ServiceBizException(ERR_MESSAGE);
                    }
                    else if (sheetIndex.equals(1) &&  null == row.getCell(j)) {
                        map.put("5003", "导入的Excel数据(Sheet2专属价格)存在空值!!!");
                        throw new ServiceBizException(ERR_MESSAGE);
                    }
                    else if (sheetIndex.equals(2) &&  null == row.getCell(j)) {
                        map.put("5004", "导入的Excel数据(Sheet3替换件)存在空值!!!");
                        throw new ServiceBizException(ERR_MESSAGE);
                    }

                    if (row.getCell(j) == null) {
                        dataMap.put(j, "");
                    } else {
                        String parseExcel = parseExcel(row.getCell(j)).trim();
                        if (!StringUtils.isBlank(parseExcel)) {
                            dataMap.put(j, parseExcel);
                            isValidRow = true;
                        } else {
                            dataMap.put(j, "");
                        }
                    }
                }

                /**
                 * 读取完一条记录,如果是有效数据行,则加入返回结果中
                 */
                if (isValidRow) {
                    dataList.add(dataMap);
                }
            }
        }
        if (CollectionUtils.isEmpty(dataList) && sheetIndex.equals(0)) {
            map.put("5001", "导入的Excel数据不能为空");
            throw new ServiceBizException(ERR_MESSAGE);
        }
        return dataList;
    }

这里有一段解析处理,有点麻烦

private static String parseExcel(Cell cell) {
        String result = "";
        switch (cell.getCellType()) {
            case HSSFCell.CELL_TYPE_NUMERIC:// 数字类型
                if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式
                    SimpleDateFormat sdf = null;
                    if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
                        sdf = new SimpleDateFormat("HH:mm");
                    } else {// 日期
                        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    }
                    Date date = cell.getDateCellValue();
                    result = sdf.format(date);
                } else if (cell.getCellStyle().getDataFormat() == 58) {
                    // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    double value = cell.getNumericCellValue();
                    Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
                    result = sdf.format(date);
                } else {
                    cell.setCellType(XSSFCell.CELL_TYPE_STRING);
                    result = cell.getStringCellValue().toString();
                }
                break;
            case HSSFCell.CELL_TYPE_STRING:// String类型
                result = cell.getRichStringCellValue().toString();
                break;
            case HSSFCell.CELL_TYPE_BLANK:
                result = "";
                break;
            default:
                result = "";
                break;
        }
        return result;

 

然后第二部分数据封装对象来插入DB:

/**
     *
     * @param datas
     * @return
     */
    private Integer insertPartMainData(List<Map<Integer, String>> datas) throws Exception {
        Integer affectRows = 0;

        Class<PartInfoPO> partInfoPOClass = PartInfoPO.class;
        PartInfoPO partInfoPO ;
        // 先遍历集合
        for (Map<Integer, String> row : datas) {
            partInfoPO = new PartInfoPO();
            partInfoPO.setOwnerCode("-1");
            // pmd是每一行的结果
            Set<Integer> columns = row.keySet();
            // 遍历每一行获取单元格的值
            for (Integer column : columns) {
                String fieldKey = fields.get(column);
                String fieldValue = row.get(column);
                if(StringUtils.isNullOrEmpty(fieldValue)){continue;}

                Field field = partInfoPOClass.getDeclaredField(fieldKey);
                field.setAccessible(true);
                Class<?> type = field.getType();

                fieldValue = "是".equals(fieldValue) ? YES :  "否".equals(fieldValue) ? NO : fieldValue;

                if (Integer.class.equals(type)) {
                    // fieldValue = "是".equals(fieldValue) ? "10041001" :  "否".equals(fieldValue) ? "10041002" : fieldValue;
                    field.set(partInfoPO, Integer.valueOf(fieldValue));
                }
                else if(BigDecimal.class.equals(type)) {
                    // fieldValue = "是".equals(fieldValue) ? "10041001" :  "否".equals(fieldValue) ? "10041002" : fieldValue;
                    field.set(partInfoPO, new BigDecimal(fieldValue));
                }
                else if(Date.class.equals(type) ) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
                    field.set(partInfoPO,  simpleDateFormat.parse(fieldValue));
                }
                else {
                    field.set(partInfoPO, fieldValue);
                }
            }
            affectRows += partInfoMapper.insert(partInfoPO);
        }
        return affectRows;
    }

 

上一篇:重庆市POI数据


下一篇:POI 生成Excel文件并下载