Java 使用POI读取大型excel时出现内存问题

Java 使用POI读取大型excel时出现内存问题,java,excel,apache-poi,sax,export-to-csv,Java,Excel,Apache Poi,Sax,Export To Csv,我工作的要求,我需要读取和转换大型xlsx到csv文件。我需要在每行中读取特定数量的单元格(预定义)。输入xlsx表包含100万条记录,最大大小为150 MB。我使用了POI API。它可以很好地处理小xlsx文件,对于大文件,它抛出Java堆空间错误。请查看下面的代码并提供解决方案。我不太了解Event/SAXParser api,并假设它适合读取大型xls文件 package test; import java.io.File; import java.io.FileInputStream;

我工作的要求,我需要读取和转换大型xlsx到csv文件。我需要在每行中读取特定数量的单元格(预定义)。输入xlsx表包含100万条记录,最大大小为150 MB。我使用了POI API。它可以很好地处理小xlsx文件,对于大文件,它抛出Java堆空间错误。请查看下面的代码并提供解决方案。我不太了解Event/SAXParser api,并假设它适合读取大型xls文件

package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Iterator;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class XLSXToCSVConverterNew {


    public static void xlsx(File inputFile, File outputFile,int expectedColumns) {
        // For storing data into CSV files
       StringBuffer data = new StringBuffer();
       String separetorString="|";

        try {
            if(outputFile.exists())
                outputFile.delete();
            FileOutputStream fos = new FileOutputStream(outputFile);
            XSSFWorkbook wBook = new XSSFWorkbook(new FileInputStream(inputFile));
            XSSFSheet sheet = wBook.getSheetAt(0);
            Row row;
            System.out.println("Number of rows in sheet are :"+sheet.getLastRowNum());
            Iterator<Row> rowIterator = sheet.iterator();
            while (rowIterator.hasNext()) {
                row = rowIterator.next();
//check whether content is there in atleast one cell out of expected columns count
                if (containsValue(row, 0, expectedColumns-1) == true){  
                for(int i=0; i<=expectedColumns-1; i++) {
                    Cell cell = row.getCell(i);

                    switch (cell.getCellType()) {
                       case Cell.CELL_TYPE_BOOLEAN:
                       cell.setCellType(Cell.CELL_TYPE_STRING);
                          if(i!=expectedColumns-1)
                        data.append(cell.getStringCellValue() + separetorString);                          
                       else
                        data.append(cell.getStringCellValue() );

                            break;
                        case Cell.CELL_TYPE_NUMERIC:
                             cell.setCellType(Cell.CELL_TYPE_STRING);
                             if(i!=expectedColumns-1)
                            data.append(cell.getStringCellValue() + separetorString);
                            else
                                data.append(cell.getStringCellValue() );    
                            break;
                        case Cell.CELL_TYPE_STRING:
                            if(i!=expectedColumns-1)
                            data.append(cell.getStringCellValue() + separetorString);
                            else
                                data.append(cell.getStringCellValue() );
                            break;

                        case Cell.CELL_TYPE_BLANK:
                            if(i!=expectedColumns-1)
                            data.append("" + separetorString);
                            else
                                 data.append("");
                            break;
                        default:
                            if(i!=expectedColumns-1)
                            data.append(cell + separetorString);
                            else                            
                                data.append(cell);
                    }
                }
                if(data.length()!=0){
                    data.append('\n'); 
                   fos.write(data.toString().getBytes());
                   data.delete(0, data.length());
                    }
            }


            }
            fos.close();

        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }


    public static boolean containsValue(Row row, int fcell, int lcell) {
        boolean flag = false;
        for (int i = fcell; i < lcell; i++) {
            if (StringUtils.isEmpty(String.valueOf(row.getCell(i))) == true
                    || StringUtils.isWhitespace(String.valueOf(row.getCell(i))) == true
                    || StringUtils.isBlank(String.valueOf(row.getCell(i))) == true
                    || String.valueOf(row.getCell(i)).length() == 0 || row.getCell(i) == null) {
            } else {
                flag = true;
            }
        }
        return flag;
    }

    public static void main(String[] args) {
        File inputFile = new File("/home/mypc/Desktop/poi/test.xlsx");
        File outputFile = new File("/home/mypc/Desktop/poi/test.csv");
        xlsx(inputFile, outputFile,30);
    }

}
封装测试;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.util.Iterator;
导入org.apache.commons.lang.StringUtils;
导入org.apache.poi.ss.usermodel.Cell;
导入org.apache.poi.ss.usermodel.Row;
导入org.apache.poi.xssf.usermodel.xssfheet;
导入org.apache.poi.xssf.usermodel.xssf工作簿;
公共类XLSXToCSVConverterNew{
公共静态void xlsx(文件inputFile、文件outputFile、int expectedColumns){
//用于将数据存储到CSV文件中
StringBuffer数据=新的StringBuffer();
字符串分隔符String=“|”;
试一试{
if(outputFile.exists())
outputFile.delete();
FileOutputStream fos=新的FileOutputStream(outputFile);
XSSF工作簿wBook=新XSSF工作簿(新文件InputStream(inputFile));
XSSFSheet sheet=wBook.getSheetAt(0);
行行;
System.out.println(“工作表中的行数为:+sheet.getLastRowNum());
迭代器rowIterator=sheet.Iterator();
while(roweiterator.hasNext()){
行=行迭代器。下一步();
//检查内容是否位于预期列计数之外的至少一个单元格中
if(containsValue(行,0,expectedColumns-1)=true){

对于(int i=0;i请向我们展示StackTraceAache POI装运a,如果您使用它会发生什么?请向我们展示StackTraceAache POI装运a,如果您使用它会发生什么?