Java利用Reflect实现封装Excel导出工具类

 更新时间:2022年11月07日 14:51:11   作者:Zeuss  
这篇文章主要为大家详细介绍了Java如何利用Reflect实现封装Excel导出工具类,文中的实现方法讲解详细,具有一定的借鉴价值,需要的可以参考一下

最近遇到一个需求,需要对页面的列表数据做导出操作,考虑了很多实现方案之后,最终选择了hutool的ExcelWriter + Spring自带的ReflectionUtils工具类来实现这个功能,采用这种方式的主要原因是对现有代码改动较少,并且可以无缝切入系统,实现各个模块的导出操作,设计思路如下:

如上图所示,首先我们定义一个接口,此接口完成Excel导出功能,在ExcelExportService 中实现功能。

话不多说,上代码:

定义ExcelExportEnum

在导出Excel之前,我们需要先定义ExcelExportEnum,此枚举存储了我们后端需要导出的模块和模板名称

@Getter
@RequiredArgsConstructor
public enum ExcelExportEnum {

/**
 * 模块
 */
MODULE_A("moduleAService", "模块A");

private final String key;
private final String name;

}

定义导出方法

校验入参

首先,我们需要对入参进行校验,查看传入的 MODULE_NAME 是否和后端Enum的一致,并且我们需要对参数中的自定义方法名进行提取,我们通过ExcelExportEnum来获取导出的module的Service名称

    if (!map.containsKey(MODULE_NAME)) {
        throw new BaseException("缺少参数:moduleName");
    }
    String moduleName = map.get(MODULE_NAME).toString();
    if (!EnumUtil.contains(ExcelExportEnum.class, moduleName)) {
        throw new BaseException("模块查找失败");
    }
    String functionName = DEFAULT_FUNCTION_NAME;
    //如果传了自定义方法名
    if (map.containsKey(CUSTOM_FUNCTION_NAME)) {
        functionName = map.get(CUSTOM_FUNCTION_NAME).toString();
    }
    String serviceName = ExcelExportEnum.valueOf(moduleName).getKey();
    String tableName = ExcelExportEnum.valueOf(moduleName).getName();

利用java反射获取Service中的所有method

Map<String, Method> methodMap = Arrays.stream(SpringContextHolder.getBean(serviceName).getClass().getMethods()).collect(Collectors.toMap(Method::getName, Function.identity(), (key1, key2) -> key2));

在上述代码中SpringContextHolder.getBean(serviceName).getClass().getMethods()方法,首先通过getBean来获取 第一步中得到的ServiceName的Java bean。然后通过Class.getMethods()方法获取此service中的所有方法

最后,使用Arrays.stream方法,将module对应的Service中的所有method获取到,并放入methodMap中,供后续代码使用

提取method中的入参对象,获取其Class

    Object o;
    try {
        o = methodMap.get(functionName).getParameterTypes()[0].getDeclaredConstructor().newInstance();
    } catch (Exception e) {
        throw new BaseException(e);
    }

通过Method.getParameterTypes()方法,将第二步中获取的method的入参的Class取到,并赋值给对象Object o,供后续调用分页列表接口传递入参匹配Class使用

传入参数,调用导出方法

    Map<String, Object> param = (Map<String, Object>) map.computeIfAbsent(PARAM, k -> new HashMap<String, Object>(4));
    param.put("limit", -1);
    CopyOptions copyOptions = new CopyOptions();
    copyOptions.setIgnoreError(true);
    PageUtils page = (PageUtils) methodMap.get(functionName).invoke(SpringContextHolder.getBean(serviceName), BeanUtil.mapToBean(param, o.getClass(), true, copyOptions));
    if (CollUtil.isEmpty(page.getList())) {
        throw new BaseException("数据获取失败");
    }
    Object resultObject = page.getList().get(0);
    ExcelUtils utils = new ExcelUtils(resultObject.getClass());
    utils.exportExcel(page.getList(), response, tableName, moduleName);

可以看到,在上述导出方法中,我们使用了Method.invoke方法,并且设置转义忽略

注意事项

使用hutool工具包输出到流

// 通过工具类创建writer,默认创建xls格式 
ExcelWriter writer = ExcelUtil.getWriter(); 
//创建xlsx格式的 
//ExcelWriter writer = ExcelUtil.getWriter(true); 
// 一次性写出内容,使用默认样式,强制输出标题 
writer.write(rows, true); 
//out为OutputStream,需要写出到的目标流 
writer.flush(out); 
// 关闭writer,释放内存 
writer.close();

注意 ExcelUtil.getWriter()默认创建xls格式的Excel,因此写出到客户端也需要自定义文件名为XXX.xls,否则会出现文件损坏的提示。 若想生成xlsx格式,请使用ExcelUtil.getWriter(true)创建。

到此这篇关于Java利用Reflect实现封装Excel导出工具类的文章就介绍到这了,更多相关Java Reflect封装Excel导出工具类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot请求参数相关注解说明小结

    SpringBoot请求参数相关注解说明小结

    这篇文章主要介绍了SpringBoot请求参数相关注解说明,主要包括@PathVariable,@RequestHeader、@CookieValue、@RequestBody和@RequestParam,本文结合实例代码给大家讲解的非常详细,需要的朋友可以参考下
    2022-05-05
  • Eclipse配置SVN的几种方法及使用详情

    Eclipse配置SVN的几种方法及使用详情

    这篇文章主要介绍了Eclipse配置SVN的几种方法及使用详情,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 老生常谈java中的数组初始化

    老生常谈java中的数组初始化

    下面小编就为大家带来一篇老生常谈java中的数组初始化。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • mybatis中延迟加载Lazy策略的方法

    mybatis中延迟加载Lazy策略的方法

    这篇文章主要介绍了mybatis中延迟加载Lazy策略,需要的朋友可以参考下
    2018-06-06
  • JAVA实现caesar凯撒加密算法

    JAVA实现caesar凯撒加密算法

    Carsar加密算法是最简单的加密算法,原理是把一个字母在字母表中移动相应的位置,比如输入a,将其移动3位,经过Caesar加密后输出的d,位置可以循环移动,输入x,则输出a
    2014-01-01
  • Mybatis plus多租户方案的实战踩坑记录

    Mybatis plus多租户方案的实战踩坑记录

    MybaitsPlus多租户处理器是一个对于多租户问题的解决方案,下面这篇文章主要给大家介绍了关于Mybatis plus多租户方案踩坑的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-12-12
  • Java中文件管理系统FastDFS详解

    Java中文件管理系统FastDFS详解

    这篇文章主要介绍了Java中文件管理系统FastDFS详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Future cancel迷惑性boolean入参解析

    Future cancel迷惑性boolean入参解析

    这篇文章主要为大家介绍了Future cancel迷惑性boolean入参解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • 浅谈Java中Properties类的详细使用

    浅谈Java中Properties类的详细使用

    properties类继承自hashtable,通常和io流结合使用。它最突出的特点是将key/value作为配置属性写入到配置文件中以实现配置持久化,或从配置文件中读取这些属性。它的这些配置文件的规范后缀名为".properties"。表示了一个持久的属性集
    2021-06-06
  • Java 精炼解读方法的定义与使用

    Java 精炼解读方法的定义与使用

    Java语言中的“方法”(Method)在其他语言当中也可能被称为“函数”(Function)。对于一些复杂的代码逻辑,如果希望重复使用这些代码,并且做到“随时任意使用”,那么就可以将这些代码放在一个大括号“{}”当中,并且起一个名字。使用的时候,直接找到名字调用即可
    2022-03-03

最新评论