You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Java读取Excel数字字段为字符串时显示科学计数法的问题

解决POI读取Excel手机号显示为科学计数法的问题

这个问题很常见,原因是Excel会把超过一定长度的数值自动转换成科学计数法存储,而你直接用toString()读取单元格内容时,就会拿到这个格式化后的字符串。下面给你两种可行的解决方案:

方案1:提前设置Excel单元格为文本格式(最简单)

如果可以修改源Excel文件,直接把存储手机号/邮箱的列设置为文本格式

  • 选中目标列,右键选择「设置单元格格式」
  • 在弹出的窗口里选择「文本」类型,点击确定
    之后再输入手机号,Excel就会把它当作文本存储,读取时直接用getStringCellValue()就能拿到完整的手机号字符串,不会出现科学计数法。

方案2:在代码中处理数值型单元格(无需修改Excel)

如果不能修改源文件,就需要在读取时判断单元格类型,对数值型单元格做特殊处理:

修改后的核心代码片段:

Workbook workbook = WorkbookFactory.create(new File("./TXN_Log_Mar_18_input.xlsx"));
Sheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.rowIterator();
while (rowIterator.hasNext() && cnt < maxRows) {
    System.out.println("\n\nNew row " + cnt + " ");
    Row row = rowIterator.next();
    
    // 安全获取第11列的单元格内容
    Cell debitCell = row.getCell(11);
    String debitUser = "";
    if (debitCell != null) {
        switch (debitCell.getCellType()) {
            case STRING:
                debitUser = debitCell.getStringCellValue();
                break;
            case NUMERIC:
                // 将数值转换为长整型,避免科学计数法
                long mobileNum = (long) debitCell.getNumericCellValue();
                debitUser = String.valueOf(mobileNum);
                break;
            case FORMULA:
                // 处理公式型单元格,先获取计算结果类型
                CellType resultType = debitCell.getCachedFormulaResultType();
                if (resultType == CellType.NUMERIC) {
                    mobileNum = (long) debitCell.getNumericCellValue();
                    debitUser = String.valueOf(mobileNum);
                } else if (resultType == CellType.STRING) {
                    debitUser = debitCell.getStringCellValue();
                } else {
                    debitUser = debitCell.toString();
                }
                break;
            default:
                debitUser = debitCell.toString();
                break;
        }
    }

    // 同理处理第12列(这里省略重复逻辑,你可以参考上面的代码实现)
    Cell creditCell = row.getCell(12);
    String creditUser = "";
    // ... 复制上面的单元格类型判断逻辑 ...

    // 修正空值判断(原代码的 != "" 有问题,应该用isEmpty())
    if (!debitUser.isEmpty() || !creditUser.isEmpty()) {
        System.out.println("input mobile? " + debitUser);
        if (emailFormat(debitUser) || mobileFormat(debitUser)) {
            response = umCall(debitUser);
        }
    }
    cnt++; // 别忘了增加计数器,否则会无限循环!
}

关键说明:

  1. 避免空指针异常:先判断debitCell != null,再处理单元格内容
  2. 数值转字符串的正确方式:把数值型单元格转成long(10位手机号在long的范围内),再转成字符串,这样就能得到完整的数字,不会出现科学计数法
  3. 处理公式单元格:如果单元格是公式,需要先获取计算结果的类型,再做对应处理
  4. 修正空值判断:原代码的row.getCell(11).toString() !=""不能正确判断空单元格,改用!debitUser.isEmpty()更可靠

额外提醒:

如果手机号存在前导零(比如0123456789),那么必须用方案1(设置为文本格式),因为数值类型会自动丢弃前导零,代码处理也无法恢复。

内容的提问来源于stack exchange,提问作者Sandeepan Nath

火山引擎 最新活动