多场景对练数据的 Excel 横向导出方案(EasyExcel 动态表头实践)

一、背景

在日常开发中,我们经常需要将复杂的场景数据导出成 Excel 文件,方便运营或培训人员查看。

比如"客户与学员对练场景"这种数据,原始结构大致如下:

  • 多个场景(List<LearnHouseScene2Vo>)

  • 每个场景里有 若干轮对话(List<SceneItem>)

一个 SceneItem 就是一轮对话:

  • 客户节点

  • 客户话术

  • 学员节点

  • 学员标准话术

  • 关键词

需求:

希望在 Excel 中导出成:

  • 每个场景占 5 列(客户节点、客户话术、学员节点、学员标准话术、关键词)

  • 多个场景横向拼接

  • 每行对应第几轮对话,不足的用空白填充

二、需求分析

举个例子:

  • 场景1 有 2 轮

  • 场景2 有 3 轮

期望的 Excel:

场景1-客户节点 场景1-客户话术 场景1-学员节点 场景1-学员标准话术 场景1-关键词 场景2-客户节点 场景2-客户话术 场景2-学员节点 场景2-学员标准话术 场景2-关键词
A1 A1话术 S1 S1话术 K1 B1 B1话术 S2 S2话术 K2
A2 A2话术 S2 S2话术 K2 B2 B2话术 S2 S2话术 K2
B3 B3话术 S3 S3话术 K3

三、解决方案

  1. 动态表头

    每个场景占 5 列,表头通过循环生成,使用 EasyExcel 的多级表头功能。

  2. 数据行构造

    • 先计算所有场景的最大对话轮数 maxRow

    • 遍历 0 ~ maxRow-1,每一行拼接所有场景的对应对话

    • 不足的补空字符串

四、实体类

复制代码
@Data
public class SceneItem {

    @ExcelProperty("客户节点")
    private String customerNode;
    @ExcelProperty("客户话术")
    private String customerScript;
    @ExcelProperty("学员节点")
    private String studentNode;
    @ExcelProperty("学员标准话术")
    private String studentScript;
    @ExcelProperty("关键词")
    private String keyword;
}

@Data
public class LearnHouseScene2Vo {

    // 存储动态数量的场景组
    private List<SceneItem> sceneItems = new ArrayList<>();

    /**
     * 向当前场景组中追加一个对话节点
     */
    public void addSceneItem(SceneItem item) {
        sceneItems.add(item);
    }

}

五、工具类实现

复制代码
import com.alibaba.excel.EasyExcel;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SceneExcelExporter {

    /**
     * 导出场景对练数据到 Excel
     *
     * @param scenes 多个场景
     * @param out    输出流
     */
    public static void export(List<LearnHouseScene2Vo> scenes, OutputStream out) {
        List<List<String>> head = buildHead(scenes);
        List<List<String>> data = buildData(scenes);

        EasyExcel.write(out)
                .head(head)
                .sheet("场景对练")
                .doWrite(data);
    }

    /**
     * 构造动态表头
     */
    private static List<List<String>> buildHead(List<LearnHouseScene2Vo> scenes) {
        List<List<String>> head = new ArrayList<>();
        for (int i = 0; i < scenes.size(); i++) {
            int idx = i + 1;
            head.add(Arrays.asList("场景" + idx, "客户节点"));
            head.add(Arrays.asList("场景" + idx, "客户话术"));
            head.add(Arrays.asList("场景" + idx, "学员节点"));
            head.add(Arrays.asList("场景" + idx, "学员标准话术"));
            head.add(Arrays.asList("场景" + idx, "关键词"));
        }
        return head;
    }

    /**
     * 构造数据行
     */
    private static List<List<String>> buildData(List<LearnHouseScene2Vo> scenes) {
        int maxRow = scenes.stream()
                .mapToInt(vo -> vo.getSceneItems().size())
                .max().orElse(0);

        List<List<String>> rows = new ArrayList<>();
        for (int r = 0; r < maxRow; r++) {
            List<String> row = new ArrayList<>();
            for (LearnHouseScene2Vo vo : scenes) {
                if (r < vo.getSceneItems().size()) {
                    SceneItem item = vo.getSceneItems().get(r);
                    row.add(item.getCustomerNode());
                    row.add(item.getCustomerScript());
                    row.add(item.getStudentNode());
                    row.add(item.getStudentScript());
                    row.add(item.getKeyword());
                } else {
                    // 补空白
                    row.add(""); row.add(""); row.add(""); row.add(""); row.add("");
                }
            }
            rows.add(row);
        }
        return rows;
    }
}

六、使用方式

复制代码
List<LearnHouseScene2Vo> scenes = findUrlGetSPBlockingData3(url); // 解析后的场景数据
try (OutputStream out = new FileOutputStream("场景对练.xlsx")) {
    SceneExcelExporter.export(scenes, out);
}

七、总结

  • 核心点:多场景横向导出,本质是动态生成表头 + 按行拼接数据。

  • 通用性 :这个 SceneExcelExporter 工具类可以复用在任何类似的"多组相同字段横向导出"需求中。

  • 扩展点:如果需要在 Excel 顶部加一行大标题,可以在 EasyExcel 写出前用 POI 或者在 head 中加额外层级。

相关推荐
2601_962780912 小时前
2027采购岗准备:大数据管理与应用专业如何把Excel、SQL变成业务能力
excel
开开心心_Every3 小时前
文件查重软件批量删除重复文件释放空间
java·开发语言·c#·计算机外设·ocr·excel·perl
泡海椒4 小时前
Spring 项目中如何组织 JQuick-Excel 的 XML 与 Bean
xml·spring·excel
死磕音视频5 小时前
Microsoft Copilot 办公入门:在 Word、Excel、PowerPoint 里用 AI 完成日常文档工作
word·excel·copilot·办公效率
Access开发易登软件5 小时前
我全新开发了一套 Access 通用 Excel 导入工具,现在开源了
数据库·microsoft·excel·mfc·vba·access·access开发
泡海椒5 小时前
图表与主题如何设计扩展:基于 JQuick-Excel 现有工厂的工程化做法
excel
积流成海5 小时前
CSV与JSON转换:RFC 4180 转义规则与 Excel 中文乱码
json·excel·盘子工具站
小麦项目管理指南7 小时前
弱电工程管理,用 Excel 还是项目管理软件?5 个该换系统的信号
excel
Sadie_d18 小时前
Excel管理研发项目有哪些问题?什么情况要升级项目管理系统?
excel·项目管理·研发管理
Metaphor69221 小时前
如何快速拆分超大 Excel 文件【Python 教程】
python·excel