根据SXSSF(Streaming Usermodel API)文档:
SXSSF(package :)
org.apache.poi.xssf.streaming是XSSF 的API兼容流式扩展,用于在必须生成非常大的电子表格时使用,并且堆空间有限.SXSSF通过限制对滑动窗口内行的访问来实现其低内存占用,而XSSF允许访问文档中的所有行.不再在窗口中的旧行变得不可访问,因为它们被写入磁盘.
但是,在提供的示例中,刷新发生在工作簿被赋予写入文件的文件位置之前.
public static void main(String[] args) throws Throwable {
Workbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk
Sheet sh = wb.createSheet();
for(int rownum = 0; rownum < 1000; rownum++){
Row row = sh.createRow(rownum);
for(int cellnum = 0; cellnum < 10; cellnum++){
Cell cell = row.createCell(cellnum);
String address = new CellReference(cell).formatAsString();
cell.setCellValue(address);
}
}
// Rows with rownum < 900 are …Run Code Online (Sandbox Code Playgroud) 我开发了一个 Java 类来使用 SXSSF 工作簿来克服在编写非常大的电子表格时总是由 XSSF 工作簿引起的 Java 堆错误。有关解决方案,请参阅http://poi.apache.org/spreadsheet/how-to.html#sxssf。
简而言之,我使用workbook = new SXSSFWorkbook(SXSSFWorkbook.DEFAULT_WINDOW_SIZE);代替workbook = new XSSFWorkbook();
这个解决方案就像魔术一样工作,我现在能够以更低的内存占用编写非常大的 xlsx 电子表格。
但是,我遇到了一个问题。使用 SXSSF 工作簿时,与 Excel 本身相比,它实际上生成了更大的 xlsx 文件。例如,SXSSF 创建了 33MB,而 Excel 使用相同的数据集创建了 25MB。为什么?
我调查了一下,找到了原因:
我将 .xlsx 扩展名更改为 .zip,以便我可以打开它并查看\xl\worksheets\sheet1.xml工作表文件。我发现使用的内联字符串t="inlineStr"是由 SXSSF 生成的,而使用 t="s" (v 标记) 的共享字符串表是由 Excel 生成的。我检查了 XSSF 还创建了共享字符串表。在巨大的电子表格中的每个单元格中使用 t="inlineStr" 会更快地增加文件大小。
我的问题是,是否可以强制 SXSSF 工作簿sheet1.xml基于共享字符串表(使用 v 标签 - t="s")而不是内联字符串 (t="inlineStr") 生成文件?我希望这个解决方案可以大大减少最终文件的大小。有谁知道?
试图在使用 apache POI 3.17 的应用程序上实现 excel 导出功能。
在我的本地 tomcat 服务器和 Windows 开发环境中一切正常。但是,SXSSFWorkbook workbook.createSheet() 方法在 linux tomcat 服务器上失败,而不会抛出任何有意义的错误(它只是挂起)。
奇怪的是,XSSFWorkbook createSheet 类上的相同方法工作正常。下面是代码片段。有没有人遇到过类似的问题?
final SXSSFWorkbook workbook = new SXSSFWorkbook();
workbook.setCompressTempFiles(true);
SXSSFSheet sheet = workbook.createSheet("Sheet 1"); //this method fails
final XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet 1"); // this works fine
Run Code Online (Sandbox Code Playgroud)
编辑
我创建了一个自定义TempFileCreationStrategy以确保 tomcat 将文件写入它具有完全访问权限的目录。我可以看到文件已创建,但它在尝试将任何数据写入文件时挂起。
我无法弄清楚这一点。
编辑2
我已经启用了 POI 日志记录,但我仍然没有得到任何可以调查的有意义的信息。在我的本地服务器上,POI 日志记录在开始写入文件时会吐出以下内容:
[20:13:05,005]DEBUG (?:?) - Save core properties part
[20:13:05,005]DEBUG (?:?) - Save package relationships
[20:13:05,005]DEBUG (?:?) - Save content …Run Code Online (Sandbox Code Playgroud) 当我尝试使用包含超过64000条记录的apache poi将数据写入excel表时,使用SXSSF并且我收到以下错误,
检测到拉链炸弹!该文件将超过最大值.压缩文件大小与扩展数据大小的比率.这可能表示该文件用于夸大内存使用量,因此可能带来安全风险.如果需要处理超出此限制的文件,可以通过ZipSecureFile.setMinInflateRatio()调整此限制.计数器:820224,cis.counter:8192,比率:0.009987515605493134Limits:MIN_INFLATE_RATIO:0.01
我找到了一个解决方案,通过添加ZipSecureFile.setMinInflateRatio(0.009)来说明,我需要知道它为什么会发生以及我需要为上述错误广告提供的限制在哪里添加解决方案,解决方案的参考:( 如何确定检索Excel文件时是否抛出Zip Bomb错误样式表是否合法?)
如果有任何其他解决方案,请告诉我