2013-06-04 159 views
1

我有一个要求做到以下几点如何使用POI读取和编辑巨大的Excel文件?

1)复制一个巨大的Excel文件1400 * 1400并进行复制。

2)读取复制的文件并添加新的列和行,并同时进行编辑。

3)这将是一个独立的程序,而不是在服务器上。我有限制内存占用少,性能快。

我已经做了一些阅读和发现下列

1)没有API复制sucg一个巨大的文件

2)SXSSF可以使用书写而不是阅读

3)XSSF和SAX(Event API)可以用于读取,但不能用于编辑。如果我尝试读取并再次存储为对象,我将遇到内存问题。

请问你能帮我怎么做?

+0

XSSF可以用于修改电子表格。但是,是的,你的记忆会有问题。 –

回答

1

假设您的内存大小足够大,可以使用XSSF/SAX读取并写入SXSSF,那么让我提出以下解决方案。

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

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

3)使用SXSSF重新组合电子表格,方法是每次读取1行对象文件并将其存储在输出电子表格中。

这样,你一次只能在内存中有一行。

0

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

“如果内存占用是一个问题,那么对于XSSF,您可以获取底层的XML数据并自行处理它,这适用于愿意学习一点点的.xlsx文件的低级结构,以及在java中处理XML的人都很高兴,它的使用相对简单,但需要对文件结构有一个基本的了解,其优点是你可以用相对比较简单的方式读取XLSX文件小内存占用“。

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

+0

这只是正常的API,它有大文件的问题,因此user1340251询问了一个不同的解决方案... – kiwiwings

+0

@kiwiwings我已经更新了答案,请您重新考虑给我打个招呼吧? –

+1

- ( - 1)只是因为你问得那么好......但是我需要为另一个投票:P – kiwiwings

1

如果有很多数据,由于其“内存的”或“GC超限超过”发生,并且如果存储器是个问题中的数据最初可以解析到一个XML文件。 Excel工作表可以用xml文件替换,以便内存使用量最小。

在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>"); 
    } 
} 
相关问题