EasyExcel - 不固定表头,导入数据百分数、小数显示位数不全及精读丢失问题解决

一、问题描述

        在工作中遇到有一个问题,导入文件中有百分数或者是小数(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;
    }
}

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
EasyExcel 中,我们可以通过自定义表头样式策略来设置表格的标题样式。具体步骤如下: 1. 创建自定义样式类,继承 HeadStyleStrategy 类,并实现其 createHeadCellStyle 方法。 例如: ``` public class CustomHeadStyleStrategy extends HeadStyleStrategy { @Override public CellStyle createHeadCellStyle(Workbook workbook) { CellStyle cellStyle = workbook.createCellStyle(); Font font = workbook.createFont(); font.setFontName("微软雅黑"); font.setFontHeightInPoints((short) 16); font.setBold(true); cellStyle.setFont(font); cellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.index); cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); cellStyle.setAlignment(HorizontalAlignment.CENTER); cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); cellStyle.setBorderBottom(BorderStyle.THIN); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setBorderTop(BorderStyle.THIN); return cellStyle; } } ``` 2. 在写入 Excel 时,使用自定义样式类。 例如: ``` // 创建工作簿 Workbook workbook = new XSSFWorkbook(); // 设置自定义样式类 CustomHeadStyleStrategy customHeadStyleStrategy = new CustomHeadStyleStrategy(); // 写入 Excel EasyExcel.write(fileName, dataClass) .head(head) .registerWriteHandler(customHeadStyleStrategy) .sheet(sheetName) .doWrite(data); ``` 这样就可以创建自定义的表头样式了。在这个例子中,我们设置了表头字体为微软雅黑,字号为 16,加粗;背景色为淡蓝色;居中对齐;边框为细线。你可以根据自己的需求进行调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值