一、问题描述
在工作中遇到有一个问题,导入文件中有百分数或者是小数(excel中显示百分数或小数,不是文本类型如图),在页面显示2位小数但实际选中后展示的数据并不只是2位小数的前提下,经过后端程序解析之后,发现解析后百分数和小数的小数点后面也只是保留了2位。
因为是动态表头不能用注解。
但是业务要求,虽然我Excel页面展示2位,但是你要把小数后面的全获取到给我
二、解决方式
方式一:解决业务
有道是解决不了需求,那就把提出需求的人解决,最简单的办法,和业务沟通你们每次Excel处理好数据再给我,例如:如果小数一共4位那就设置保留4位,让Excel页面显示4位这时再提交,百分数同理。
方式二:解决需求
当业务沟通失败那么就可以进行下一步解决需求,回导致上面的问题本质本质上是因为EasyExcel默认设置的转换器
什么的是转换器,我的理解哈,不正确欢迎指正,就是把excel的数据格式转换为Java的数据格式,就是说先获取到excel的数然后进行转化。
其执行步骤要早与监听器,所以朋友你会发现,你把断点打在自定义的监听器上,就已经晚了,已经是保留2位后的结果了
仅提供思路
以下为程序解析Excel方法
public class EasyExcelImportUtils {
/**
* 动态表头导入功能
*
* @param file 文件
* @return
*/
public static List<Map<String, Object>> importExcel(MultipartFile file) {
try {
// 首先校验传入文件是否为空
if (file == null) {
throw new BookException(2000, "传入数据为空");
}
// 引入监听器(此处需注意,监听器不可被Spring管理)
EasyExcelListener readListener = new EasyExcelListener();
// 开始处理excel
EasyExcelFactory.read(file.getInputStream(), readListener)
// 使用转换器
.registerConverter(new CustomStringNumberConverter())
.sheet(0)
.doRead();
// 获取表头(验空)
List<Map<Integer, String>> headList = readListener.getHeadList();
if (CollectionUtils.isEmpty(headList)) {
throw new RuntimeException("Excel表头不能为空");
}
// 获取表数据(验空)
List<Map<Integer, Object>> dataList = readListener.getDataList();
if (CollectionUtils.isEmpty(dataList)) {
throw new RuntimeException("Excel数据内容不能为空");
}
//获取头部,取最后一次解析的列头数据
Map<Integer, String> excelHeadIdxNameMap = headList.get(headList.size() - 1);
//封装数据体
List<Map<String, Object>> excelDataList = new ArrayList<Map<String, Object>>();
for (Map<Integer, Object> dataRow : dataList) {
HashMap<String, Object> rowData = new HashMap<>();
excelHeadIdxNameMap.entrySet().forEach(columnHead -> {
rowData.put(columnHead.getValue(), dataRow.get(columnHead.getKey()));
});
excelDataList.add(rowData);
}
return excelDataList;
} catch (Exception e) {
e.printStackTrace();
throw new BookException(2000, "导入失败");
}
}
}
以下为转换器方法
package com.book.utils.easyexcel;
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 java.math.BigDecimal;
/**
* 自定义转换器
*/
public class CustomStringNumberConverter implements Converter<String> {
//在java中数据类型
@Override
public Class supportJavaTypeKey() {
return String.class;
}
// 在excel中的数据类型
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.NUMBER;
}
/**
* 读的时候调用这里, 将excel的数据类型转为java数据类型
* @param cellData
* @param excelContentProperty
* @param globalConfiguration
* @return
* @throws Exception
*/
@Override
public String convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
String value = null;
if (cellData.getDataFormatString().equals("0.00%")){
BigDecimal numberValue = cellData.getNumberValue();
value = numberValue.multiply(new BigDecimal("100")).toString();
value = value + "%";
}else {
value = cellData.getNumberValue().toString();
}
return value;
}
/**
* 写的时候调用这里
* @param s
* @param excelContentProperty
* @param globalConfiguration
* @return
* @throws Exception
*/
@Override
public CellData convertToExcelData(String s, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
return null;
}
}