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

一、背景

近期开发的一个新功能需要导出和前端展示样式一致的统计表格,而前端使用的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

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EasyExcel是一款基于Java的开源Excel操作工具,它提供了丰富的API,可以方便地进Excel文件的读写操作。在EasyExcel中,导出合计可以通过以下步骤实现: 1. 创建ExcelWriter对象:使用`EasyExcel.write()`方法创建一个ExcelWriter对象,用于写入Excel文件。 2. 定义数据模型:创建一个Java类,用于表示Excel中的每一数据。该类的属性对应Excel中的列。 3. 准备数据:将需要导出的数据准备好,并封装到数据模型对象中。 4. 设置合计:在数据列表的最后一添加一个合计,计算需要合计的列的值。 5. 写入数据:使用`ExcelWriter.write()`方法将数据写入到Excel文件中。 下面是一个示例代码,演示了如何使用EasyExcel导出带有合计的Excel文件: ```java // 导出数据模型类 public class ExportData { private String name; private int quantity; // 其他属性... // 构造方法、getter和setter... } // 导出合计示例 public class ExportWithTotalRow { public static void main(String[] args) { // 准备数据 List<ExportData> dataList = new ArrayList<>(); dataList.add(new ExportData("A", 10)); dataList.add(new ExportData("B", 20)); dataList.add(new ExportData("C", 30)); // 创建ExcelWriter对象 String fileName = "export_with_total_row.xlsx"; ExcelWriter excelWriter = EasyExcel.write(fileName).build(); // 设置合计 Sheet sheet = new Sheet(1, 0, ExportData.class); sheet.setStartRow(1); // 数据从第2开始 sheet.setNeedHead(false); // 不需要表头 sheet.setTableStyle(createTableStyle()); // 设置表格样式 // 写入数据 excelWriter.write(dataList, sheet); // 添加合计 Row row = new Row(dataList.size() + 1); // 合计在数据列表的下一 row.createCell(0).setCellValue("合计"); row.createCell(1).setCellFormula("SUM(B2:B" + (dataList.size() + 1) + ")"); excelWriter.writeRow(row, sheet); // 关闭ExcelWriter对象 excelWriter.finish(); } // 创建表格样式 private static TableStyle createTableStyle() { TableStyle tableStyle = new TableStyle(); tableStyle.setTableContentBackGroundColor(IndexedColors.WHITE); tableStyle.setTableContentFontName("Arial"); tableStyle.setTableContentFontSize(12); // 其他样式设置... return tableStyle; } } ``` 在上述示例代码中,我们首先创建了一个`ExportData`类来表示导出的数据模型,其中包含了需要导出的列。然后,我们准备了一个数据列表`dataList`,并将数据封装到`ExportData`对象中。 接下来,我们创建了一个`ExcelWriter`对象,并指定要写入的Excel文件名。然后,我们创建了一个`Sheet`对象,并设置了一些属性,如起始、是否需要表头和表格样式。 然后,我们使用`excelWriter.write()`方法将数据列表写入到Excel文件中。 最后,我们创建了一个合计,并使用`setCellValue`方法设置合计的文本内容,使用`setCellFormula`方法设置合计的公式,计算需要合计的列的值。然后,我们使用`excelWriter.writeRow()`方法将合计写入到Excel文件中。 最后,我们关闭了`ExcelWriter`对象,完成导出操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值