正在处理大型 xlsx 文件

2022-09-01 03:12:36

我需要自动调整大型(30k +行)xlsx文件中的所有行。

以下通过 apache poi 编写的代码适用于小文件,但适用于大文件:OutOfMemoryError

Workbook workbook = WorkbookFactory.create(inputStream);
Sheet sheet = workbook.getSheetAt(0);

for (Row row : sheet) {
    row.setHeight((short) -1);
}

workbook.write(outputStream);

更新:遗憾的是,增加堆大小不是一个选项 - 出现在和 30k 行不是上限。OutOfMemoryError-Xmx1024m


答案 1

请尝试使用事件 API。有关详细信息,请参阅 POI 文档中的事件 API(仅限 HSSF)和 XSSF 和 SAX(事件 API)。该页面中的几句话:

高铁:

事件 API 比用户 API 新。它适用于愿意学习一些低级API结构的中级开发人员。它使用起来相对简单,但需要对Excel文件的各个部分有基本的了解(或学习的意愿)。提供的优点是,您可以读取内存占用相对较小的 XLS。

XSSF:

如果内存占用是一个问题,那么对于 XSSF,您可以获取基础 XML 数据,并自行处理它。这适用于那些愿意学习一些.xlsx文件的低级结构,并且喜欢用java处理XML的中级开发人员。它使用起来相对简单,但需要对文件结构有基本的了解。提供的优点是,您可以读取内存占用相对较小的 XLSX 文件。

对于输出,一种可能的方法在博客文章流式处理 xlsx 文件中进行了介绍。(基本上,使用 XSSF 生成容器 XML 文件,然后将实际内容作为纯文本流式传输到 xlsx zip 存档的相应 xml 部分。


答案 2

通过使用文件而不是流,可以显著提高内存使用率。(最好使用流式处理 API,但流式处理 API 有限制,请参阅 http://poi.apache.org/spreadsheet/index.html)

所以不是

Workbook workbook = WorkbookFactory.create(inputStream);

Workbook workbook = WorkbookFactory.create(new File("yourfile.xlsx"));

这是根据: http://poi.apache.org/spreadsheet/quick-guide.html#FileInputStream

文件与输入流

“打开工作簿时,无论是.xls HSSFWorkbook,还是.xlsx XSSFWorkbook,都可以从文件或 InputStream 加载工作簿。使用File对象可以降低内存消耗,而InputStream需要更多的内存,因为它必须缓冲整个文件。


推荐