Java实战-优雅的合并Excel列中的相同内容

Java实战-优雅的合并Excel列中的相同内容_第1张图片

前言

最近有一个业务需求是这样的:为了方便展示数据,需要对收集到的数据需要输出为 Excel 文件,并且要按型号及坐标字段合并列

原始数据如下所示

tips:此处只是将测试数据放到Excel中展示,实际情况并不是从Excel中读取的。 用Excel是为了更直观的展示列的内容

Java实战-优雅的合并Excel列中的相同内容_第2张图片

想要达到的效果如下

需要达到的效果就是合并 型号坐标 中相同的内容,

Java实战-优雅的合并Excel列中的相同内容_第3张图片

一、思路

当我接到这个需求的时候,第一时间就去度娘上找了半天。发现大部分都是使用POI来操作的,比较繁琐,而且扩展性不高

于是我就想看一下开源工具类 EasyExcel 原生能不能支持这个功能,不出所料也是没有的。所以只能自己撸一个工具类了。

我充分的考虑到了使用的便利性扩展性,此处使用了 自定义注解 + 策略模式 来实现的。大致的思路主要分为以下两个部分:

  1. 使用自定义注解标识需要合并的列
  2. 使用策略模式扫描数据列表,利用 CellRangeAddress 生成合并策略,即告诉 POI 在写入Excel时需要合并的列的起始位置、列的结束位置、行的起始位置以及行的结束位置

因为 是基于 POI 来实现的,所以它是支持在写入时指定合并策略的。

涉及到的一些概念:
POI:Apache开源的Java处理Office文档的工具包
EasyExcel:阿里开源的读写Excel的工具包(基于POI)
WriteHandler:写入策略接口(CellWriteHandler 继承此接口)
CellRangeAddress:单元格合并对象,new 实例时的四个参数分别为列的起始位置、列的结束位置、行的起始位置以及行的结束位置

二、实现

因为考虑到后期的维护,所以对实现部分做细致的划分。

实现代码

自定义注解

合并模式注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MergeModel {
   

    /**
     * 1 means col merge
     * 2 means row merge
     */
    int type() default 1;
}

待合并的字段注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface CellMerge {
   
    // default:merger the col with same val
    MergeType type() default MergeType.Col_Repeat_Val;

    // col index
    int index() default -1;
}

上下文对象

/**
 * 合并上下文
 */
public class MergeContext<T> {
   
    // 具体的策略对象
    private MergeStrategy<T> strategy;
    private Class<?> clazz;

    private MergeContext(MergeStrategy<T> strategy) {
   
        this.strategy = strategy;
    }

    /**
     * 外部需走此处
     */
    public static class Holder {
   
        /**
         * 构建上下文
         */
        public static MergeContext build(Class clazz) {
   
            MergeContext context = null;
            if (clazz.isAnnotationPresent(MergeModel.class)) {
   
                MergeModel model = (MergeModel) clazz.getAnnotation(MergeModel.

你可能感兴趣的:(#,Java,java,poi,excel)