最近工作上要提供一个功能,把grid中的数据下载成excel,初步的考虑是使用poi来生成workbook,然后把workbook写到response的outputstream中去。
但是在使用的时候,发现因为我们在一些场景下会下载上网条的数据,poi的开销太大了。
我这边造了30000条数据,就要消耗掉超过300MB的内存,导致outofmemory,而且这300MB内存还不包括对象占用的内存(我的测试数据太少,只好写死了一条数据的,然后循环30000次)。后来我使用真实的数据来测,1000条记录就要消耗掉300MB的内存,用时约6分钟,这是因为我使用的object是带有级联的,每次去取他的某个对象属性时都会call下db去拿,因此非常的耗资源。据说以前同事测过一个比较复杂的对象,2000个这样的对象就要占用上GB的内存。所以这种方法不可取。
现在采用的方案是超过2000条数据使用csv文件以供下载,在取对象的时候每次少取一些,取多次,减少对象占用的内存。
后来才去的方案是超大的数据,使用一条sql直接返回最终结果的string,然后用csv来写,18000条数据大概耗时1分多钟,内存消耗因为种种原因没有再测。
挺说现在oracle提供了可以返回stream,多次返回的方式。现在正有同事在研究,不知道会不会符合我们的需求。
听前辈讲,他们以前做过20万条数据的下载,是直接用jdbc连接数据库,跳过了中间n多层。我估计他们也是要分批查询的。
这次做poi真是之前完全没想到会数据量大的时候会这么复杂。