暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

EasyExcel读取EXCEL用String去接收数字,出现小数点BUG

全栈的程序员 2022-08-15
4292


在项目中经常会用到poi。奔着开箱即用的风格,自然而然的用到阿里开源的EasyExcel。

但是这个在.2.2.6 以下版本会有一个bug。那就是excel中的数字入库会有.0的问题,就是小数点,一般是18的字符以内认为是文本。入库有.0。

官方也公布了此次问题,有点类似于苹果7的彩虹版问题了。



解决方式


方法一

使用官方的NumberFormat.format()方式处理,具体方法自行百度使用。


方法二 

自定义转换器,使用时再注册进去

    import com.alibaba.excel.converters.Converter;
    import com.alibaba.excel.enums.CellDataTypeEnum;
    import com.alibaba.excel.metadata.CellData;
    import com.alibaba.excel.metadata.GlobalConfiguration;
    import com.alibaba.excel.metadata.property.ExcelContentProperty;
    import com.alibaba.excel.util.DateUtils;
    import com.alibaba.excel.util.NumberUtils;
    import org.apache.poi.hssf.usermodel.HSSFDateUtil;
    import org.apache.poi.ss.usermodel.DateUtil;
    import org.apache.poi.ss.util.NumberToTextConverter;


    import java.math.BigDecimal;
    import java.math.BigInteger;
    import java.util.regex.Pattern;


    /**
    * todo:
    *
    * @author : zhoulin.zhu
    * @date : 2020/4/28 10:17
    */
    public class CustomStringNumberConverter implements Converter<String> {


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


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


    @Override
    public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
    GlobalConfiguration globalConfiguration) {
    // If there are "DateTimeFormat", read as date
    if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) {
    return com.alibaba.excel.util.DateUtils.format(
    HSSFDateUtil.getJavaDate(cellData.getDoubleValue(),
    contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null),
    contentProperty.getDateTimeFormatProperty().getFormat());
    }
    // If there are "NumberFormat", read as number
    if (contentProperty != null && contentProperty.getNumberFormatProperty() != null) {
    return NumberUtils.format(cellData.getDoubleValue(), contentProperty);
    }


    // Excel defines formatting
    if (cellData.getDataFormat() != null) {
    if (DateUtil.isADateFormat(cellData.getDataFormat(), cellData.getDataFormatString())) {


    if(cellData.getDataFormatString().contains(":")){
    return DateUtils.format(HSSFDateUtil.getJavaDate(cellData.getDoubleValue(),
    globalConfiguration.getUse1904windowing(), null));
    } else {
    return DateUtils.format(HSSFDateUtil.getJavaDate(cellData.getDoubleValue(),
    globalConfiguration.getUse1904windowing(), null), "yyyy-MM-dd");
    }
    } else if(contentProperty == null) {
    try{
    // 百分比
    if(cellData.getDataFormatString() != null && cellData.getDataFormatString().contains("%")){
    return new BigDecimal(cellData.getDoubleValue().toString()).multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString() + "%";
    } else if(cellData.getDataFormatString() != null && cellData.getDataFormatString().equals("General")){


    //解决easyExcel 解析无 CLASS 对象时,Number to string 用String去接收数字,出现小数点等情况 方法一 会出现 数字位数失真的情况 ,即 excel 用公式计算数值后,只保留3位小数, 读取时 可能出现 直接去取保留前的N为小数的情况 建议使用方法二
    // 方法一 NumberFormat numberFormat = NumberFormat.getInstance();
    // numberFormat.setMaximumFractionDigits(20);
    // numberFormat.setGroupingUsed(false);
    // return numberFormat.format(cellData.getDoubleValue());
    // 方法二
    return NumberToTextConverter.toText(cellData.getDoubleValue());
    } else {
    return NumberToTextConverter.toText(cellData.getDoubleValue());
    // return cellData.getDoubleValue().toString();
    }
    } catch (Exception e) {
    // 建议 统一使用以下方法,可以解决数值格式问题
    return NumberToTextConverter.toText(cellData.getDoubleValue());
    // return NumberUtils.format(cellData.getDoubleValue(), contentProperty);
    }
    } else {
    return NumberToTextConverter.toText(cellData.getDoubleValue());
    // return NumberUtils.format(cellData.getDoubleValue(), contentProperty);
    }
    }
    // Default conversion number
    // NumberFormat numberFormat = NumberFormat.getInstance();
    // numberFormat.setMaximumFractionDigits(20);
    // numberFormat.setGroupingUsed(false);
    // return numberFormat.format(cellData.getDoubleValue());
    // 方法二
    return NumberToTextConverter.toText(cellData.getDoubleValue());
    // return NumberUtils.format(cellData.getDoubleValue(), contentProperty);
    }


    @Override
    public CellData convertToExcelData(String value, ExcelContentProperty contentProperty,
    GlobalConfiguration globalConfiguration) {
    return new CellData(Double.valueOf(value));
    }
    }



    调用案例

         InputStream inputStream = file.getInputStream();
      // 可以是自己的监听器
      SalaryExcelListener excelListener = new SalaryExcelListener();
      EasyExcel.read(inputStream, excelListener).registerConverter(new CustomStringNumberConverter()).sheet().doRead();



      方法三

      简单粗暴,直接改pom.xml文件的 easyexcel的版本,改为 2.2.6


      文章转载自全栈的程序员,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论