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

文章目录

一、背景

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

二、实现

1、写法一

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

2、写法二

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

java 复制代码
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

相关推荐
zzzgd81632 分钟前
easyexcel实现自定义的策略类, 最后追加错误提示列, 自适应列宽,自动合并重复单元格, 美化表头
java·excel·表格·easyexcel·导入导出
友善的鸡蛋33 分钟前
解决:使用EasyExcel导入Excel模板时出现数据导入不进去的问题
java·easyexcel·excel导入
马剑威(威哥爱编程)6 天前
Java EasyExcel 导出报内存溢出如何解决
java·开发语言·easyexcel
飞廉灬少将14 天前
EasyExcel_动态表头的导入导出
java·easyexcel·1024程序员节
树欲静而风不止14 天前
Easy Excel合并单元格情况简单导入导出
easyexcel·1024程序员节·合并单元格
-南帝-21 天前
EasyExcel填充模板导出excel.xlsx
java·excel·poi·easyexcel·模板导出
weixin_4304317325 天前
EasyExcel读入数字类型数据时出现小数位丢失精度问题
java·spring boot·excel·easyexcel
碎像2 个月前
EasyExcel 快速入门
java·spring boot·easyexcel
記億揺晃着的那天2 个月前
EasyExcel 文件导出:表头与内容样式简单设置
java·easyexcel·文件导出