EasyExcel 直接写 Long 到 Excel 丢精度

来自姬鸿昌的知识库
Jihongchang讨论 | 贡献2026年1月27日 (二) 01:22的版本 (Jihongchang移动页面EasyExcel 写 Long 到 Excel 丢精度EasyExcel 直接写 Long 到 Excel 丢精度
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

Java 里的 Long 类型直接输出到 Excel 的数值不等于原值,所以需要转成字符串再输出到 Excel文件,需要自定义转换器:

其实叫 LongConverter 就行,放到 xx.xx.xx.common.converter.excel 包下就可以

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.Data;

// 自定义 Long 转字符串的转换器
class LongToStringConverter implements Converter<Long> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return Long.class;
    }

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

    @Override
    public Long convertToJavaData(WriteCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        return cellData.getStringValue() == null || cellData.getStringValue().isEmpty() 
                ? null : Long.valueOf(cellData.getStringValue());
    }

    @Override
    public WriteCellData<?> convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        return new WriteCellData<>(value == null ? "" : String.valueOf(value));
    }
}

// 实体类:指定自定义转换器
@Data
class SafeLongDemo {
    @ExcelProperty(value = "大数值", converter = LongToStringConverter.class)
    private Long bigNum;
}

// 测试写入(无精度丢失)
public class SafeLongWrite {
    public static void main(String[] args) {
        String filePath = "safe_long_test.xlsx";
        List<SafeLongDemo> dataList = new ArrayList<>();
        SafeLongDemo demo = new SafeLongDemo();
        demo.setBigNum(9007199254740993L); // 超过 2^53 的值
        dataList.add(demo);
        
        EasyExcel.write(filePath, SafeLongDemo.class)
                .sheet("安全写入")
                .doWrite(dataList);
        
        // 读取验证
        EasyExcel.read(filePath, SafeLongDemo.class, new PageReadListener<SafeLongDemo>(dataList1 -> {
            for (SafeLongDemo d : dataList1) {
                System.out.println("读取值:" + d.getBigNum()); // 输出 9007199254740993,无丢失
            }
        })).sheet().doRead();
    }
}