常见问题

读取文件务必使用2.0.5+

2.0.0-beta1到2.0.2有小概率会丢失数字。

beta版本使用注意

用beta版本的同学注意,建议一个月以后看看有没有正式版(一般一个月内肯定会升级正式版),有的话改成正式版,因为beta版,容易如有bug,然后也别跳级升级比如你用的是2.1.0-beat1,建议一个月后升级到2.1.x,第一第二位不变,第三位用最新的就可以。

不支持功能

  • 单个文件的并发写入、读取
  • 读取图片
  • csv读取(这个后续可能会考虑)

    常见问题

    必读

    不管想要读还是写,对应的最简单的demo,必须看下

    关于@Data

    读写的对象都用到了Lombok,他会自动生成get,set ,如果不需要的话,自己创建对象并生成get,set

    填充和写怎么选择?

    填充其实也不会占用大量内存,用的也是文件缓存,最后统一书写,如果导出的内容各种格式复杂,建议直接用模板然后填充(填充的数据会自动有格式)。如果格式相对简单,建议直接用写,相对来说,直接导出性能还是高一丢丢。

    部分字段读取或者写入为空?

    读写反射对象用到了Cglib,所以成员变量必须符合驼峰规范,而且使用@Data不能使用@Accessors(chain = true)。后续会考虑支持非驼峰。

    出现 NoSuchMethodExceptionClassNotFoundException, NoClassDefFoundError

    极大概率是jar冲突,建议clean项目,或者统一poi 的版本,理论上来说easyexcel兼容poi的3.17,4.0.1,4.1.0所有较新版本

    在读的时候Listener里面需要使用spring的@Autowired

    Listener创建成员变量,然后在构造方法里面传进去。必须不让spring管理Listener,每次读取都要new一个。

    String去接收数字,出现小数点等情况

    这个是BUG,但是很难修复,后续版本会修复这个问题。目前请使用@NumberFormat注解,里面的参数就是调用了java自带的NumberFormat.format方法,不知道怎么入参的可以自己网上查询。

    自定义拦截器创建CellStyle需要注意

    千万别每次afterCellDispose都创建CellStyle,第一次进来创建,后面直接用这个就行。CellStyle最多创建65536个,多了会崩.

    10M+文件读取说明(如果感觉目前效率还行后面的都不需要看)

    03版没有办法处理,相对内存占用大很多。excel 07版本有个共享字符串共享字符串的概念,这个会非常占用内存,如果全部读取到内存的话,大概是excel文件的大小的3-10倍,所以easyexcel用存储文件的,然后再反序列化去读取的策略来节约内存。当然需要通过文件反序列化以后,效率会降低,大概降低30-50%(不一定,也看命中率,可能会超过100%)

    如果对读取效率感觉还能接受,就用默认的,永久占用(单个excel读取整个过程)一般不会超过50M(大概率就30M),剩下临时的GC会很快回收

    默认大文件处理

    默认大文件处理会自动判断,共享字符串5M以下会使用内存存储,大概占用15-50M的内存,超过5M则使用文件存储,然后文件存储也要设置多内存M用来存放临时的共享字符串,默认20M。除了共享字符串占用内存外,其他占用较少,所以可以预估10M,所以默认大概30M就能读取一个超级大的文件。

    根据实际需求配置内存

    想自定义设置,首先要确定你大概愿意花多少内存来读取一个超级大的excel,比如希望读取excel最多占用100M内存(是读取过程中永久占用,新生代马上回收的不算),那就设置使用文件来存储共享字符串的大小判断为20M(小于20M存内存,大于存临时文件),然后设置文件存储时临时共享字符串占用内存大小90M差不多

    如果最大文件条数也就十几二十万,然后excel也就是十几二十M,而且不会有很高的并发,并且内存也较大

    1
    2
    3
    4
     // 强制使用内存存储,这样大概一个20M的excel使用150M(很多临时对象,所以100M会一直GC)的内存
    // 这样效率会比上面的复杂的策略高很多
    // 这里再说明下 就是加了个readCache(new MapCache()) 参数而已,其他的参照其他demo写 这里没有写全
    EasyExcel.read().readCache(new MapCache());

对并发要求较高,而且都是经常有超级大文件

1
2
3
4
5
 // 第一个参数的意思是 多少M共享字符串以后 采用文件存储 单位MB 默认5M
// 第二个参数 文件存储时,内存存放多少M缓存数据 默认20M
// 比如 你希望用100M内存(这里说的是解析过程中的永久占用,临时对象不算)来解析excel,前面算过了 大概是 20M+90M 所以设置参数为:20 和 90
// 这里再说明下 就是加了个readCacheSelector(new SimpleReadCacheSelector(5, 20))参数而已,其他的参照其他demo写 这里没有写全
EasyExcel.read().readCacheSelector(new SimpleReadCacheSelector(5, 20));

关于maxCacheActivateSize 也就是前面第二个参数的详细说明

easyexcel在使用文件存储的时候,会把共享字符串拆分成1000条一批,然后放到文件存储。然后excel来读取共享字符串大概率是按照顺序的,所以默认20M的1000条的数据放在内存,命中后直接返回,没命中去读文件。所以不能设置太小,太小了,很难命中,一直去读取文件,太大了的话会占用过多的内存。

如何判断 maxCacheActivateSize是否需要调整

开启debug日志会输出Already put :4000000 最后一次输出,大概可以得出值为400W,然后看Cache misses count:4001得到值为4K,400W/4K=1000 这代表已经maxCacheActivateSize 已经非常合理了。如果小于500 问题就非常大了,500到1000 应该都还行。