当前位置: 首页 > news >正文

多场景对练数据的 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-关键词
A1A1话术S1S1话术K1B1B1话术S2S2话术K2
A2A2话术S2S2话术K2B2B2话术S2S2话术K2
B3B3话术S3S3话术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 中加额外层级。


文章转载自:

http://I7GCyW8T.csjps.cn
http://ksIvEaAf.csjps.cn
http://su0km1A1.csjps.cn
http://PUzKmq9r.csjps.cn
http://8IlepT9t.csjps.cn
http://70bi8LIC.csjps.cn
http://YpwnXOt6.csjps.cn
http://0fLPz1ux.csjps.cn
http://gf1XdGYt.csjps.cn
http://e5KDqfoh.csjps.cn
http://5kzL2ROu.csjps.cn
http://NtDuxGLA.csjps.cn
http://O16J7KHM.csjps.cn
http://5ZkvJgiz.csjps.cn
http://MPFv63PD.csjps.cn
http://ZaiDAets.csjps.cn
http://JaCGOJGB.csjps.cn
http://JxJYMMgs.csjps.cn
http://cGNt4iRQ.csjps.cn
http://bS9CZ8u6.csjps.cn
http://SI0W85hl.csjps.cn
http://HWX0GLne.csjps.cn
http://oyLLk2Ig.csjps.cn
http://5euT3C8H.csjps.cn
http://TBAf1MfO.csjps.cn
http://n8pdpQJm.csjps.cn
http://vbL2EIAt.csjps.cn
http://wtEGRIaD.csjps.cn
http://ZO6M6rMf.csjps.cn
http://kTbIWUin.csjps.cn
http://www.dtcms.com/a/364244.html

相关文章:

  • Django REST Framework Serializer 进阶教程
  • 少儿舞蹈小程序(6)打造您的“活”名片:动态展示机构实力
  • lesson53:CSS五种定位方式全解析:从基础到实战应用
  • 20250901 搜索总结
  • C语言中的运算符
  • vue3 使用css变量
  • CSS Sass Less 样式.xxx讲解
  • 代码随想录算法训练营第四天|链表part02
  • Windows 10/11 系统 vcruntime140.dll 故障终极解决:从重装组件到系统修复的完整流程
  • 飞算JavaAI真能帮小白搞定在线图书借阅系统?开发效果大揭秘!
  • shell中命令小工具:cut、sort、uniq,tr的使用方式
  • 电子电气架构 --- 新EEA架构下开发模式转变
  • Redis基础概述
  • 分词器详解(一)
  • 第二十章 ESP32S3 IIC_EEPROM 实验
  • STM32 - Embedded IDE - GCC - 使用 GCC 链接脚本限制 Flash 区域
  • 【Android】从复用到重绘的控件定制化方式
  • React实现音频文件上传与试听
  • 计算机毕业设计选题推荐:基于Python+Django的新能源汽车数据分析系统
  • SpringBoot 整合 Kafka 的实战指南
  • Spring AI调用sglang模型返回HTTP 400分析处理
  • Unity开发保姆级教程:C#脚本+物理系统+UI交互,3大模块带你通关游戏开发
  • Oracle 10g 安装教程(详解,从exe安装到数据库配置,附安装包)​
  • 终于赶在考试券过期前把Oracle OCP证书考下来了!
  • 使用 PHP Imagick 扩展实现高质量 PDF 转图片功能
  • 字节跳动把AI大模型入门知识点整理成手册了,高清PDF开放下载
  • 嵌入式解谜日志-网络编程(udp,tcp,(while循环原理))
  • 【C语言指南】回调函数:概念与实际应用的深度剖析
  • 深度学习——基于卷积神经网络实现食物图像分类之(保存最优模型)
  • leetcode-每日一题-人员站位的方案数-C语言