zoukankan      html  css  js  c++  java
  • 【POI】Excel数据导入

    Postman请求方式:

     

    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;
        }
  • 相关阅读:
    20200226 Java IO流——廖雪峰
    20200225 Java 多线程(2)-廖雪峰
    20200225 Java 多线程(1)-廖雪峰
    20200224 尚硅谷ElasticSearch【归档】
    20200224 一 概述
    20200222 尚硅谷Dubbo【归档】
    20200222 四、dubbo原理
    Improved robustness of reinforcement learning policies upon conversion to spiking neuronal network platforms applied to Atari Breakout game
    Reinforcement learning in populations of spiking neurons
    Solving the Distal Reward Problem through Linkage of STDP and Dopamine Signaling
  • 原文地址:https://www.cnblogs.com/mindzone/p/15505422.html
Copyright © 2011-2022 走看看