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

您所在的位置:网站首页 java整数加小数 解决easyExcel读取EXCEL用String去接收数字,出现小数点BUG

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

2023-07-24 10:08| 来源: 网络整理| 查看: 265

起因

目前项目中需要使用easyExcel 读取Excel文件,因为后端使用mongodb存储格式,数据格式不确定。因此读取文件时,未传递.class对象(指用方法一调用),使用String 接收Number 类型时,出现 .0情况。 在这里插入图片描述

本文依赖 com.alibaba easyexcel 2.0.0-beta6 org.slf4j slf4j-log4j12 log4j log4j 官方文档分析

easyExcel 官方文档描述如下, 如果传递了 .class 对象接收,则可以使用官方的NumberFormat.format()方式处理。 如果没有传递 接受对象那该如何处理呢? 在这里插入图片描述

源代码分析

easyExcel 都是通过各种 转换器(Converter) 实现的,因此我们可以找到对应 StringNumberConverter 转换器,其源代码如下: 在这里插入图片描述 在这里插入图片描述

/** * String and number converter * * @author Jiaju Zhuang */ public class StringNumberConverter implements Converter { @Override public Class supportJavaTypeKey() { return String.class; } @Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.NUMBER; } @Override public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { // 如果传递了 .class 接收,则 contentProperty 不为空 // If there are "DateTimeFormat", read as date, // 获取 contentProperty 对象上是否有加日期格式注解 if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { return DateUtils.format( HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null), contentProperty.getDateTimeFormatProperty().getFormat()); } // If there are "NumberFormat", read as number // 获取 contentProperty 对象上是否有加数字格式注解 if (contentProperty != null && contentProperty.getNumberFormatProperty() != null) { return NumberUtils.format(cellData.getDoubleValue(), contentProperty); } // Excel defines formatting // 如果没有格式注解 // 注意: 如果 Excel 为Number 类型,则 cellData.getDataFormat() = 0!!! if (cellData.getDataFormat() != null) { // 判断是否为日期格式 if (DateUtil.isADateFormat(cellData.getDataFormat(), cellData.getDataFormatString())) { return DateUtils.format(HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), globalConfiguration.getUse1904windowing(), null)); } else { // 如果不是日期格式就直接调用这个方法, 该方法会 保留 .0的情况。可以进行拓展 return NumberUtils.format(cellData.getDoubleValue(), contentProperty); } } // Default conversion number return NumberUtils.format(cellData.getDoubleValue(), contentProperty); } @Override public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return new CellData(Double.valueOf(value)); } } 解决方案

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

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 { @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(); 使用效果对比

excel 数据: 在这里插入图片描述

使用前 {0=202003.0, 1=11.0, 2=XX, 3=2000.0, 4=1000, 5=7.5} {0=202003.0, 1=90.0, 2=XX, 3=2000.0, 4=1000.0, 5=7.5} 在这里插入图片描述 使用后 {0=202003, 1=632511, 2=XX, 3=2000, 4=1000, 5=7.5} {0=202003, 1=624190, 2=XX, 3=2000, 4=1000, 5=7.5} 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3