SpringBoot + hutool工具 实现动态表头导出Excel
动态表头定位:前端导出Excel时,选择需要导出的字段。实现思路:使用 自定义注解 ,映射 实体类字段和表头名称,再通过反射获取到实体类的自定义注解,对比 前端带过来的 表头集合,通过 hutool导出功能实现。导入 相关依赖<!--hutool 工具依赖--><dependency><groupId>cn.hutool</groupId><
·
动态表头定位:前端导出Excel时,选择需要导出的字段。
实现思路:使用 自定义注解 ,映射 实体类字段和表头名称,再通过反射获取到实体类的自定义注解,对比 前端带过来的 表头集合,通过 hutool导出功能实现。
- 导入 相关依赖
<!-- hutool 工具依赖 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.3</version>
</dependency>
<!-- poi 相关依赖 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>
这里说明一下导入了 poi-ooxml 依赖,因为这个是 hutool 要求的,可以在 ExcelUtil 类中看到
- 自定义注解
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HeaderName {
String value() default "";
}
- 实体类使用 自定义注解 ,映射表头。注意: 这里的 字段顺序 和 导出Excel 后表头顺序是一致的
public class Album {
@HeaderName("编号")
private Long id;
@HeaderName("相册名称")
private String title;
@HeaderName("相册封面")
private String image;
@HeaderName("图片列表")
private String imageItems;
// Getter and Setter 省略。。。
}
- 封装hutool导出Excel工具类(HuTool参考文档)
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
public class HuToolExcelUtil {
/**
* 封装 通用导出方法
* @param response
* @param dataList
* @param fileName
*/
public static void universalExcelExport(HttpServletResponse response, List<Map<String, Object>> dataList, String fileName) {
BigExcelWriter writer = (BigExcelWriter) ExcelUtil.getBigWriter();
ServletOutputStream out = null;
try {
writer.write(dataList, true);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
fileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
out = response.getOutputStream();
writer.flush(out, true);
} catch (IOException e) {
e.printStackTrace();
} finally {
writer.close();
IoUtil.close(writer);
}
}
}
- 导出业务类 编写(相关的mapper 我就不粘出来了,我这里直接查询的 全部数据,需求不同可以条件查找之类的)
@Service
public class AlbumService {
@Resource
private AlbumMapper albumMapper;
/**
* 相册数据导出
* @param response
* @param names
* @throws IllegalAccessException
*/
public void export(HttpServletResponse response, List<String> names) throws IllegalAccessException {
// 获取全部数据
List<Album> albums = albumMapper.selectByExample(null);
// 封装 hutool 导出需要的 数据格式。String:表头;Object:数据
List<Map<String, Object>> dataMap = new LinkedList<>();
for (Album album : albums) {
// 实体类 转 Map
Map<String, Object> entityMap = entityToMap(album, names);
dataMap.add(entityMap);
}
HuToolExcelUtil.universalExcelExport(response,dataMap,"相册数据");
}
/**
* 数据封装
* @param album
* @param names
* @return
* @throws IllegalAccessException
*/
private Map<String, Object> entityToMap(Album album, List<String> names) throws IllegalAccessException {
Map<String, Object> resMap = new LinkedHashMap<>();
Class<?> albumClass = album.getClass();
// 获取 实体类 中所有的字段
Field[] declaredFields = albumClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
// 这里设置为 true 才可以访问到 实体类中的 private 字段
declaredField.setAccessible(true);
// 获取字段所对应的注解
HeaderName annotation = declaredField.getAnnotation(HeaderName.class);
if (null != annotation){
// 有注解 则 获取 注解的值(表头名称)
String value = annotation.value();
// 再判断 实体类中是否有这个表头
if (names.contains(value)){
resMap.put(value,declaredField.get(album));
}
}
}
return resMap;
}
}
- 导出Controller 编写
@RestController
@RequestMapping("/album")
public class AlbumController {
@PostMapping("/export")
public void export(HttpServletResponse response,@RequestBody List<String> names) throws IllegalAccessException {
albumService.export(response,names);
}
}
- 测试
- 结束啦!
更多推荐
已为社区贡献2条内容
所有评论(0)