动态表头导出EasyExcel

news/2025/2/26 6:40:44

在 Spring Boot 中结合 EasyExcel 实现动态表头导出(无实体类,表头和字段(前端传表名,字段值动态查询,返回List<Map<String,Object>>)由前端传递)可以通过以下步骤实现。以下是完整示例:


1. 前端请求数据结构

假设前端传递的 JSON 格式如下:

{
  "headers": [
    {"title": "姓名", "field": "name"},
    {"title": "年龄", "field": "age"},
    {"title": "城市", "field": "city"}
  ],
  "data": [
    {"name": "张三", "age": 25, "city": "北京"},
    {"name": "李四", "age": 30, "city": "上海"}
  ]
}

2. 后端 DTO 定义

定义接收参数的 DTO 类:

@Data
public class ExportRequest {
    private List<Header> headers;
    private List<Map<String, Object>> data;

    @Data
    public static class Header {
        private String title;  // 表头名称
        private String field;  // 数据字段名
    }
}

3. Controller 层接口

处理导出请求:

@RestController
public class ExportController {

    @Autowired
    private ExportService exportService;

    @PostMapping("/export")
    public void exportExcel(@RequestBody ExportRequest request, HttpServletResponse response) {
        exportService.export(request, response);
    }
}

4. Service 层实现

核心导出逻辑:

@Service
public class ExportService {

    public void export(ExportRequest request, HttpServletResponse response) {
        try {
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            String fileName = URLEncoder.encode("动态导出.xlsx", "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

            // 获取输出流
            OutputStream outputStream = response.getOutputStream();

            // 动态构建表头和数据
            WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();

            // 动态添加表头
            WriteTable writeTable = new WriteTable();
            List<List<String>> head = buildHead(request.getHeaders());
            writeTable.setHead(head);

            // 动态填充数据
            List<List<Object>> data = buildData(request.getHeaders(), request.getData());
            excelWriter.write(data, writeSheet, writeTable);

            // 关闭流
            excelWriter.finish();
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException("导出失败", e);
        }
    }

    // 构建表头
    private List<List<String>> buildHead(List<ExportRequest.Header> headers) {
        List<List<String>> head = new ArrayList<>();
        for (ExportRequest.Header header : headers) {
            List<String> columnHead = Collections.singletonList(header.getTitle());
            head.add(columnHead);
        }
        return head;
    }

    // 构建数据行
    private List<List<Object>> buildData(List<ExportRequest.Header> headers, List<Map<String, Object>> dataList) {
        List<List<Object>> data = new ArrayList<>();
        for (Map<String, Object> rowData : dataList) {
            List<Object> row = new ArrayList<>();
            for (ExportRequest.Header header : headers) {
                row.add(rowData.get(header.getField()));
            }
            data.add(row);
        }
        return data;
    }
}

5. 关键点说明

  1. 动态表头

    • 通过 buildHead() 方法将前端传递的 headers 转换为 EasyExcel 需要的 List<List<String>> 格式。
  2. 动态数据

    • 通过 buildData() 方法,根据 headers 中定义的 field 字段顺序,从 data 中提取对应值,构建数据行。
  3. 流式导出

    • 使用 ExcelWriter 直接操作输出流,避免内存溢出(适合大数据量)。

6. 测试与验证

使用 Postman 发送请求:

  • URL: POST http://localhost:8080/export

  • Body(JSON):

    {
      "headers": [
        {"title": "姓名", "field": "name"},
        {"title": "年龄", "field": "age"},
        {"title": "城市", "field": "city"}
      ],
      "data": [
        {"name": "张三", "age": 25, "city": "北京"},
        {"name": "李四", "age": 30, "city": "上海"}
      ]
    }
    
  • 响应:浏览器自动下载 动态导出.xlsx,内容如下:

    姓名年龄城市
    张三25北京
    李四30上海

7. 扩展优化

  • 字段校验:确保前端传递的 fielddata 中存在对应值。
  • 大数据量分页:如果数据量过大,可分页查询后分批写入。
  • 自定义样式:通过 WriteHandler 动态设置单元格样式(如字体、颜色)。

通过这种方式,无需定义实体类即可实现完全动态的 Excel 导出功能,表头和字段完全由前端控制。


http://www.niftyadmin.cn/n/5868235.html

相关文章

Log | Hugo+PaperMod+Github创建自己的博客网站

0. 友情提示 以上内容是我根据我的博客构建内容中总结&#xff0c;并不是在构建过程中记录的&#xff0c;或许有错误之处&#xff0c;若存在问题&#xff0c;欢迎大家指出&#xff01; 欢迎大家关注我的个人博客网站&#xff1a;YHs Log 1. 引言 Lilian Wengs Log: LilLog 在…

MacOS 终端选型

MacOS终端工具选型与技术栈建议 一、核心工具对比矩阵 工具名称最新版本核心优势适用场景推荐指数引用来源iTerm25.3分屏/自动补全/多语言支持/全局搜索全栈开发/服务器运维⭐⭐⭐⭐⭐19Warp1.4AI智能补全/块编辑/现代UI/跨平台协作新手友好/团队协作⭐⭐⭐⭐39Tabby2.0多协议…

Spring MVC 的执行流程解析:从用户请求到响应返回

Spring MVC 是一种基于 Model-View-Controller 设计模式的 Web 框架&#xff0c;用于处理用户请求、执行相应的业务逻辑并返回响应。它广泛应用于 Java Web 开发&#xff0c;提供了灵活的架构和丰富的功能。 本文将详细介绍 Spring MVC 的执行流程&#xff0c;帮助你理解它是如…

人工智能丨基于 OCR 识别方法的自动化测试

基于OCR技术的自动化测试是一种通过识别图像或界面中的文本来验证应用程序功能的测试方法。OCR技术在自动化测试中的应用场景广泛&#xff0c;尤其是在需要处理图像、PDF、扫描文档或无法直接获取文本的UI元素时。 以下是基于OCR识别方法的自动化测试的关键步骤和注意事项&…

gotool在线工具集

1. 包含各种 sql 处理 2. 包含 json 处理 3. 包含 图片处理 4. 跨平台传输 gotool

AI绘画软件Stable Diffusion详解教程(1):Windows系统本地化部署操作方法(专业版)

一、事前准备 1、一台配置不错的电脑&#xff0c;英伟达显卡&#xff0c;20系列起步&#xff0c;建议显存6G起步&#xff0c;安装win10或以上版本&#xff0c;我的显卡是40系列&#xff0c;16G显存&#xff0c;所以跑大部分的模型都比较快&#xff1b; 2、科学上网&#xff0…

python实战项目58:采集蜻蜓FM热门音频top排行榜

python实战项目58:采集蜻蜓FM热门音频top排行榜 一、采集流程介绍二、数据接口采集三、使用xpath提取页面数据1、抓包,找到数据接口2、发送请求,获取数据3、提取数据4、保存数据一、采集流程介绍 蜻蜓FM热门音频top排行榜的链接为: https://m.qingting.fm/rank/,首页如下图…

从零开始用react + tailwindcs + express + mongodb实现一个聊天程序(三) 实现注册 登录接口

1.划分文件夹 在src目录下创建controllers middleware models routes controllers 放具体的方法 signup login middleware 里面是中间件 请求的验证 models 放对象实体 routes 处理访问路径像/signup /login 等等 2. 接口开发 系统的主要 有用户认证 和 消息 2种类型…