Excel Export 踩坑注意点+导出方案设计

零 Java教程评论35字数 979阅读3分15秒阅读模式

Excel Export 踩坑注意点+导出方案设计

产品需求

产品经理需要导出一个页面的所有的信息到 EXCEL 文件。

需求分析

对于 excel 导出,是一个很常见的需求。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

最常见的解决方案就是使用 poi 直接同步导出一个 excel 文件。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

客户体验 & 服务性能

  • 客户体验

如果导出的文件比较大,比如几十万条数据,同步导出页面就会卡主,用户无法进行其他操作。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

  • 服务性能

导出的时候,任务比较耗时就会阻塞主线程。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

如果导出的服务是暴露给外部(前后端分离),这种大量的数据传输十分消耗性能。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

解决方案

使用异常处理导出请求,后台 MQ 通知自己进行处理。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

MQ 消费之后,多线程处理 excel 文件导出,生成文件后上传到 FTP 等文件服务器。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

前端直接查询并且展现对应的任务执行列表,去 FTP 等文件服务器下载文件即可。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

EXCEL 导出需要考虑的问题

OOM

正常的 poi 在处理比较大的 excel 的时候,会出现内存溢出。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

网上的解决方案也比较多。文章源自灵鲨社区-https://www.0s52.com/bcjc/javajc/17643.html

比如官方的 SXSSF (Since POI 3.8 beta3) 解决方式。

当然,这种写法比较麻烦。

可以选择一些封装好的 excel 工具,解决 oom 问题:

iexcel excel 更加优雅地读取和写入,解决 excel OOM 问题

FULL GC

如果一次查询 100W 条数据库,然后把这些信息全部加载到内存中,是不可取的。

建议有2个:

  1. 限制每一次分页的数量。比如一次最多查询 1w 条。分成 100 次查询。(必须)
  2. 限制查询得总条数。比如限制为最多 10W 条。(根据实际情况选择)

虽然使用者提出要导出类似于 3 个月的所有信息,但是数量太多,毫无意义。(提出者自己可能体会不到)

尽量避免 FULL-GC 的情况发生,因为目前的所有方式对于 excel 的输出流都会占用内存,100W 条很容易导致 FULL-GC。

数据库的压力

去数据库读取的时候一定要记得分页,免得给数据库太大的压力。

一次读取太多,也会导致内存直线上升。

比如 100W 条数据,则分成 100 次去数据库读取。

网络传输

传统的 excel 导出,都是前端一个请求,直接 HTTP 同步返回。导出 100W 条,就在那里傻等。

这客户体验不友好,而且网络传输,系统占用多种问题。

建议使用异步处理的方式,将文件上传到文件服务器。前端直接去文件服务器读取。

编程的便利性

对于上面提到的工具,比如 Hutool,在表头的处理方面没法很方便的统一。

你可以自己定义类似于 easypoi/easyexcel 中的注解,自己反射解析。

然后统一处理表头即可。

零
  • 转载请务必保留本文链接:https://www.0s52.com/bcjc/javajc/17643.html
    本社区资源仅供用于学习和交流,请勿用于商业用途
    未经允许不得进行转载/复制/分享

发表评论