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

动态表头导出EasyExcel

在 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.kler.cn/a/562927.html

相关文章:

  • ExpMoveFreeHandles函数分析和备用空闲表的关系
  • python曲线回归小案例教程
  • 全球首个平行推理模型,对标Claude3.7,零延迟
  • 机试刷题_NC17 最长回文子串【python】
  • OpenAPI Generator:API开发的瑞士军刀
  • JavaEE 编写Java程序,实现简单的echo程序(网络编程TCP实践练习)
  • 解决Spring Boot中LocalDateTime返回前端数据为数组结构的问题
  • 欢乐力扣:最长连续序列
  • Flink SQL怎么用?
  • Android 10.0 Settings中系统菜单去掉备份二级菜单
  • 【字符串】最长公共前缀 最长回文子串
  • 2025最新Flask学习笔记(对照Django做解析)
  • windows设置暂停更新时长
  • 【多模态大模型】GLM-4-Voice端到端语音交互机器人VoiceAI
  • Ubuntu本地使用AnythingLLM
  • 【解决idea2024.3.3版本Vue插件报错】
  • 【新人系列】Python 入门专栏合集
  • 百度觉醒,李彦宏渴望光荣
  • 【Linux高级IO】掌握Linux高效编程:深入探索多路转接select机制
  • 3-提前结束训练