1. 程式人生 > 其它 >【POI】Excel資料匯入

【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;
    }