Java XLSX到CSV内存不足错误
我找到了很多解决方案,如何使用Java将XLSX转换为CSV文件,所有的解决方案都使用:xssf工作簿。我面临的问题是,流可能有太多的数据。我不明白为什么,这个文件只有4mb 代码:Java XLSX到CSV内存不足错误,java,excel,csv,xlsx,xssf,Java,Excel,Csv,Xlsx,Xssf,我找到了很多解决方案,如何使用Java将XLSX转换为CSV文件,所有的解决方案都使用:xssf工作簿。我面临的问题是,流可能有太多的数据。我不明白为什么,这个文件只有4mb 代码: 错误指向switch语句中的第行,我在其中向data StringBuffer添加了一些内容,但我正在将其置零,因此它不应该是一个问题。现在您可能无法使用SXSSFWorkbook,因为它是只写的,但您可以使用。编辑:您可能想尝试的另一件事是从文件创建XSSFWorkbook,而不是从InputStream创建。我
错误指向switch语句中的第行,我在其中向data StringBuffer添加了一些内容,但我正在将其置零,因此它不应该是一个问题。现在您可能无法使用SXSSFWorkbook,因为它是只写的,但您可以使用。编辑:您可能想尝试的另一件事是从文件创建XSSFWorkbook,而不是从InputStream创建。我记得在某个地方读到,基于文件的代码需要更少的内存 第一次尝试是:
由于您是按顺序读取数据,因此该类应该正是您所需要的。xlsx格式只是一个包含内容xml和共享字符串xml的zip文件。因此4 MB压缩,很可能是非常大的未压缩 使用zip文件系统,您可以将共享字符串加载到内存中,然后按顺序读取内容xml,并立即输出
考虑到两个内部文件,您可以使用java的zip文件系统。乏味但不难。试试这段代码。这段代码对我来说非常有效,我希望对你也有效
package com.converting;
import java.io.FileInputStream;
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.opencsv.CSVWriter;
import java.util.Iterator;
import java.io.FileWriter;
public class XlsxtoCSV {
public static void main(String[] args) throws Exception{
FileInputStream input_document = new FileInputStream(new File("/home/blackpearl/Downloads/aa.xlsx"));
XSSFWorkbook my_xls_workbook = new XSSFWorkbook(input_document);
XSSFSheet my_worksheet = my_xls_workbook.getSheetAt(0);
Iterator<Row> rowIterator = my_worksheet.iterator();
FileWriter my_csv=new FileWriter("/home/blackpearl/Downloads/Newaa.csv");
CSVWriter my_csv_output=new CSVWriter(my_csv);
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
int i=0;//String array
String[] csvdata = new String[20];
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext()) {
Cell cell = cellIterator.next(); //Fetch CELL
switch(cell.getCellType()) { //Identify CELL type
case Cell.CELL_TYPE_STRING:
csvdata[i]= cell.getStringCellValue();
break;
}
i=i+1;
}
my_csv_output.writeNext(csvdata);
}
System.out.println("file imported");
my_csv_output.close(); //close the CSV file
input_document.close(); //close xlsx file
}
}
SXSSFWorkbook是只写的,请检查:您正在将内容填充到StringBuffer中,这可能没有那么有效。为什么要把它存储在内存中呢?只需创建一行,将其写入文件,然后继续使用BufferedWriter。另外,为什么要创建一个字符串并将其转换为一个字节[],然后复制内存占用。根据JVM和GC的速度,您可以获得许多附加对象。首先要做的一件事是降低您的限制,而不是构建一个新的StringBuffer,只需清空它并重新使用。我建议使用StringBUffer,而不是StringBUffer。是的,在我使用setLength0之前,问题并不存在,而是在fileInputStream期间。大型对象可能会徘徊,因此重用可能更好。事实上,它发生在阅读时并不意味着它是因为阅读。您的内存已满,我将首先修复大型StringBuffer。另一个注意事项是,您正在使用StringBuffer,但仍在使用String concat添加字符串。我建议删除+;从您的case语句中添加数据。追加“;”在案件陈述之后。保存为concat创建其他字符串。
package com.converting;
import java.io.FileInputStream;
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.opencsv.CSVWriter;
import java.util.Iterator;
import java.io.FileWriter;
public class XlsxtoCSV {
public static void main(String[] args) throws Exception{
FileInputStream input_document = new FileInputStream(new File("/home/blackpearl/Downloads/aa.xlsx"));
XSSFWorkbook my_xls_workbook = new XSSFWorkbook(input_document);
XSSFSheet my_worksheet = my_xls_workbook.getSheetAt(0);
Iterator<Row> rowIterator = my_worksheet.iterator();
FileWriter my_csv=new FileWriter("/home/blackpearl/Downloads/Newaa.csv");
CSVWriter my_csv_output=new CSVWriter(my_csv);
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
int i=0;//String array
String[] csvdata = new String[20];
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext()) {
Cell cell = cellIterator.next(); //Fetch CELL
switch(cell.getCellType()) { //Identify CELL type
case Cell.CELL_TYPE_STRING:
csvdata[i]= cell.getStringCellValue();
break;
}
i=i+1;
}
my_csv_output.writeNext(csvdata);
}
System.out.println("file imported");
my_csv_output.close(); //close the CSV file
input_document.close(); //close xlsx file
}
}