人生无常,大肠包小肠;代码无常,一坑接一坑,坑坑不一样!

最近有个需求,需要将项目中的数据导出到表格,so,毫无疑问直接上EasyExcel,毕竟这玩意儿是阿里系的,性能还算比较能打的!但导出时缺遇到一个问题,不分字段一直为空,开始以为是数据为空,经过排查数据是有值的,EasyExcel导出的list对象中也是有值的,那特喵的问题出在哪里了呢?

后经排查发现:由于导出对象中的字段命名不规范,EasyExcel在写数据的时候会将数据list转换为BeanMap对象,它在使用==BeanMap.create(onRowData)==时,将属性名进行了处理,导致未找到对象。。。

问题描述

EasyExcel导出数据时,部分列为空,可以肯定的是数据是存在的!
在这里插入图片描述

问题排查

排查数据源

检查数据源,为空的几列的数据源是否有值,可以看到是有值的!
在这里插入图片描述

排查导出对象

在这里插入图片描述
说明

  • 导出流程
    • 查询数据库获取源数据集合
    • 源数据集合转换为需要导出的对象集合
    • 使用EasyExcel工具导出表格
  • 数据排查
    • 先查看源数据集合,可以看到里面是有值的,通过
    • 再查看对象集合,发现依然有值,通过
    • 最后就只能想到是EasyExcel在写入时数据丢失了

排查EasyExcel

一路排查下来,数据都是没问题的,那十有八九就出现在EasyExcel导出数据中了,看了一下写入数据使用的方法EasyExcel.doWrite(),这个确实会存在数据处理,so,跟踪一下:

  1. doWrite(List data)
    键入write(data, build())方法
    在这里插入图片描述

  2. ExcelBuilderImpl.addContent(List data……)
    键入add(data)方法
    在这里插入图片描述

  3. ExcelWriteAddExecutor.add(List data)
    此方法为添加对象集合,会进行遍历数据,逐行进行读取
    在这里插入图片描述

  4. ExcelWriteAddExecutor.addOneRowOfDataToExcel
    此方法中判断对象是否是List类型,如果不是,则按照Java对象进行处理
    在这里插入图片描述

  5. ExcelWriteAddExecutor.addJavaObjectToExcel
    此刻该放大招了!!!
    在此方法中会将读取的数据进行BeanMap对象转换,然后通过反射获取导出对象中的属性,判断导出对象中的属性是否存在于BeanMap中,如果存在则获取,否则进行下一属性的循环!
    在这里插入图片描述
    可以看到,BeanMap中的属性名称被EasyExcel自动处理了,变成了AModeOrderId, 而我导出对象中的属性名为aModeOrderId,所以在执行ExcelWriteAddExecutor.addJavaObjectToExcel方法中的beanMap.containsKey(name)时,将获取不到该属性而跳出循环进行下一轮
    在这里插入图片描述
    问题找到了,那又如何处理呢?

问题处理

经上面排查可以看出,问题出现在导出对象属性名不规范导致,EasyExcel将兑换转换为BeanMap时会将首字母大写,导致查询不到该属性(aModeOrderId),真是命名不规范,害死人呀!!!
问题找到了,处理起来就容易了!
由于数据源对象中的属性是他人命名的,咱们不方便改,那就只能改咱们自己创建的导出对象,给它个规范的命名即可,或者将此对象作为不需要导出的属性,创建一个规范的命名用来导出,只需要在对象转换的时候,将aModeOrderId属性的值赋给规范命名的属性中即可!

  • 规范属性名
    在这里插入图片描述
  • 赋值给新属性
    在这里插入图片描述
  • 导出效果
    在这里插入图片描述

至此,大功告成!!!
一句话总结:

代码千万行,注释第一行

命名不规范,同事两行泪

GitHub 加速计划 / ea / easyexcel
31.64 K
7.47 K
下载
快速、简洁、解决大文件内存溢出的java处理Excel工具
最近提交(Master分支:3 个月前 )
c42183df Bugfix 3 个月前
efa7dff6 * 重新加回 `commons-io` 3 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐