[alibaba/easyexcel]非预期的表头字体属性

2024-05-10 748 views
0

触发场景描述 我的实体类有多个字段,我希望数据导出到excel后对某些字段的表头进行样式修改

触发Bug的代码 这是我的实体类示例

import cn.zswltech.easyexcel.demo.core.excel.converter.SexConverter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.poi.ss.usermodel.IndexedColors;

import java.net.URL;
import java.util.Date;

/**
 * 第一个简单的excel数据模型 需要使用easyexcel注解
 *
 * @author ertong0129
 * @date 2022/4/28 3:01 PM
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor

@HeadRowHeight(50)
@ContentRowHeight(20)
public class SimpleExcelData {

    @ExcelProperty(value = "名称", index = 0)
    @ColumnWidth(40)
    // 填充背景色的时候,需要fillPatternType属性
    @ContentStyle(fillForegroundColor = 5, fillPatternType = FillPatternTypeEnum.ALT_BARS)
    @ContentFontStyle(color = 51)
    @HeadStyle(fillForegroundColor = 5, fillPatternType = FillPatternTypeEnum.ALT_BARS)
    @HeadFontStyle(color = 51)
    private String name;

    @ExcelProperty(value = "身份证", index = 1)
    private String idCard;

    @ExcelProperty(value = "手机号", index = 2)
    private Long phone;

    @ExcelProperty(value = "性别", index = 3)
    private Integer sex;

}

这是我的测试代码

    @Test
    public void writeExcelSimple() throws Exception {
        String fileName = "/Users/wang/Desktop/测试文件夹/测试excel.xlsx";

        SimpleExcelData excelData = SimpleExcelData.builder()
                .name("测试名称")
                .sex(2)
                .idCard("460103123123")
                .phone(1525185L)
                .build();

        EasyExcel.write(fileName)
                .head(SimpleExcelData.class)
                .needHead(true)
                .autoCloseStream(true)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet("指定sheet")
                .doWrite(Arrays.asList(excelData));
    }

我定位到问题的代码

问题代码:
com.alibaba.excel.write.metadata.style.WriteCellStyle#merge 165行
        if (source.getWriteFont() != null) {
            if (target.getWriteFont() == null) {
                target.setWriteFont(source.getWriteFont());
            } else {
                WriteFont.merge(source.getWriteFont(), target.getWriteFont());
            }
        }

当以下方法执行时,会将DefaultStyle的headWriteCellStyle属性的writeFont对象赋值给cellData的writeCellStyle属性的writeFont属性
com.alibaba.excel.write.style.HorizontalCellStyleStrategy#setHeadCellStyle

在以下方法执行时,cellData的writeCellStyle属性的writeFont属性,会引发DefaultStyle的headWriteCellStyle属性的writeFont属性的修改
com.alibaba.excel.write.style.AbstractVerticalCellStyleStrategy#setHeadCellStyle

所以是否可以考虑第一段问题代码不要将source的writeFont对象给target复用,而是直接深拷贝一个新对象给target
其他merge方法复用对象的地方是否也存在这个问题?

提示的异常或者没有达到的效果 我预期第一个字段的表头导出到excel的字体使用自定义样式,第二个及之后的字段的表头导出到excel的字体使用默认样式 实际上所有的字段与第一个字段样式相同,与我预期的不符

回答

5

您好 您可以参考下demo中的DemoStyleData类。在类上增加注解@ContentStyle、@HeadStyle等。作者的设计应该是如果要个性列修改,需要先有个默认的整体类的属性。

6

您好 您可以参考下demo中的DemoStyleData类。在类上增加注解@ContentStyle、@headstyle等。作者的设计应该是如果要个性列修改,需要先有个默认的整体类的属性。

好的,感谢您,这解决了我的问题 但这确实让我有些困惑,列数据字段我并没有设置默认的整体类样式,我只是对某个字段设置了个性列修改,但它并不会影响其他列的默认属性。

9

您好 您可以参考下demo中的DemoStyleData类。在类上增加注解@ContentStyle、@headstyle等。作者的设计应该是如果要个性列修改,需要先有个默认的整体类的属性。

好的,感谢您,这解决了我的问题 但这确实让我有些困惑,列数据字段我并没有设置默认的整体类样式,我只是对某个字段设置了个性列修改,但它并不会影响其他列的默认属性。

嗯 主要和作者设计有关系 他是想类上有个默认的,如果你不设置默认的,就会把你第一个列的当成默认了。所以只要在类上加上注解就能解决问题。