首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java.lang.OutOfMemoryError:将xlsx转换为csv格式时的JAVA堆空间。我试过这个没有用的<java-opts>-Xms400m -Xmx4096m</java-opts>

Java.lang.OutOfMemoryError:将xlsx转换为csv格式时的JAVA堆空间。我试过这个没有用的<java-opts>-Xms400m -Xmx4096m</java-opts>
EN

Stack Overflow用户
提问于 2020-01-27 19:39:44
回答 1查看 359关注 0票数 0
代码语言:javascript
复制
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.net.*;
import java.util.List;

import com.google.common.base.Joiner;

import org.apache.poi.hssf.usermodel.HSSFCell;
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;

import org.apache.hadoop.fs.*;
import org.apache.hadoop.conf.*;

import static org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted;

public class XlsxToCsv {

    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private XSSFSheet excelSheet;
    private String outputFile;
    private String defaultFS;
    private List<String[]> arrayCSV = new ArrayList<>();

    // Minumun amount of rows to expect
    private int minRows = 5;

    // Escape char for hive
    private String escapeStr = "\\";

    // Escape char for csv
    private String separatorStr = ",";

    public XlsxToCsv(String inputFile, String outputFile, String excelSheet, String defaultFS) throws IOException {
        this.outputFile = outputFile;
        this.defaultFS = defaultFS;
        this.excelSheet = new XSSFWorkbook(new FileInputStream(inputFile)).getSheet(excelSheet);
    }

    public void setMinRows(int minRows) {
        this.minRows = minRows;
    }

    public void setEscapeStr(String escapeStr) {
        this.escapeStr = escapeStr;
    }

    public void setSeparatorStr(String separatorStr) {
        this.separatorStr = separatorStr;
    }

    public List<String[]> getArrayCSV() {
        return arrayCSV;
    }

    private void convertToCsv() {
        Cell cell;

        try {

            for (Row row : excelSheet) {
                int lastColumnNum = Math.max(row.getLastCellNum(), minRows);
                String[] rowArray = new String[lastColumnNum];

                for (int count = 0; count < lastColumnNum; count++) {
                    cell = row.getCell(count, Row.CREATE_NULL_AS_BLANK);

                    switch (cell.getCellType()) {
                        case HSSFCell.CELL_TYPE_FORMULA:
                            rowArray[count] = isCellDateFormatted(cell) ? dateFormat.format(cell.getDateCellValue()) : Double.toString(cell.getNumericCellValue());
                            break;
                        case Cell.CELL_TYPE_BOOLEAN:
                            rowArray[count] = Boolean.toString(cell.getBooleanCellValue());
                            break;
                        case Cell.CELL_TYPE_NUMERIC:
                            rowArray[count] = isCellDateFormatted(cell) ? dateFormat.format(cell.getDateCellValue()) : Double.toString(cell.getNumericCellValue());
                            break;
                        case Cell.CELL_TYPE_STRING:
                            rowArray[count] = cell.getStringCellValue().replace(separatorStr, escapeStr + separatorStr).replace("\n", " ");
                            break;
                        default:
                            rowArray[count] = "";
                    }
                }

                arrayCSV.add(rowArray);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void writeCsv() {
        try {
            FileSystem fs = FileSystem.get(new URI(defaultFS), new Configuration());
            FSDataOutputStream outputStream = fs.create(new Path(outputFile));

            Joiner joinEmpty = Joiner.on("").skipNulls();
            Joiner joinComma = Joiner.on(separatorStr).skipNulls();

            for (String[] i : arrayCSV) {
                if (joinEmpty.join(i).length() > 0) {
                    outputStream.writeBytes(joinComma.join(i) + "\n");
                }
            }

            outputStream.hflush();
            outputStream.hsync();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws IOException {
        String inputFile = args[0];
        String outputFile = args[1];
        String excelSheet = args[2];
        String defaultFS = args[3];

        XlsxToCsv processExcelFile = new XlsxToCsv(inputFile, outputFile, excelSheet, defaultFS);
        processExcelFile.convertToCsv();
        processExcelFile.writeCsv();

        Joiner joinEmpty = Joiner.on("").skipNulls();
        Joiner joinComma = Joiner.on(",").skipNulls();

        for (String[] record : processExcelFile.getArrayCSV()) {
            if (joinEmpty.join(record).length() > 0) {
                System.out.print(joinComma.join(record));
                System.out.print("\n");
            }
        }
    }
}

在将xlsx转换为csv时,我遇到以下错误消息:

代码语言:javascript
复制
Caused by: java.lang.OutOfMemoryError: Java heap space  
at java.io.ByteArrayOutputStream.<init>(ByteArrayOutputStream.java:77)  
at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource$FakeZipEntry.<init>(ZipInputStreamZipEntrySource.java:123)  
at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource.<init>(ZipInputStreamZipEntrySource.java:57)  
at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:93)  
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:278)  
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:37)  
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:274)  
at acvx.agg.qwuer.excel.XlsxToCsv.<init>(XlsxToCsv.java:43)  
at acvx.agg.qwuer.excel.XlsxToCsv.main(XlsxToCsv.java:135)  
EN

回答 1

Stack Overflow用户

发布于 2020-01-29 00:49:55

一些建议: 1)我怀疑你正在逐行阅读excel,但在一些行之后可能没有数据,而且看起来没有检查你的程序!2)我建议试着编辑这个只运行50行,你会得到一个很好的想法,如果你的excel是250行,它可以转换那部分。3)如果你在上面获得了成功,尝试进入读和写的循环,当前你正在将所有内容读取到数组,然后下一个函数将所有内容写入。只是建议打破这一点,比如读10和写10。确保在此之后将变量设置为空,以便它们可用于垃圾回收4) eclipse大小的增加取决于机器的总RAM,对于给定的机器,您不能超过一个点,所以我同意这不一定能解决您的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59930426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档