明白了,你这个需求是 反过来的场景 👇:
✅ 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️⃣ 想自动识别数字字符串?
告诉我是哪一种,我给你最精准方案。