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;
        }
  • 相关阅读:
    常用的40个建站代码及使用说明
    vs2008与vs2005的冲突
    ASP调用.net的webservices的实现方法
    Web Development Tools for the Power Developer
    XML Web Service开发实例——通过Windows Forms调用Web Service
    “家贼”倒卖“征途”源代码 13万元卖给识货人
    [轉載]让UpdatePanel支持文件上传
    DB2与Sybase/Oracle/Informix的比较
    網頁打印代碼大全
    完整的网站间共享数据的WebService
  • 原文地址:https://www.cnblogs.com/mindzone/p/15505422.html
Copyright © 2011-2022 走看看