easyExcel 的动态列导出把文本转为数值格式,可以进行函数计算

明白了,你这个需求是 反过来的场景 👇:

✅ EasyExcel 动态列导出时

希望:

  • 看起来是"文本"的值(比如 "12.5""100"
  • 在 Excel 中是【数值格式】
  • 可以参与公式计算(SUM、AVG 等)
  • 而不是被当成【文本】

也就是说:

❌ 当前问题:被导出成"文本格式",Excel 公式算不了

✅ 目标:导出成真正的 Number 类型


🎯 核心原则

Excel 是否可参与函数计算,取决于单元格类型是否是 NUMERIC,而不是 STRING

你现在用的是动态列(head + Map / List<List>),常见错误是:

java 复制代码
map.put("金额", "123.45"); // String

Excel 会当成文本。

正确做法是:👇

👉 放 Number 类型,而不是 String

java 复制代码
map.put("金额", new BigDecimal("123.45"));
// 或
map.put("金额", 123.45);
// 或
map.put("金额", Integer.valueOf(100));

✅ 方案一(最推荐):Map 中数值字段用 Number 类型

表头

java 复制代码
List<List<String>> head = Arrays.asList(
        Collections.singletonList("商品"),
        Collections.singletonList("金额")
);

数据

java 复制代码
List<Map<String, Object>> data = new ArrayList<>();

Map<String, Object> row = new LinkedHashMap<>();
row.put("商品", "苹果");              // String
row.put("金额", new BigDecimal("12.5")); // Number
data.add(row);

导出

java 复制代码
EasyExcel.write(out)
        .head(head)
        .sheet("sheet1")
        .doWrite(data);

这样 Excel 中:

  • "金额"列是数值
  • 可以 =SUM(B2:B10)
  • 不会变成文本

✅ 方案二:如果你现在的数据是 String → 转成 Number

很多时候数据来自数据库或前端,全是 String,例如:

java 复制代码
row.put("金额", "123.45");

你需要在导出前转换:

java 复制代码
String moneyStr = (String) row.get("金额");
row.put("金额", new BigDecimal(moneyStr));

或者统一处理:

java 复制代码
Object value = row.get(key);
if (value instanceof String && value.toString().matches("-?\\d+(\\.\\d+)?")) {
    row.put(key, new BigDecimal(value.toString()));
}

✅ 方案三:自定义 Converter(动态列场景也可用)

如果你想自动把 String 数字转为 Number:

java 复制代码
public class StringToNumberConverter implements Converter<String> {

    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.NUMBER;
    }

    @Override
    public WriteCellData<?> convertToExcelData(String value,
            ExcelContentProperty contentProperty,
            GlobalConfiguration globalConfiguration) {

        if (value == null) return new WriteCellData<>("");
        return new WriteCellData<>(new BigDecimal(value));
    }
}

注册:

java 复制代码
EasyExcel.write(out)
    .head(head)
    .registerConverter(new StringToNumberConverter())
    .doWrite(data);

⚠️ 注意:要保证传进来的 String 真的是数字,否则会异常。


🚨 不要做的事(会导致不能计算)

❌ 1. 设置成文本格式

java 复制代码
writeCellStyle.setDataFormat((short)49); // 文本格式

这会导致 Excel 永远当字符串。

❌ 2. 在前面加 '

java 复制代码
"'123.45"

❌ 3. 所有值都用 String

java 复制代码
Map<String,Object> 全是 String

🧠 推荐实践(动态列 + 可计算)

LinkedHashMap + 区分类型:

java 复制代码
row.put("姓名", "张三");              // String
row.put("数量", 10);                 // Integer
row.put("单价", new BigDecimal("12.5"));
row.put("总价", new BigDecimal("125"));

Excel 中:

  • 数量、单价、总价 → 数值
  • 可 SUM / AVG / 公式计算
  • 姓名仍是文本

📌 总结一句话

✅ 动态列导出要能函数计算:
Map 里放 Number,不要放 String


如果你愿意,可以把你现在的代码片段贴出来(head + data 部分),比如:

java 复制代码
List<Map<String,Object>> data = ...

我可以帮你改成:

✅ 哪些字段是文本

✅ 哪些字段是数值

✅ Excel 中可以直接 SUM 的正确写法

你现在遇到的是:

1️⃣ 所有列都变成文本,公式算不了?

2️⃣ 只有部分列算不了?

3️⃣ 数据来自数据库 String?

4️⃣ 想自动识别数字字符串?

告诉我是哪一种,我给你最精准方案。

相关推荐
茶本无香几秒前
【无标题】
java·设计模式·策略模式
wangbing11258 分钟前
平台介绍-SDK包
java
亓才孓20 分钟前
[SpringIOC]NoUniqueBeanDefinitionException
java·spring
开开心心就好22 分钟前
实用PDF批量加马赛克,抹除敏感信息绿色版
java·linux·开发语言·网络·人工智能·pdf·word2vec
kong790692828 分钟前
SpringBoot Rest风格 API
java·spring boot·后端
Moshow郑锴39 分钟前
WindowsRemoteAdmin(超级马里奥像素版)专为无远程登录桌面系统打造的便携式管理工具
java·powershell·远程控制·远程桌面·系统运维
骇城迷影41 分钟前
代码随想录:栈和队列篇
java·服务器·算法
重生之后端学习1 小时前
124. 二叉树中的最大路径和
java·数据结构·算法·职场和发展·深度优先·图论
Renhao-Wan1 小时前
Java 算法实践(五):二叉树遍历与常见算法题
java·数据结构·算法
知识即是力量ol1 小时前
口语八股——计算机网络篇(终篇)
java·计算机网络·面试·八股