XLSX를 Java를 사용하여 CSV 파일로 변환하는 방법을 많이 발견했습니다. 모든 솔루션에는 XSSFWorkbook
이 사용됩니다. 내가 직면 한 문제는 스트림에 너무 많은 데이터가있는 것 같습니다. 나는 이유를 모르겠다. 파일은 단지 4MB이다.XLSX에서 CSV로 메모리 부족 오류
CODE : 오류가 나는 데이터 (StringBuffer를) 뭔가를 추가하고 스위치 문에서 줄을 가리키는하지만 문제가 될해서는 안 내가 널링하고
// 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'에서 물건을 채우고 있습니다. 어쨌든 그것을 왜 메모리에 저장해야합니까? 한 줄을 만들고 파일에 쓰고 계속 진행하면됩니다 (아마도'BufferedWriter'를 사용하기를 원할 것입니다.) 또한 String을 만들고 그것을 메모리 풋 프린트와 중복되는'byte []'로 변환하는 이유는 무엇입니까? 당신의 JVM과 GC의 속도는 많은 추가적인 객체를 얻습니다. 한 가지 시도는 한계를 낮추는 것입니다, 그리고 새로운'StringBuffer'를 생성하는 대신 그것을 비우고 재사용하는 것입니다 .'StringBuffer' 대신 –
그래, 그냥 setLength (0)을 사용하기 전에 문제가 거기에 없었지만 fileInputStream 중이었습니다 –
큰 개체가 주변에 머물러있어 재사용 성이 좋을 수도 있습니다. 읽는 동안 그것이 발생하는 것을 의미하지 않습니다. 당신의 메모리가 가득 차고 큰'StringBuffer'가 처음 수정 될 것입니다. 또 다른 메모는 당신이'StringBuffer'를 사용하고 있지만 아직도 문자열 concat을 사용하여 추가하고 있습니다. 문자열. 나는' + ";" "를 case 문 다음에 추가하고 case 문 다음에'data.append (';')'를 추가하십시오. concat에 대한 추가 String 생성을 저장합니다. –