在企业的开发工程中,偶尔会遇到不同的用户具有不同表头的结构的导出功能实现,这个时候,使用类添加注解,然后进行映射的方式可能无法实现,那么这种时候只能自己写一下表头映射了。
本案例基于EasyExcel实现了LinkedHashMap进行字段、表头、默认值的映射,从而达到动态导出数据的功能,测试以实际场景中,编写controller接口导出接口,希望能够帮助到你!
<dependency>
<groupId>com.alibabagroupId>
<artifactId>easyexcelartifactId>
<version>3.0.5version>
dependency>
尽量引入高版本的easyexcel,2.x的版本可能会有坑
package com.walker.entity;
import lombok.Data;
@Data
public class DynamicExcelData {
//列名
private String name;
//默认值
private String defaultValue;
public DynamicExcelData(String name, String defaultValue) {
this.name = name;
this.defaultValue = defaultValue;
}
}
public static void dynamicExport(HttpServletResponse response,
LinkedHashMap<String,DynamicExcelData> nameMap,
List<Map<String, Object>> list,
String sheetName) throws IOException {
//首先判断是否有数据,没有就返回
if(CollUtil.isEmpty(list)){
return;
}
//这里的map使用LinkedHashMap,实现字段的顺序功能
if(nameMap==null){
throw new RuntimeException("请填写好映射表数据");
}
//先初始化一下传入
int size = list.size();
List<List<String>> dataList = new ArrayList<>();
for (int i = 0; i < size; i++) {
dataList.add(new ArrayList<>());
}
//获取表头
ArrayList<List<String>> head = new ArrayList<>();
for (Map.Entry<String, DynamicExcelData> titleMap : nameMap.entrySet()) {
DynamicExcelData data = titleMap.getValue();
head.add(Collections.singletonList(data.getName()));
}
//数据重组
for (int i = 0; i < list.size(); i++) {
Map<String, Object> map = list.get(i);
List<String> columns = dataList.get(i);
for (Map.Entry<String, DynamicExcelData> sortNameEntry : nameMap.entrySet()) {
String key = sortNameEntry.getKey();
Object value = map.get(key);
columns.add(value!=null?String.valueOf(value):sortNameEntry.getValue().getDefaultValue());
}
}
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
//使用EasyExcel write进行写出
EasyExcel.write(response.getOutputStream()).head(head)
.sheet(sheetName).doWrite(dataList);
}
package com.walker.controller;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.walker.entity.DynamicExcelData;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
@RestController
@RequestMapping("/export")
public class ExportController {
@PostMapping("/export")
public void export(HttpServletResponse response) throws IOException {
//模拟数据
//一般动态数据使用的是List,然后内部使用Map进行数据的接受
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
HashMap<String, Object> map = new HashMap<>();
for (int j = 0; j < 5; j++) {
map.put("title"+j,i+","+j);
}
//这个用于测试值如果为null时,能否进行默认值填充
map.put("title5",null);
list.add(map);
}
//使用LinkedHashMap进行表头字段映射
LinkedHashMap<String, DynamicExcelData> nameMap = new LinkedHashMap<>();
nameMap.put("title1",new DynamicExcelData("年龄","0"));
nameMap.put("title0",new DynamicExcelData("姓名","0"));
nameMap.put("title2",new DynamicExcelData("职业","0"));
nameMap.put("title3",new DynamicExcelData("爱好","0"));
nameMap.put("title4",new DynamicExcelData("小名","0"));
nameMap.put("title5",new DynamicExcelData("空白字段","0"));
//调用方法,方法已在步骤3进行介绍
dynamicExport(response,nameMap, list,"模板");
}
/**
* 列表
*/
public static void dynamicExport(HttpServletResponse response,
LinkedHashMap<String,DynamicExcelData> nameMap,
List<Map<String, Object>> list,
String sheetName) throws IOException {
if(CollUtil.isEmpty(list)){
return;
}
if(nameMap==null){
throw new RuntimeException("请填写好映射表数据");
}
int size = list.size();
List<List<String>> dataList = new ArrayList<>();
for (int i = 0; i < size; i++) {
dataList.add(new ArrayList<>());
}
//获取表头
ArrayList<List<String>> head = new ArrayList<>();
for (Map.Entry<String, DynamicExcelData> titleMap : nameMap.entrySet()) {
DynamicExcelData data = titleMap.getValue();
head.add(Collections.singletonList(data.getName()));
}
//数据重组
for (int i = 0; i < list.size(); i++) {
Map<String, Object> map = list.get(i);
List<String> columns = dataList.get(i);
for (Map.Entry<String, DynamicExcelData> sortNameEntry : nameMap.entrySet()) {
String key = sortNameEntry.getKey();
Object value = map.get(key);
columns.add(value!=null?String.valueOf(value):sortNameEntry.getValue().getDefaultValue());
}
}
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
EasyExcel.write(response.getOutputStream()).head(head)
.sheet(sheetName).doWrite(dataList);
}
}
我使用的是apiPost,这里就不细讲了
调用的方式很多,可以使用Postman,也可以让前端进行调用。
直接看看返回结果
这个也算是简陋的实现方式了,希望能够帮助到你!
我是walker,欢迎关注公众号I am Walker
,有更多的干货分享~