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