使用easyexcel对导出表格添加合计行

文章目录

    • 一、背景
    • 二、实现
      • 1、写法一
      • 2、写法二
    • 三、遇到的问题
    • 四、参考

一、背景

近期开发的一个新功能需要导出和前端展示样式一致的统计表格,而前端使用的elementui的table组件,show-summary属性选择后可以自动计算。后端导出时其他单元格与返回前端展示时一致,但最后一行的合计行需要后端计算并填充。

二、实现

1、写法一

可以参考issue中填充模板形式,代码略。

2、写法二

由于表头和行数量是动态的,我是采取构造dataList和header的方式,未读取模板文件。部分逻辑为伪代码。

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.data.FormulaData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.google.common.collect.Lists;
import org.apache.poi.ss.usermodel.Workbook;

import java.util.List;

public class ExcelTest {
    public void download() {
        try {
            ExcelWriter excelWriter = EasyExcel.write("需要生成的文件名.xlsx").inMemory(true).build();
            WriteSheet mainSheet = EasyExcel.writerSheet(0, "需要写入的sheet名").head(buildHeadTitles("123")).build();
            excelWriter.write(buildData("123"), mainSheet);
            Workbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();
            workbook.setForceFormulaRecalculation(true);
            workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();
            excelWriter.finish();
            // 传给前端的相关逻辑
        } catch (Exception e) {
            // 异常处理
        }
    }

    private List<List<String>> buildHeadTitles(String targetId) {
        // 构建动态表头,相邻两个同名表头会默认合并
        // 这里的Lists是com.google.guava下的 com.google.common.collect.Lists
        List<List<String>> headTitles = Lists.newArrayList();
        // 第一列
        headTitles.add(Lists.newArrayList("团队统计", "姓名", "姓名"));
        headTitles.add(Lists.newArrayList("团队统计", "机构名称", "机构名称"));
        // 查询并类似上面格式添加动态列
        headTitles.add(Lists.newArrayList("团队统计", "分类1", "动态列1"));

        return headTitles;
    }

    private List<List<Object>> buildData(String targetId) {
        ListList<Object>> dataList = Lists.newArrayList();
        // 循环塞数据行 =========== 循环开始
        // 最后一行塞数据的其中一个单元格公式示例如下
        // 在前面构造的公式字符串
		List<Object> list = new ArrayList<>():
		// 先塞其他数据
		list.add("syz");
		list.add("顶级机构");
		list.add("1");
        String formulaStr = "SUM(VALUE(D4),VALUE(E4),VALUE(F4))";
        WriteCellData<String> formula = new WriteCellData<>();
        FormulaData formulaData = new FormulaData();
        formula.setFormulaData(formulaData);
        formulaData.setFormulaValue(formulaStr);
        list.add(formula);
        dataList.add(list)
        // ============= 循环结束
        return dataList;
    }
}

三、遇到的问题

  • 需要注意的是只有3.0.0+版本,才包含WriteCellData类,以及对应的formulaData的内部类,workbook相关的计算属性才会被调用,否则不会生效。此前2.0.0+的版本,找了半天设置未生效原因,翻了下workbook设置源码和相关issue才发现。
  • 计算序号与字母转换时可以善用hutool工具包的ExcelUtil,已提供了序号到字母的转换,从0开始,如0-A,1-B。。。26-AA。。。等等,便于公式计算行和列。

四、参考

https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write
https://github.com/alibaba/easyexcel/issues/3242
https://github.com/alibaba/easyexcel/issues/1464

你可能感兴趣的:(easyexcel)