You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Apache POI XSSFWorkbook如何将价格列设为数值格式而非文本?

解决Apache POI生成Excel时价格列文本格式转数值格式的问题

你当前的代码通过value.toString()将所有字段统一以字符串形式写入Excel单元格,这直接导致价格列被识别为文本格式——即便后续设置了数值样式,Excel也不会将字符串自动转换为数值,所以样式设置无效。

核心解决思路是区分数据类型写入单元格,而非统一转成字符串。针对价格列,先将获取到的值转换为数值类型,再调用对应类型的setCellValue方法,同时为该列应用数值样式。

修改后的代码示例:

public static void generateExcel(List<Results> results, String outputPath)
    throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

    Workbook workbook = new XSSFWorkbook();
    var sheet = workbook.createSheet("Report");

    String[] headerValues = {"Name", "Type", "Price"};

    // 预先创建数值样式
    DataFormat fmt = workbook.createDataFormat();
    CellStyle numericStyle = workbook.createCellStyle();
    numericStyle.setDataFormat(fmt.getFormat("0.00"));

    Row headerRow = sheet.createRow(0);
    for (int i = 0; i < headerValues.length; i++) {
        headerRow.createCell(i).setCellValue(headerValues[i]);
    }

    for (var i = 0; i < results.size(); i++) {
        var row = sheet.createRow(i + 1);
        Results summary = results.get(i);
        int colNum = 0;
        for (var header : headerValues) {
            String propertyName = "get" + header;
            Method method = Results.class.getMethod(propertyName);
            Object value = method.invoke(summary);

            if (value != null) {
                if ("Price".equals(header)) {
                    // 单独处理价格列:写入数值类型并应用样式
                    if (value instanceof Number) {
                        double priceValue = ((Number) value).doubleValue();
                        Cell cell = row.createCell(colNum);
                        cell.setCellValue(priceValue);
                        cell.setCellStyle(numericStyle);
                    } else {
                        // 若Price返回字符串,尝试解析为数值(根据实际情况调整异常处理)
                        try {
                            double priceValue = Double.parseDouble(value.toString());
                            Cell cell = row.createCell(colNum);
                            cell.setCellValue(priceValue);
                            cell.setCellStyle(numericStyle);
                        } catch (NumberFormatException e) {
                            row.createCell(colNum).setCellValue("");
                        }
                    }
                } else {
                    // 其他列按原逻辑写入字符串
                    row.createCell(colNum).setCellValue(value.toString());
                }
            } else {
                row.createCell(colNum).setCellValue("");
            }
            colNum++;
        }
    }

    for (var i = 0; i < headerValues.length; i++) {
        sheet.autoSizeColumn(i);
    }

    String path = Objects.requireNonNullElse(outputPath, "report.xlsx");
    writeToFile(workbook, path, LOG);
}

补充说明:

  • 之前的sheet.setDefaultColumnStyle(15, numericStyle)无效,一是列索引错误(Price列是第2列,索引从0开始应为2),二是单元格存储的是字符串,样式无法覆盖数据类型的本质问题。
  • 若Results类的getPrice()返回BigDecimal、Double等数值类型,直接用((Number)value).doubleValue()即可;若返回字符串,需额外处理解析异常。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:52:45