目录

工欲善其事

实践出真知

活跃标签: linux java mysql 待分类 windows js win10 springboot pdf idea docker 电路 esp32 vue macOS nginx git Arduino maven ffmpeg

存档:

X

EasyExcel复杂表头读写,合并表头读写

JAVA版本:1.8.0_321,所需的maven依赖:

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.1.0</version>
    </dependency>

    <!-- lombok 非必要 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
        <scope>provided</scope>
    </dependency>

    <!-- fastjson非必要 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.70</version>
    </dependency>

1,读取复杂表头的Excel内容:

最简单的方法是,通过@ExcelProperty(index = 0) 指定实体类字段对应的列序号,读取的时候通过 .headRowNumber(2)设置需要跳过的表头行数。

Excel示例:

image.png

方法一:

@Data
@ExcelIgnoreUnannotated
public class Tr08StatisticsDto {

    //     样品名称
    @ContentLoopMerge(eachRow = 2) 合并行
    @ExcelProperty(value = {"样品名称", "样品名称"})
    private String sampleName;

    // 样品编号
    @ExcelProperty(value = {"公共", "样品编号"}) 设置表头两个表头
    private String sampleCode;

    // 采样地点
    @ExcelProperty(value = {"公共", "采样地点"})
    private String place;

    // 采样日期t3
    @ExcelProperty(value = "采样日期t3")
    private LocalDateTime sampleDateT3;

    // 测量日期
    @ExcelProperty(value = "测量日期")
    private LocalDateTime measureDate;

}

ExcelProperty

2.1 作用

ExcelProperty注解用于匹配excel和实体类字段之间的关系。

可以作用于字段上

名称默认值描述
value用于匹配excel中的头,必须全匹配,如果有多行头,会匹配最后一行头
orderInteger.MAX_VALUE优先级高于value,会根据order的顺序来匹配实体和excel中数据的顺序
index-1优先级高于valueorder,会根据index直接指定到excel中具体的哪一列
converter自动选择指定当前字段用什么转换器,默认会自动选择。写的情况下只要实现
@Getter
@Setter
@EqualsAndHashCode
public class DemoData {
    @ExcelProperty("字符串标题")
    private String title;
  
    // 在这个字段前面加上 自定义三个字
    @ExcelProperty(value = "conver的使用", converter = CustomStringStringConverter.class)
    private String convert;
  
    @ExcelProperty(value = "日期标题", index = 3)
    private Date date;
  
    @ExcelProperty(value = "数字标题", index = 5)
    private Double doubleData;
}
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.WriteCellData;

/**
 * 定义一个字符串转换器,需要实现Converter接口并且传递需要转换的泛型
 */
public class CustomStringStringConverter implements Converter<String> {
  
    // 所支持的java类型
    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }

    // 所支持的Excel枚举类型
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    /**
     * 这里读的时候会调用
     * @param context	上下文对象  可以获取当前读的单元格的文字内容
     * @return			格式化后的值
     */
    @Override
    public String convertToJavaData(ReadConverterContext<?> context) {
        return "自定义:" + context.getReadCellData().getStringValue();
    }

    /**
     * 这里是写的时候会调用 通常情况可以不用管
     * @return
     */
    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) {
        return new WriteCellData<>(context.getValue());
    }

}

注意点:

1)关于index

如果所有字段都不加index的话,默认index会从0开始,最早的声明的字段的名字的index的值就是0。

之后字段的index就从0开始递增,依次类推。index是几决定了该字段数据会赋值给Excel中的第几列。

如果不想按这个顺序把数据写到Excel当中。那么就可以手动设置index的值,把字段写到想要的列中去。

如果index相同,直接会抛出异常,因为程序无法判断这个列放那个字段。

2)关于order

index和order虽然都决定顺序,但是两者语义不同:

如果order和index同时使用,index优先占据位置,order再进行排序。

index=-1的话,使用jJava进行默认排序。

order的默认值为Integer.MAX_VALUE,其中order的值越小,列越靠前。

ContentLoopMerge

11.1 作用

用于合并单元格。

可以作用于字段上。

11.2 注解参数

名称默认值描述
eachRow1用于设置当前列每隔几行合并一次单元格
columnExtend1用于合并列
@data
public class DemoData {
    // 单前列每隔两行合并一次单元格
    @ContentLoopMerge(eachRow = 2)
    @ExcelProperty("字符串标题")
    private String string;
}

EasyExcel格式化映射注解和样式注解详解_excelproperty_流水武qin的博客-CSDN博客

方法二

写代码处理


标题:EasyExcel复杂表头读写,合并表头读写
作者:llilei
地址:http://solo.llilei.work/articles/2023/12/01/1701395298058.html