关于POI导出excel表,不做任何操作直接再次导入,读取数据失效(解析不到数据)的问题解决办法

项目场景:

在项目开发中,经常会遇到导出数据到excel表和利用excel表批量导入数据的需求,最常用的是利用POI进行导出导入操作;

问题描述:

导入一个有数据的excel文件, 导入成功后,再导出,对导出的excel文件不做任何处理再进行导入操作,java poi 解析不到数据; 如果将导出的excel文件打开随便点一下,保存再导入,此时可以解析到数据,之前取单元格值代码如下:

    XSSFCell cell = row.getCell(j);
    if (null == cell) {
    
    
        continue;
    }
    // 获取当前行当前列的值并进行保存s
    // 要对列进行类型的转化
    if (22 == cell.getCellStyle().getDataFormat()) {
    
    
        Date date = DateUtil.getJavaDate(cell.getNumericCellValue());
        String dateStr = sdf.format(date);
        ss[j] = dateStr;
    } else {
    
    
         cell.setCellType(CellType.STRING);
        ss[j] = cell.getStringCellValue();
    }

原因分析:

有文章说是导入、导出时都要设置CellType,查看代码发现导入的时候设置了cell.setCellType(CellType.STRING),导出没写,后来在导出的时候也进行设置newCell.setCellType(CellType.STRING),但是没效果,后经调试,发现cell值取值能取到,但是进行设置cellType后再去取值,取不到值,猜测是不是因为poi中cell.setCellType(CellType.STRING)过期问题导致的,于是替换采用DataFormatter进行格式化,去取单元格中的值。


解决方案:

对单元格的值使用DataFormatter对象格式化,直接获取,修改后代码如下:

    XSSFCell cell = row.getCell(j);
    if (null == cell) {
    
    
        continue;
    }
    // 获取当前行当前列的值并进行保存s
    // 要对列进行类型的转化
    if (22 == cell.getCellStyle().getDataFormat()) {
    
    
        Date date = DateUtil.getJavaDate(cell.getNumericCellValue());
        String dateStr = sdf.format(date);
        ss[j] = dateStr;
    } else {
    
    
	   //直接获取到单元格的值
        DataFormatter formatter = new DataFormatter();
        ss[j] = formatter.formatCellValue(cell);    
    }

此时单元格中的值能正常解析到。

查看DataFormatter对象formatCellValue()方法源码,发现方法中对单元格中的值都做了类型转换处理:

    public String formatCellValue(Cell cell, FormulaEvaluator evaluator, ConditionalFormattingEvaluator cfEvaluator) {
    
    
        this.localeChangedObservable.checkForLocaleChange();
        if (cell == null) {
    
    
            return "";
        } else {
    
    
            CellType cellType = cell.getCellType();
            if (cellType == CellType.FORMULA) {
    
    
                if (evaluator == null) {
    
    
                    return cell.getCellFormula();
                }

                cellType = evaluator.evaluateFormulaCell(cell);
            }

            switch(cellType) {
    
    
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell, cfEvaluator)) {
    
    
                    return this.getFormattedDateString(cell, cfEvaluator);
                }

                return this.getFormattedNumberString(cell, cfEvaluator);
            case STRING:
                return cell.getRichStringCellValue().getString();
            case BOOLEAN:
                return cell.getBooleanCellValue() ? "TRUE" : "FALSE";
            case BLANK:
                return "";
            case ERROR:
                return FormulaError.forInt(cell.getErrorCellValue()).getString();
            default:
                throw new RuntimeException("Unexpected celltype (" + cellType + ")");
            }
        }
    }

完美解决导出excel表,不做任何操作直接导入,读取数据失效的问题~~~!!!

猜你喜欢

转载自blog.csdn.net/hurtseverywhere/article/details/122433494
今日推荐