XLSX到CSV内存不足错误

我发现很多解决scheme如何使用Java将XLSX转换为CSV文件,所有解决scheme都使用: XSSFWorkbook 。 我面临的问题是,这个stream可能是有太多的数据。 我只是不明白为什么,这个文件只有4MB。

码:

 // For storing data into CSV files StringBuffer data = new StringBuffer(); try { FileOutputStream fos = new FileOutputStream(outputFile); System.out.println("Getting input stream."); // Get the workbook object for XLS file XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(inputFile)); System.out.println(" - Done"); // Get first sheet from the workbook XSSFSheet sheet = workbook.getSheetAt(0); Cell cell; Row row; // Iterate through each rows from first sheet Iterator<Row> rowIterator = sheet.iterator(); System.out.println(" - Reading xlsx rows."); while (rowIterator.hasNext()) { i++; row = rowIterator.next(); // For each row, iterate through each columns Iterator<Cell> cellIterator = row.cellIterator(); while (cellIterator.hasNext()) { cell = cellIterator.next(); switch (cell.getCellType()) { case Cell.CELL_TYPE_BOOLEAN: data.append(cell.getBooleanCellValue() + ";"); break; case Cell.CELL_TYPE_NUMERIC: data.append(cell.getNumericCellValue() + ";"); break; case Cell.CELL_TYPE_STRING: data.append(cell.getStringCellValue() + ";"); break; case Cell.CELL_TYPE_BLANK: data.append("" + ";"); break; default: data.append(cell + ";"); } } data.append('\n'); int limit = 10000; if ((i % limit) == 0) { System.out.println(" - Writing " + limit + " data."); fos.write(data.toString().getBytes()); fos.flush(); data = null; data = new StringBuffer(); System.out.println(" - Data written."); } } fos.write(data.toString().getBytes()); fos.flush(); fos.close(); 

错误是指向switch语句中的行附加到数据(StringBuffer)的行,但我把它归零,所以它不应该是一个问题。

现在,您可能无法使用SXSSFWorkbook(因为它是只写的),但是您可以使用基于SAX的API将程序转换为stream式。 编辑:另一件你可能想要尝试的是从文件而不是InputStream创buildXSSFWorkbook(我记得读的地方,基于文件的代码需要更less的内存)。

(第一次尝试是:由于您正在顺序读取数据, SXSSFWorkbook类应该只是您需要的东西。)

xlsx格式只是一个带有内容xml和共享stringxml的zip文件。 因此,4 MB压缩,可能是非常大的未压缩。

使用zip文件系统可以将共享string加载到内存中,然后依次读取内容xml,立即输出。

作为两个内部文件,你可以使用java的zip文件系统。 单调但不难。