几年前,我遇到了使用 jXLS 和 POI XSSF 创建大型 excel 文件的问题。如果我没记错的话,我认为 XSSF 会在磁盘上创建类似 1GB+ 的临时文件来创建 10mb 的 excel 文件。所以我停止使用 jXLS 而是使用 SXSSF 来创建 excel 文件,但今天我有了使用 jXLS 或 JETT 的新理由。
jXLS 和 JETT 网站似乎都暗示性能要好得多,但是 POI 的 XSSF网站仍然笼统地说 XSSF 需要更高的内存占用。我想知道现在这种更高的内存占用是否相当于合理的 10% 开销,或者它是否仍然像几年前那样的 10,000% 开销。
POI 3.9 XSSF 是否修复了疯狂的内存问题?我是否应该担心将它与 jXLS 或 JETT 一起使用?或者是否有某些陷阱需要避免?我对重复使用单元格样式很谨慎。
最佳答案
要回答您的问题,是的,POI 在处理大型 XLSX 文件时总是会使用非常大量的内存,这比 XLSX 文件的大小大得多。 我认为这不会很快改变,并且有很明显的原因:XLSX 基本上是一堆压缩的 XML 文件,并且 XML 压缩得很好(大约 10 倍)。将此 XML 不压缩地放在内存中就已经将内存消耗增加了十倍,因此如果您添加数据结构的所有开销,您不可能期望内存消耗比 XLSX 文件大小增加 10%。
现在,好消息是,如评论中所述,Apache POI 引入了 SXSSF用于在电子表格中流式传输非常大量的数据,具有非常好的性能和低内存使用率。以这种方式生成的 XLSX 文件仍然在硬盘上流式传输,它们最终可能会占用相当多的空间,但至少您不会在写入数十万行时冒 OOME 的风险。
您的问题是您无法让 JETT 直接使用 SXSSF,因为它需要将整个文档加载到内存中才能执行模板填充。 JETT作者快速讨论了这个话题here .
我有同样的问题,最后做了一个两步的 XLSX 创建:
用于生成 header 和格式的标准 JETT XLSX 模板。第一张表的最后一行包含带有 $$tokens$$ 的单元格,每个单元格一个。我不使用 JETT 插入大量行。
JETT 完成工作后,我重新打开工作簿,阅读然后删除第一个电子表格最后一行的 $$tokens$$,并开始使用 SXSSF 逐行传输数据。
当然,这种方法也有局限性: - 在行插入期间,您不能在任何流式处理行上使用 JETT(但您之前可以,例如动态选择 $$tokens$$ 的顺序) - 除非您使用 POI API 自行处理,否则不会复制单元格格式。我个人更喜欢在我的 XLSX 文件中格式化整个列,它将应用于流式数据。
如果您想使用通过 SXSSF 插入的数据显示图表,这也适用:您可以使用函数 OFFSET 和 COUNTA 定义一个命名范围,然后创建一个数据透视表和数据透视图,当在 Excel 中打开 XLSX 时,这些数据透视表和数据透视图将被刷新。
关于java - POI XSSF 是否仍然存在疯狂的错误内存问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21488738/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test