在 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. 关键点说明
- 动态表头
- 通过 buildHead() 方法将前端传递的 headers 转换为 EasyExcel 必要的 List<List<String>> 格式。
- 动态数据
- 通过 buildData() 方法,根据 headers 中界说的 field 字段次序,从 data 中提取对应值,构建数据行。
- 流式导出
- 使用 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. 扩展优化
- 字段校验:确保前端传递的 field 在 data 中存在对应值。
- 大数据量分页:如果数据量过大,可分页查询后分批写入。
- 自界说样式:通过 WriteHandler 动态设置单元格样式(如字体、颜色)。
通过这种方式,无需界说实体类即可实现完全动态的 Excel 导出功能,表头和字段完全由前端控制。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |