[alibaba/easyexcel]EasyExcel3.1.1动态为数字列设置保留两位小数不生效

2023-12-14 832 views
5

EasyExcel3.1.1动态为数字列设置保留两位小数不生效,有大佬能给点建议么? 以下是我的代码 public class CustomCellStyleStrategy extends AbstractCellStyleStrategy {

/**
 * 通用头样式
 */
private WriteCellStyle headWriteCellStyle;

/**
 * 通用内容样式
 */
private List<WriteCellStyle> contentWriteCellStyleList;

public static final Pattern pattern = Pattern.compile("^[-+]?[0-9]+\\.[0-9]+$");

public CustomCellStyleStrategy() {
    this.headWriteCellStyle = getHeadStyle();
    this.contentWriteCellStyleList = ListUtils.newArrayList(getContentStyle());
}

@Override
protected void setHeadCellStyle(CellWriteHandlerContext context) {
    if (stopProcessing(context) || headWriteCellStyle == null) {
        return;
    }
    WriteCellData<?> cellData = context.getFirstCellData();
    WriteCellStyle.merge(headWriteCellStyle, cellData.getOrCreateStyle());
    if (context.getColumnIndex() == 0) {
        // 是第一列 左对齐
        WriteCellStyle cellStyle = cellData.getOrCreateStyle();
        cellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
    }
}

@Override
protected void setContentCellStyle(CellWriteHandlerContext context) {
    if (stopProcessing(context) || CollectionUtils.isEmpty(contentWriteCellStyleList)) {
        return;
    }
    WriteCellData<?> cellData = context.getFirstCellData();

    if (context.getRelativeRowIndex() == null || context.getRelativeRowIndex() <= 0) {
        WriteCellStyle.merge(contentWriteCellStyleList.get(0), cellData.getOrCreateStyle());
    } else {
        WriteCellStyle.merge(
                contentWriteCellStyleList.get(context.getRelativeRowIndex() % contentWriteCellStyleList.size()),
                cellData.getOrCreateStyle());
    }
    if (context.getColumnIndex() == 0) {
        // 是第一列 左对齐
        WriteCellStyle cellStyle = cellData.getOrCreateStyle();
        cellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        cellData.setWriteCellStyle(cellStyle);
    }
    //        // 是否是小数,小数需要格式化 (打断点发现是执行了设置格式化的语句的)
    String stringValue = cellData.getStringValue();
    if (isDecimalPointAndNumber(stringValue)) {
        cellData.setType(CellDataTypeEnum.NUMBER);
        WriteCellStyle cellStyle = cellData.getOrCreateStyle();
        DataFormatData dataFormatData = new DataFormatData();
        dataFormatData.setFormat("0.00");
        dataFormatData.setIndex((short) 2);
        cellStyle.setDataFormatData(dataFormatData);
        cellData.setNumberValue(new BigDecimal(stringValue));
        cellData.setStringValue(null);
        cellData.setWriteCellStyle(cellStyle);
    }

    // 下边这种方式 格式化的小数点位数不对

// Cell cell = context.getCell(); // String stringCellValue = cell.getStringCellValue(); // if (isDecimalPointAndNumber(stringCellValue)) { // // 设置小数点后的位数为2位 // CellStyle cellStyle = cell.getCellStyle(); // cellStyle.setDataFormat((short)BuiltinFormats.getBuiltinFormat("0.00")); // cell.setCellType(CellType.NUMERIC); // cell.setCellValue(Double.parseDouble(stringCellValue)); // }

}

protected boolean stopProcessing(CellWriteHandlerContext context) {
    return context.getFirstCellData() == null;
}

public WriteCellStyle getHeadStyle() {
    WriteCellStyle style = new WriteCellStyle();
    // 背景天藍色
    style.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
    style.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

    // 字体设置
    WriteFont writeFont = new WriteFont();
    writeFont.setFontName("Calibri");
    // 加粗
    writeFont.setBold(true);
    // 字号
    writeFont.setFontHeightInPoints((short) 11);
    style.setWriteFont(writeFont);

    // 水平居中
    style.setHorizontalAlignment(HorizontalAlignment.CENTER);
    // 垂直居中
    style.setVerticalAlignment(VerticalAlignment.CENTER);
    // 设置自动换行
    style.setWrapped(true);
    // 设置文本收缩至合适
    style.setShrinkToFit(true);
    return style;
}

public WriteCellStyle getContentStyle() {
    WriteCellStyle style = new WriteCellStyle();
    // 水平居中
    style.setHorizontalAlignment(HorizontalAlignment.CENTER);
    // 垂直居中
    style.setVerticalAlignment(VerticalAlignment.CENTER);
    // 设置自动换行
    style.setWrapped(true);
    // 设置文本收缩至合适
    style.setShrinkToFit(true);
    return style;
}

public static boolean isDecimalPointAndNumber(String input) {
    if (StrUtil.isBlank(input)) {
        return false;
    }
    return pattern.matcher(input).find();
}

回答

1
解决EasyExcel3.1.1动态位数字列设置保留2位小数不生效 #3503 您的需求

​ 动态位数字列设置保留2位小数不生效,想要保留两位小数生效。

我的想法

​ 您好,在我复现过您的问题后,我发现了您的问题在您的

        String stringValue = cellData.getStringValue();

代码stringValue 是一个 String 类型的变量,这意味着它包含的数据会被当作字符串处理。如果您使用这个字符串值来设置 cellData 的数据类型为 NUMBER 并尝试设置数据格式,这可能无法正确工作,因为数据类型是字符串而不是数字。您应该把它正确的设置为小数类型。

如果是小数请使用进行获取,或您将它设置为正确的数据类型

cellData.getNumberValue()
image 我的尝试解决方案代码
    @Override
    protected void setContentCellStyle(CellWriteHandlerContext context) {
        if (stopProcessing(context) || CollectionUtils.isEmpty(contentWriteCellStyleList)) {
            return;
        }
        WriteCellData<?> cellData = context.getFirstCellData();

        if (context.getRelativeRowIndex() == null || context.getRelativeRowIndex() <= 0) {
            WriteCellStyle.merge(contentWriteCellStyleList.get(0), cellData.getOrCreateStyle());
        } else {
            WriteCellStyle.merge(
                    contentWriteCellStyleList.get(context.getRelativeRowIndex() % contentWriteCellStyleList.size()),
                    cellData.getOrCreateStyle());
        }
        if (context.getColumnIndex() == 0) {
            // 是第一列 左对齐
            WriteCellStyle cellStyle = cellData.getOrCreateStyle();
            cellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
            cellData.setWriteCellStyle(cellStyle);
        }

        // 是否是小数,小数需要格式化
        if (cellData.getNumberValue() != null) {
            cellData.setType(CellDataTypeEnum.NUMBER);
            WriteCellStyle cellStyle = cellData.getOrCreateStyle();
            DataFormatData dataFormatData = new DataFormatData();
            dataFormatData.setFormat("0.00");
            cellStyle.setDataFormatData(dataFormatData);
        }

        // 清空字符串值
        cellData.setStringValue(null);
    }

祝您生活愉快,工作顺利。

5

大哥您好!我想问一下,我导出的数据集类型是List<List> dataList;我要做格式化的那一列数据本省就是String 类型的。 我参照您的代码使用cellData.getNumberValue() 发现始终是null,这样有办法处理吗

0

您好,能为我提供一个测试Excel文件样本吗? 或者您更改后的代码。

6

import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.data.DataFormatData; import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.util.ListUtils; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.AbstractCellStyleStrategy; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.VerticalAlignment;

import java.util.List;

@Slf4j public class CustomCellStyleStrategy extends AbstractCellStyleStrategy {

/**
 * 通用头样式
 */
private WriteCellStyle headWriteCellStyle;

/**
 * 通用内容样式
 */
private List<WriteCellStyle> contentWriteCellStyleList;

public CustomCellStyleStrategy() {
    this.headWriteCellStyle = getHeadStyle();
    this.contentWriteCellStyleList = ListUtils.newArrayList(getContentStyle());
}

@Override
protected void setHeadCellStyle(CellWriteHandlerContext context) {
    if (stopProcessing(context) || headWriteCellStyle == null) {
        return;
    }
    WriteCellData<?> cellData = context.getFirstCellData();
    WriteCellStyle.merge(headWriteCellStyle, cellData.getOrCreateStyle());
    if (context.getColumnIndex() == 0) {
        // 是第一列 左对齐
        WriteCellStyle cellStyle = cellData.getOrCreateStyle();
        cellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
    }
}

@Override
protected void setContentCellStyle(CellWriteHandlerContext context) {
    if (stopProcessing(context) || CollectionUtils.isEmpty(contentWriteCellStyleList)) {
        return;
    }
    WriteCellData<?> cellData = context.getFirstCellData();

    if (context.getRelativeRowIndex() == null || context.getRelativeRowIndex() <= 0) {
        WriteCellStyle.merge(contentWriteCellStyleList.get(0), cellData.getOrCreateStyle());
    } else {
        WriteCellStyle.merge(
                contentWriteCellStyleList.get(context.getRelativeRowIndex() % contentWriteCellStyleList.size()),
                cellData.getOrCreateStyle());
    }
    if (context.getColumnIndex() == 0) {
        // 是第一列 左对齐
        WriteCellStyle cellStyle = cellData.getOrCreateStyle();
        cellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        cellData.setWriteCellStyle(cellStyle);
    }

    // 是否是小数,小数需要格式化
    if (cellData.getNumberValue() != null) {
        cellData.setType(CellDataTypeEnum.NUMBER);
        WriteCellStyle cellStyle = cellData.getOrCreateStyle();
        DataFormatData dataFormatData = new DataFormatData();
        dataFormatData.setFormat("0.00");
        cellStyle.setDataFormatData(dataFormatData);
        // 清空字符串值
        cellData.setStringValue(null);
    }

}

protected boolean stopProcessing(CellWriteHandlerContext context) {
    return context.getFirstCellData() == null;
}

public WriteCellStyle getHeadStyle() {
    WriteCellStyle style = new WriteCellStyle();
    // 背景天藍色
    style.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
    style.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

    // 字体设置
    WriteFont writeFont = new WriteFont();
    writeFont.setFontName("Calibri");
    // 加粗
    writeFont.setBold(true);
    // 字号
    writeFont.setFontHeightInPoints((short) 11);
    style.setWriteFont(writeFont);

    // 水平居中
    style.setHorizontalAlignment(HorizontalAlignment.CENTER);
    // 垂直居中
    style.setVerticalAlignment(VerticalAlignment.CENTER);
    // 设置自动换行
    style.setWrapped(true);
    // 设置文本收缩至合适
    style.setShrinkToFit(true);
    return style;
}

public WriteCellStyle getContentStyle() {
    WriteCellStyle style = new WriteCellStyle();
    // 水平居中
    style.setHorizontalAlignment(HorizontalAlignment.CENTER);
    // 垂直居中
    style.setVerticalAlignment(VerticalAlignment.CENTER);
    // 设置自动换行
    style.setWrapped(true);
    // 设置文本收缩至合适
    style.setShrinkToFit(true);
    return style;
}

}

导出的样例数据及表头如下: [["2023-07-01", "0", "39858.60012435913", "2023-07-01", "30421"], ["2023-07-01", "包场", "373874.9599609375", "2023-07-02", "25038"], ["2023-07-01", "周边", "-53154.40002441406", "2023-07-03", "18655"], ["2023-07-01", "球票", "-305453.900390625", "2023-07-04", "19797"], ["2023-07-01", "球票赠送", "527.0", "2023-07-05", "21309"]] [["消费时间"], ["消费类型"], ["消费金额"], ["消费时间"], ["消费订单量"]] [[消费时间], [消费类型], [消费金额], [消费时间], [消费订单量]]

if (cellData.getNumberValue() != null) 这行代码始终是false,可能是由于我的数据类型全是String