注意: 本文只适用于EasyExcel模板填充的场景

思路

​ 在Excel单元格中,可以利用公式设置数据的约束,也可以理解成限制数据的来源范围。例如:

7887c1c9e08a9f5618195047f1942f4f.png

​ 设置公式的方式:选中需要设置公式约束的列或者单元格,切换到【数据】栏,选择有效性选项,然后在弹出框选择【序列】,最后在【来源】处填入公式:=INDIRECT("选择项定义!C2:C"&COUNTA(选择项定义!C:C))

7fd312e4df913c2d1a3d0634e8ad4c06.png

4f8efcb4b38070b37fa3ee868771ffc4.png

这里对公式进行一下解释说明,可根据实际情况,做处调整:

915189f9f19b408408db80524f7206a8.png

到这里,思路就很明确了,只需要预先在模板中设置好公式,再利用EasyExcel的列表填充必要的候选数据列,就可以实现了

程序示例及效果

  • 模板示例

    1582fd08e2867fca569a403130ac63a8.png

  • 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public class WriteWithTemplateTest {

    public static void main(String[] args) {
    dynamicFillUp();
    }
    private static void dynamicFillUp() {
    // 最终输出的文件路径
    String outputFile = "D:/data/result.xlsx";
    // 模板路径
    String templateFile = "D:/data/template.xlsx";
    try (ExcelWriter excelWriter = EasyExcel.write(outputFile).withTemplate(templateFile).build()) {
    // 获取数据源所在的sheet页的写对象,下边从 0 开始
    WriteSheet writeSheet = EasyExcel.writerSheet(1).build();
    FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.VERTICAL).build();
    // 拿到候选数据,
    List<CellDownDropValue> cellDownDropValues = buildDownDropData();
    // 这里 【country】的key值, 要与excel模板中的列表的key对应上,如: {country.value}
    excelWriter.fill(new FillWrapper("country", cellDownDropValues), fillConfig, writeSheet);

    // 填充第一个sheet页的默认数据
    writeSheet = EasyExcel.writerSheet(0).build();
    Map<String, String> defautValues = new HashMap<>();
    defautValues.put("defCountry", "中国");
    defautValues.put("name", "尼古拉斯、赵四");
    excelWriter.fill(defautValues, writeSheet);
    }
    }
    // 实际业务,动态获取
    private static List<CellDownDropValue> buildDownDropData() {
    CellDownDropValue china = new CellDownDropValue("中国");
    CellDownDropValue us = new CellDownDropValue("美国");
    CellDownDropValue uk = new CellDownDropValue("英国");
    CellDownDropValue jp = new CellDownDropValue("日本");
    return Arrays.asList(china, us ,uk, jp);
    }
    }
  • 最终渲染的效果

    98f8e4e7adb7e1ac1f071e7b3b62036a.png

简单总结

​ 最初想的是能不能利用EasyExcel扩展Handler的方式来为单元格设置下拉框约束方式,试过了发现不行,不知道是不是姿势不对。然后是想直接在代码里设置excel公式来实现,网上查了很多资料,没有自己想要的效果,而且官方好像也不推荐直接在程序中设置公式。最终选择了这种方式。代码不复杂也好理解,算是一种曲线救国的方式吧。