ExcelUtils导入excel,自动对负数金额格式化的问题

大坑

今日开发中遇到一个问题,使用ExcelUtils导入excel,excel中有一列为金额字段,有负数 ,例如-2.94,发现在导入后被自动转换为了-3.00,只有负数会这样

负数会进行以下操作

复制代码
(new DecimalFormat("0")).format(o)

解决方案:

1.手写ExcelUtils

java 复制代码
package com.chinaums.common.utils.sql;

import com.chinaums.common.annotation.Excel;
import com.chinaums.tools.DateUtils;
import com.chinaums.tools.StringUtils;
import com.chinaums.tools.converter.Convert;
import com.chinaums.tools.reflect.ReflectUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

import static com.chinaums.tools.poi.ExcelUtils.reverseByExp;

/**
 * Bean 工具类
 */
public class ExcelUtils<T> {
    private static final Logger log = LoggerFactory.getLogger(com.chinaums.tools.poi.ExcelUtils.class);
    public static final int sheetSize = 65536;
    private String sheetName;
    private Excel.Type type;
    private Workbook wb;
    private Sheet sheet;
    private List<T> list;
    private List<Object[]> fields;
    public final Class<T> clazz;

    public ExcelUtils(Class<T> clazz) {
        this.clazz = clazz;
    }

    public List<T> importExcel(String sheetName, InputStream is) throws Exception {
        this.type = Excel.Type.IMPORT;
        this.wb = WorkbookFactory.create(is);
        List<T> list = new ArrayList();
        Sheet sheet;
        if (StringUtils.isNotEmpty(sheetName)) {
            sheet = this.wb.getSheet(sheetName);
        } else {
            sheet = this.wb.getSheetAt(0);
        }

        if (sheet == null) {
            throw new IOException("文件sheet不存在");
        } else {
            int rows = sheet.getPhysicalNumberOfRows();
            if (rows > 0) {
                Map<String, Integer> cellMap = new HashMap();
                Row heard = sheet.getRow(0);

                for (int i = 0; i < heard.getPhysicalNumberOfCells(); ++i) {
                    String value = this.getCellValue(heard, i).toString();
                    cellMap.put(value, i);
                }

                Field[] allFields = this.clazz.getDeclaredFields();
                Map<Integer, Field> fieldsMap = new HashMap();
                Field[] var10 = allFields;
                int var11 = allFields.length;

                for (int var12 = 0; var12 < var11; ++var12) {
                    Field field = var10[var12];
                    Excel attr = (Excel) field.getAnnotation(Excel.class);
                    if (attr != null && (attr.type() == Excel.Type.ALL || attr.type() == this.type)) {
                        field.setAccessible(true);
                        Integer column = (Integer) cellMap.get(attr.name());
                        fieldsMap.put(column, field);
                    }
                }

                for (int i = 1; i < rows; ++i) {
                    Row row = sheet.getRow(i);
                    T entity = null;
                    Iterator var25 = fieldsMap.entrySet().iterator();

                    while (var25.hasNext()) {
                        Map.Entry<Integer, Field> entry = (Map.Entry) var25.next();
                        Object val = this.getCellValue(row, (Integer) entry.getKey());
                        entity = entity == null ? this.clazz.newInstance() : entity;
                        Field field = (Field) fieldsMap.get(entry.getKey());
                        Class<?> fieldType = field.getType();
                        if (String.class == fieldType) {
                            String s = Convert.toStr(val);
                            if (StringUtils.endsWith(s, ".0")) {
                                val = StringUtils.substringBefore(s, ".0");
                            } else {
                                val = Convert.toStr(val);
                            }
                        } else if (Integer.TYPE != fieldType && Integer.class != fieldType) {
                            if (Long.TYPE != fieldType && Long.class != fieldType) {
                                if (Double.TYPE != fieldType && Double.class != fieldType) {
                                    if (Float.TYPE != fieldType && Float.class != fieldType) {
                                        if (BigDecimal.class == fieldType) {
                                            val = Convert.toBigDecimal(val);
                                        } else if (Date.class == fieldType) {
                                            if (val instanceof String) {
                                                val = DateUtils.parseDate(val);
                                            } else if (val instanceof Double) {
                                                val = DateUtil.getJavaDate((Double) val);
                                            }
                                        }
                                    } else {
                                        val = Convert.toFloat(val);
                                    }
                                } else {
                                    val = Convert.toDouble(val);
                                }
                            } else {
                                val = Convert.toLong(val);
                            }
                        } else {
                            val = Convert.toInt(val);
                        }

                        if (StringUtils.isNotNull(fieldType)) {
                            Excel attr = (Excel) field.getAnnotation(Excel.class);
                            String propertyName = field.getName();
                            if (StringUtils.isNotEmpty(attr.targetAttr())) {
                                propertyName = field.getName() + "." + attr.targetAttr();
                            } else if (StringUtils.isNotEmpty(attr.readConverterExp())) {
                                val = reverseByExp(String.valueOf(val), attr.readConverterExp());
                            }

                            ReflectUtils.invokeSetter(entity, propertyName, val);
                        }
                    }

                    list.add(entity);
                }
            }

            return list;
        }
    }

    public Object getCellValue(Row row, int column) {
        if (row == null) {
            return null;
        } else {
            Object val = "";

            try {
                Cell cell = row.getCell(column);
                if (cell != null) {
                    if (cell.getCellTypeEnum() != CellType.NUMERIC && cell.getCellTypeEnum() != CellType.FORMULA) {
                        if (cell.getCellTypeEnum() == CellType.STRING) {
                            val = cell.getStringCellValue();
                        } else if (cell.getCellTypeEnum() == CellType.BOOLEAN) {
                            val = cell.getBooleanCellValue();
                        } else if (cell.getCellTypeEnum() == CellType.ERROR) {
                            val = cell.getErrorCellValue();
                        }
                    } else {
                        val = cell.getNumericCellValue();
                        if (HSSFDateUtil.isCellDateFormatted(cell)) {
                            val = DateUtil.getJavaDate((Double) val);
                        } else if ((Double) val % 1.0 > 0.0) {
                            val = (new DecimalFormat("0.00")).format(val);
                        }
                    }
                }

                return val;
            } catch (Exception var5) {
                return val;
            }
        }
    }
}

2.优化getCellValue方法 使其不对负数金额进行处理,原样返回

3.最后附上 导入excel代码

java 复制代码
 public R elmImport(MultipartFile multipartFile) {
        //1、文件上传
        fileInfoService.uploadFile(1, 1, null, "", userId, Constants.OTHERS, multipartFile);
        //2、excel文件读取
        ExcelUtils<ElmImportVo> excelUtils = new ExcelUtils<>(ElmImportVo.class);
        //待存储数量
        List<RealTransInfoEntity> waitSaveList = new ArrayList<>();
        List<ElmImportVo> elmList;
        //3、读取校验excel信息
        try {
            elmList = excelUtils.importExcel("账单明细", multipartFile.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("--------导入失败---------");
        }
}
相关推荐
bbq粉刷匠41 分钟前
HashMap 底层原理深度拆解(二):putVal 完整链路解析(懒加载 · 链表遍历 · 尾插法)
java·开发语言·哈希算法
Sam_Deep_Thinking1 小时前
一个靠谱的C端网关服务应该包含什么内容
java·程序员·系统架构
杨运交1 小时前
[055][调度模块]Spring动态任务调度框架的设计与实现
java·后端·spring
白狐_7982 小时前
408 数据结构算法题 01:线性表暴力求解保分指南
java·数据结构·算法
流云鹤2 小时前
03Java学习day(3)
java·学习
tqs_123452 小时前
Agent智能体+Skill插件引擎+Milvus混合检索 技术沉淀
java·python·milvus
严同学正在努力2 小时前
从备份到恢复:我用 30 分钟恢复了误删的核心业务表
android·java·数据库·ai
破z晓3 小时前
javascript 导出excel表
开发语言·javascript·excel
QQ_21696290963 小时前
Spring Boot 养老院管理系统:从入住、护理到费用结算的全流程实现(源码可领)
java·spring boot·后端
cxoptics4 小时前
冰洲石分束器设计与应用
java