V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Kimen
V2EX  ›  Java

POI 如何快速导出千万级数据的 Excel

  •  
  •   Kimen · 117 天前 · 3293 次点击
    这是一个创建于 117 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在使用 POI 导出一千万行数据到 Excel 时,CPU 长时间爆炸💥
    现在的解决方案是:

    • 使用 SXSSFWorkbook 类
    • 每 50W 数据划分 sheet
    • 采用多线程,每个 sheet 开一个线程去跑

    现已探明的问题:
    一千万的数据在创建 Excel 前都存储在 list 中,当 list 占用内存很小时,导出很快,一旦 list 变得很大,分段导出都会变的很慢

    53 条回复    2021-08-13 16:30:18 +08:00
    mhycy
        1
    mhycy  
       117 天前
    先不说导出,就是成功导出了,这千万级数据的 Excel 有办法开么
    Kimen
        2
    Kimen  
    OP
       117 天前
    @mhycy 哎,客户要求的,之前 100w 试过是可以打开的
    fengpan567
        3
    fengpan567  
       117 天前
    为什么要搞一个 1000W 大小的 list 出来,不能分页查吗?
    fox1751
        4
    fox1751  
       117 天前   ❤️ 1
    搞明白客户的真实需求吧.
    7925250
        5
    7925250  
       117 天前   ❤️ 1
    可以改造成流式导出,一千万的数据 (1.3GB) 导出,耗时 2 分钟
    wangkun025
        6
    wangkun025  
       117 天前
    Excel 目前单个 sheet 只能容纳 104 万行。不过可以分 sheet,sheet 数量没有限制。
    chendy
        7
    chendy  
       117 天前
    直接走数据库查询导出 csv 吧
    MidGap
        8
    MidGap  
       117 天前
    曾经踩过内存溢出的坑,就是用使用 SXSSFWorkbook 类这个方法解决的,但是这样 IO 好像就会变密集,慢也是无法避免的。。 本身这个需求感觉就很扯淡,使劲 battle 一下多好~ 或者用 csv 啊,简单多了
    MidGap
        9
    MidGap  
       117 天前
    @fengpan567 excel 的 append 操作很坑,要先读到内存再往下写我记得
    aguesuka
        10
    aguesuka  
       117 天前   ❤️ 8
    直接导出 csv 文件, 能提出导出 1000 万行 excel 数据的客户估计也分不清这两种数据的区别
    franklinray
        11
    franklinray  
       117 天前
    导出 1000 万行 excel,一般电脑都打不开吧。打开了谁能去查看数据……如果只是为了导出数据,然后导入其他系统做分析,换成 csv 不好吗
    binsys
        12
    binsys  
       117 天前
    我处理大量 EXCEL 数据用 MS 的 OPENXMLSDK ,在直接以 XML SAX 形式写入
    pengtdyd
        13
    pengtdyd  
       117 天前
    什么样的电脑可以打开 1000w 的 excel,很难想象
    jzphx
        14
    jzphx  
       117 天前
    easyexcel 尝试用过了吗
    liuxu
        15
    liuxu  
       117 天前
    这种阔气的问题,只有 java 节点提的出来
    xuanbg
        16
    xuanbg  
       117 天前
    50 万行的 excel,我 i9/32G 的 mbp 打开是能打开,但很费劲。100 万行是想都不敢想,何况 1000 万行。SB 客户不能惯着
    7228897
        17
    7228897  
       117 天前
    单位的电脑 4G 内存,打开 40 万条的月数据已经卡的不能动了
    chenqh
        18
    chenqh  
       117 天前
    1KW 估计内存会炸把
    EscYezi
        19
    EscYezi  
       117 天前 via iPhone
    之前用 easyExcel 看官网说是擅长导出大量数据,楼主可以体验一下🤣
    jorneyr
        20
    jorneyr  
       117 天前
    这是要把整个数据库都给搬家了
    Kimen
        21
    Kimen  
    OP
       117 天前
    @fengpan567 数据实时在产生,分页查会导致第二页和第一页数据有重复
    Kimen
        22
    Kimen  
    OP
       117 天前
    @chendy csv 碰到数据里面带逗号的都懵逼了
    Kimen
        23
    Kimen  
    OP
       117 天前
    @jzphx 没有用过 easyexcel,我看文档 easyexcel 是基于注解的,但是我的数据流是 List<Map<String, Object>>这种形式的,不知道能不能用
    chendy
        24
    chendy  
       117 天前
    @Kimen #22 能转义,不用程序实现直接用数据库的导出功能
    Kimen
        25
    Kimen  
    OP
       117 天前
    @franklinray csv 就怕遇到逗号,用户在导出之前也不知道自己能不能打开,就想看看能不能导出来。看来我要跟领导提一下,限制用户的导出数量
    Kimen
        26
    Kimen  
    OP
       117 天前
    @jorneyr 心里已经锤死客户一千万遍了
    A1exlee
        27
    A1exlee  
       117 天前
    不建议一次性将一千万数据加载到 list,可以考虑分页读库,比如每次 load 100 万条,然后写入一个 excel,分开写 10 个 excel,通过编号确认顺序,最后客户端打包下载。
    fpure
        28
    fpure  
       117 天前
    @MidGap SXSSFWorkbook 还要记得清理硬盘缓存,也是坑
    spLite
        29
    spLite  
       117 天前
    数据库导出 Excel 或者 csv,应用程序只负责把导出的文件传输给用户。
    “用户在导出之前也不知道自己能不能打开” —— 可以先手动搞一个 1000W 的 Excel 让客户打开看看么,如果他自己看下打开费劲,说不定自己就否了这方案了。
    doudou1523102
        30
    doudou1523102  
       117 天前
    建议分批导出,然后进行压缩
    kifile
        31
    kifile  
       117 天前
    csv 不是也可以用 excel 打开吗?还是流式卸乳的,考虑考虑
    speedofstephen
        32
    speedofstephen  
       117 天前
    poi 有流式 api 写 excel 的。建议不要全量放在 list 中
    lwjef
        33
    lwjef  
       117 天前   ❤️ 1
    创建个占用空间很大的假 excel,反正用户打不开。(doge
    MidGap
        34
    MidGap  
       117 天前
    @Kimen CSV 的分隔符可以指定,不一定非要逗号的。。
    onionKnight888
        35
    onionKnight888  
       117 天前
    @liuxu 哈哈 你永远无法理解客户的需求有多奇葩
    zhenglin
        36
    zhenglin  
       117 天前
    建议导出为多个 csv 再压缩成 zip 文件,SB 需求不能接!再说千万数据在一个 Excel 里他如果是普通电脑能打开么?
    2bNot2b
        37
    2bNot2b  
       117 天前
    excel 有行数上限,我记得 xls 是 10W 多吧,xlsx 是 1048576
    wqhui
        38
    wqhui  
       117 天前
    上面三个方法我当时都用了,poi 我记得有个流模式,类似于窗口控制,读一部分写一部分这个会快很多,忘了是不是叫 SXSSFWorkbook,但占内存还是挺多的,我当时三百万记录差不多耗 2G 内存,不过为什么不分几个 excel 文件然后打成压缩包呢,excel 太大打开可能会崩溃
    aitaii
        39
    aitaii  
       117 天前
    excel 很大,你的电脑忍一下
    Lemeng
        40
    Lemeng  
       117 天前
    千万级,客户也是秀逗
    kg2019
        41
    kg2019  
       117 天前
    easyExce 了解一下
    levon
        42
    levon  
       117 天前
    分文件吧,存在一个 excel 里干吗用
    jack778
        43
    jack778  
       117 天前
    那么大弄成一个文件怎么操作呢,客户的电脑配置有多牛呢
    Hallelu
        44
    Hallelu  
       117 天前
    之前跟一个客户做 excel 导出的功能,他说数据多,直接给他声明,单个 excel 超过一百万,不做....
    est
        45
    est  
       117 天前
    .csv 斥候
    dayeye2006199
        46
    dayeye2006199  
       116 天前
    建议走 tsv + 份文件 + 压缩的路线吧。
    excel 虽然很牛。。但也不是万能的。
    Vegetable
        47
    Vegetable  
       116 天前
    实际上,这个性能瓶颈时 Excel 本身带来的,Excel 天生不适合大规模数据,导出到 Excel 是一个非常耗时的操作。建议不要分 Sheet,而是分工作簿。
    wxw752
        48
    wxw752  
       116 天前
    easyexcel 导出 List<Map<String, Object>> 这种格式的 我昨天刚写完
    wxy1991
        49
    wxy1991  
       116 天前
    除了 easyexcel 还有个 eec,不用依赖 poi,效率比 easyexcel 还要高,不过你这很明显需求不合理,1000w 的 excel 我就不信有电脑能打开,我的破电脑打开个 500m 的 word 感觉就要卡死了
    someonedeng
        50
    someonedeng  
       116 天前
    真给他导出了,他怎么打开? 能不能分成多个 excel 文件再打包 zip ?
    beginor
        51
    beginor  
       116 天前 via Android
    软件工程师,多动脑子,不是程序猿。
    dcncy
        52
    dcncy  
       116 天前 via iPhone
    之前做过一个 700w+的数据导出,每一行 40 多列。
    使用的是 easyExcel 导的,分多个 excel,多个 sheet,多线程跑效率能快点。
    janda
        53
    janda  
       115 天前
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4121 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 06:15 · PVG 14:15 · LAX 22:15 · JFK 01:15
    ♥ Do have faith in what you're doing.