2013-06-04 158 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>"); 
    } 
} 
相關問題