Я нашел множество решений, как преобразовать файл XLSX в файл CSV с помощью Java, все решения используют: XSSFWorkbook
. Проблема, с которой я сталкиваюсь, заключается в том, что, вероятно, в потоке слишком много данных. Я просто не понимаю, почему, файл всего 4 МБ.
КОД:
// 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), но я обнуляю его, поэтому это не должно быть проблемой.
StringBuffer
, которые могут быть не такими эффективными. Зачем вообще хранить это в памяти? Просто создайте одну строку, напишите это в файл и двигайтесь дальше (вы, вероятно, захотите использоватьBufferedWriter
. Также почему вы создаете строку и преобразуете ее вbyte[]
, которая дублирует объем памяти. В зависимости от скорости вашей JVM и GC вы получаете много дополнительных объектов.Одна вещь, с которой нужно начать, это снизить лимит и вместо создания новогоStringBuffer
просто очистить его и использовать повторно.ВместоStringBUffer
я предлагаю использоватьStringBuilder
. - person M. Deinum   schedule 18.09.2014StringBuffer
. Еще одно замечание: вы используетеStringBuffer
, но по-прежнему используете String concat для добавления строк. Я предлагаю удалить+ ";"
из вашего заявления о случаях и добавитьdata.append(';')
после утверждений о случаях. Сохраняет создание дополнительной строки для concat. - person M. Deinum   schedule 18.09.2014