测试代码:
@RequestMapping("/createCsvFileJcTest") public void createCsvFileJcTest() { //类不确定 随便怎么传都行 List<District> districts = districtService.queryByParentCodes(Arrays.asList("110100")); //存放地址&文件名 String fileName = "D:\\mycsv\\"+MyCsvFileUtil.buildCsvFileFileName(districts); //创建表格行标题 String tableNames = MyCsvFileUtil.buildCsvFileTableNames(districts); //创建文件 MyCsvFileUtil.writeFile(fileName, tableNames); //写入数据 String contentBody = MyCsvFileUtil.buildCsvFileBodyMap(districts); //调用方法生成 MyCsvFileUtil.writeFile(fileName, contentBody); }
看看效果:
导出的excel文件内容:
接下来换个类玩玩:
然后导出看看效果:
可以看到数据导出也是OK的:
没错就是这么简单, 当然也是抛转引玉, 希望大家看了这篇文章,可以借鉴这些反射的函数玩法,做更多的好玩的封装,比如加上一些自定义注解的解析,比如加上一些前后置拦截器拓展等等。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
扩展
上面的示例中导出的表头是属性名,如果正式的导出通常需要自定义表头名称,我们这里可以使用自定义注解来完成。
JcExcelName.java
/** * @Author : JCccc * @CreateTime : 2020/5/14 * @Description : **/ @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface JcExcelName { String name() default ""; }
然后在想导出的类里面,想加看得懂的名字就加,不加就拿属性名:
随手再写一个 ,新的反射解析拿字段属性注解值函数:
public static <T> List<String> resolveExcelTableName(T entity) { List<String> tableNamesList = new ArrayList<>(); Class<? extends Object> bean = entity.getClass(); Field[] fields = bean.getDeclaredFields(); Map<String, Object> map = new HashMap<>(fields.length); for (Field field : fields) { try { if (!"serialVersionUID".equals(field.getName())) { String tableTitleName = field.getName(); JcExcelName myFieldAnn = field.getAnnotation(JcExcelName.class); String annName = myFieldAnn.name(); if (StringUtils.hasLength(annName)) { tableTitleName = annName; } tableNamesList.add(tableTitleName); } } catch (Exception e) { log.warn("toMap() Exception={}", e.getMessage()); } } return tableNamesList; }
然后根据解析出来的注解值列名拼接 表格标题名格式:
public static String buildCsvFileTableNamesNew(List<String> dataList) { StringBuilder tableNames = new StringBuilder(); for (String name : dataList) { tableNames.append(name).append(MyCsvFileUtil.CSV_DELIMITER); } return tableNames.append(MyCsvFileUtil.CSV_TAIL).toString(); }
测试看看效果:
public static void main(String[] args) { User user = new User(); List<String> nameList = MapUtils.resolveExcelTableName(user); System.out.println(nameList.toString()); String tableNames = buildCsvFileTableNamesNew(nameList); System.out.println(tableNames); }
效果嘎嘎好:
然后反手就搞到我们前面的文章使用例子里面:
String tableNames = MyCsvFileUtil.buildCsvFileTableNamesNew( MyCsvFileUtil.resolveExcelTableName(dataList.get(0)));
执行一下示例接口,看看效果:
文件出来了:
打开看看效果:
好了,就到这吧,非常完美。