1

I have a requirement to do the following

1)Copy a huge excel file 1400*1400 and make a copy.

2)Read the copied file and add new columns and rows and also edit at the same time.

3)This is going to be a standalone program and not on a server. I have limitations of having low memory footprint and fast performance.

I have done some reading and have found the following

1)There is no API to copy sucg a huge file

2)SXSSF can be using for writing but not for reading

3)XSSF and SAX (Event API) can be using for reading but not for editing.If i tried to read and store as objects again i will have a memory issue.

Please can you help on how i can do this?

4

3 回答 3

1

假设您的内存大小足以使用 XSSF/SAX 读取和 SXSSF 写入,让我建议以下解决方案。

1) 使用 XSSF/SAX 读取文件。对于每一行,使用行数据创建一个对象,并立即使用 ObjectOutputStream 或您认为方便的任何其他输出格式将其写入文件。您将为每一行创建一个单独的文件。并且内存中只会有 1 个行对象,因为您可以使用每一行的数据不断修改同一个对象。

2)进行任何您需要的修改。对于需要修改的行,将相应的文件读回您的行对象,根据需要进行修改,然后将其写回。对于新行,只需在行对象中设置数据并将其写入新文件即可。

3) 使用 SXSSF 通过一次读取 1 行目标文件并将其存储在输出电子表格中来重组电子表格。

这样,您一次只能在内存中使用 1 行。

于 2013-06-04T18:45:43.877 回答
1

如果由于出现“内存不足”或“GC 超出限制”而导致的数据过多,并且如果内存存在问题,则可以将数据最初解析为 xml 文件。可以用 xml 文件替换 excel 工作表,以便将内存使用量降至最低。

在 excel 中,工作表表示为 xml。使用 java.util.zip.ZipFile 可以识别每个条目。工作表的 xml 可以替换为解析的 xml,以便我们在 excel 工作表中获得预期的数据。

以下类可用于创建 xml 文件:

public class XmlSpreadsheetWriter {
    private final Writer _out;
    private int _rownum;

    public XmlSpreadsheetWriter(Writer out){
        _out = out;
    }

    public void beginSheet() throws IOException {
        _out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">" );
        _out.write("<sheetData>\n");
    }

    public void endSheet() throws IOException {
        _out.write("</sheetData>");
        _out.write("</worksheet>");
    }

    public void insertRow(int rownum) throws IOException {
        _out.write("<row r=\""+(rownum+1)+"\">\n");
        this._rownum = rownum;
    }

    public void endRow() throws IOException {
        _out.write("</row>\n");
    }

    public void createCell(int columnIndex, String value, int styleIndex) throws IOException {
     String ref = new CellReference(_rownum, columnIndex).formatAsString();
     _out.write("<c r=\""+ref+"\" t=\"inlineStr\"");
     _out.write(" s=\""+styleIndex+"\"");
     _out.write(">");
     _out.write("<is><t>"+value+"</t></is>");
     _out.write("</c>");
    }

    public void createCell(int columnIndex, double value, int styleIndex) throws IOException {
     String ref = new CellReference(_rownum, columnIndex).formatAsString();
     _out.write("<c r=\""+ref+"\" t=\"n\"");
     _out.write(" s=\""+styleIndex+"\"");
     _out.write(">");
     _out.write("<v>"+value+"</v>");
     _out.write("</c>");
    }

    public void createEmptyCell(int columnIndex, int styleIndex)throws IOException {
     String ref = new CellReference(_rownum, columnIndex).formatAsString();
     _out.write("<c r=\""+ref+"\" t=\"n\"");
     _out.write(" s=\""+styleIndex+"\"");
     _out.write(">");
     _out.write("<v></v>");
     _out.write("</c>");
    }
} 
于 2013-11-11T13:58:25.390 回答
0

如果内存是处理您指出的记录数(即 1400*1400 )的问题,那么获取 XML 数据并处理这些数据可能是您的解决方案。我知道这可能不是最好的解决方案,但它肯定会解决您的低内存要求。甚至 POI 网站也指出了这个解决方案:

“如果内存占用是一个问题,那么对于 XSSF,您可以获取底层 XML 数据,并自己处理它。这适用于愿意学习一点 .xlsx 文件低级结构的中级开发人员,并且“谁喜欢用java处理XML。它使用起来比较简单,但需要对文件结构有基本的了解。提供的好处是你可以读取内存占用相对较小的XLSX文件。”

来源: http: //poi.apache.org/spreadsheet/how-to.html

于 2013-06-04T19:20:36.367 回答