From 8c530958ddc169eb275a31bd6429332fe9a3c78e Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Wed, 8 Jun 2011 12:38:07 +0000 Subject: [PATCH] SXSSF documentation and polishing git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1133372 13f79535-47bb-0310-9956-ffa450edef68 --- .../content/xdocs/spreadsheet/how-to.xml | 69 ++++++++++++++++++ .../content/xdocs/spreadsheet/index.xml | 38 +++++++++- .../resources/images/ss-features.png | Bin 0 -> 13173 bytes .../xssf/usermodel/examples/BigGridDemo.java | 11 +++ .../apache/poi/xssf/streaming/SXSSFSheet.java | 16 ++-- .../poi/xssf/streaming/SXSSFWorkbook.java | 46 ++++++++++++ 6 files changed, 169 insertions(+), 11 deletions(-) create mode 100644 src/documentation/resources/images/ss-features.png diff --git a/src/documentation/content/xdocs/spreadsheet/how-to.xml b/src/documentation/content/xdocs/spreadsheet/how-to.xml index 35e4a00030..a8f6515315 100644 --- a/src/documentation/content/xdocs/spreadsheet/how-to.xml +++ b/src/documentation/content/xdocs/spreadsheet/how-to.xml @@ -58,6 +58,7 @@
  • Event API (HSSF Only)
  • Event API with extensions to be Record Aware (HSSF Only)
  • XSSF and SAX (Event API)
  • +
  • SXSSF (Streaming User API)
  • Low Level API
  • @@ -620,6 +621,74 @@ public class ExampleEventUserModel { howto.processAllSheets(args[0]); } } +]]> + + +
    SXSSF (Streaming Usermodel API) +

    + XSSF is an API-compatible streaming extension of XSSF to be used when + very large spreadsheets have to be produced, and heap space is limited. + SXSSF achieves its low memory footprint by limiting access to the rows that + are within a sliding window, while XSSF gives access to all rows in the + document. Older rows that are no longer in the window become inaccessible, + as they are written to the disk. +

    +

    + When a new row is created via createRow() and the total number + of unflushed records would exeed the specified window size, then the + row with the lowest index value is flushed and cannot be accessed + via getRow() anymore. +

    +

    + A value of -1 indicates unlimited access. In this case all + records that have not been flushed by a call to flush() are available + for random access. +

    + +
    diff --git a/src/documentation/content/xdocs/spreadsheet/index.xml b/src/documentation/content/xdocs/spreadsheet/index.xml index f52d60c3dd..514460106d 100644 --- a/src/documentation/content/xdocs/spreadsheet/index.xml +++ b/src/documentation/content/xdocs/spreadsheet/index.xml @@ -73,6 +73,42 @@ the memory footprint for processing them is higher than for the older HSSF supported (.xls) binary files.

    + + + - + +
    +SXSSF (SInce POI 3.8 beta3) +

    Since 3.8-beta3, POI provides a low-memory footprint SXSSF API built on top of XSSF.

    +

    +XSSF is an API-compatible streaming extension of XSSF to be used when +very large spreadsheets have to be produced, and heap space is limited. +SXSSF achieves its low memory footprint by limiting access to the rows that +are within a sliding window, while XSSF gives access to all rows in the +document. Older rows that are no longer in the window become inaccessible, +as they are written to the disk. +

    +

    +In auto-flush mode the size of the access window can be specified, to hold a certain number of rows in memory. When that value is reached, the creationof an additional row causes the row with the lowest index to to be removed from the access window and written to disk.. Or, the window size can be set to grow dynamically; it can be trimmed periodically by an explicit call to flush(int keepRows) as needed. +

    +

    +Due to the streaming nature of the implementation, there are the following +limitations when compared to XSSF: +

    +
      +
    • Only a limited number of rows are accessible at a point in time.
    • +
    • Sheet.clone() is not supported.
    • +
    • Formula evaluation is not supported
    • +
    + +

    The table below synopsizes the comparative features of POI's Spreadsheet API:

    +

    Spreadsheet API Feature Summary

    + +

    + Spreadsheet API Feature Summary +

    +
    + + diff --git a/src/documentation/resources/images/ss-features.png b/src/documentation/resources/images/ss-features.png new file mode 100644 index 0000000000000000000000000000000000000000..17554c71514f7c4445c51f12ed0821bc7837c2d6 GIT binary patch literal 13173 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 literal 0 HcmV?d00001 diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java index 723c424fd4..91092232a9 100644 --- a/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java +++ b/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java @@ -36,7 +36,18 @@ import org.apache.poi.xssf.usermodel.*; * 2. create an application that streams data in a text file * 3. Substitute the sheet in the template with the generated data * + *

    + * Since 3.8-beta3 POI provides a low-memory footprint SXSSF API which implementing the "BigGridDemo" strategy. + * XSSF is an API-compatible streaming extension of XSSF to be used when + * very large spreadsheets have to be produced, and heap space is limited. + * SXSSF achieves its low memory footprint by limiting access to the rows that + * are within a sliding window, while XSSF gives access to all rows in the + * document. Older rows that are no longer in the window become inaccessible, + * as they are written to the disk. + *

    + * * @author Yegor Kozlov + * @see http://poi.apache.org/spreadsheet/how-to.html#sxssf */ public class BigGridDemo { private static final String XML_ENCODING = "UTF-8"; diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java index be90606e1b..baea693418 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java @@ -17,15 +17,10 @@ package org.apache.poi.xssf.streaming; +import java.io.*; import java.util.Iterator; import java.util.TreeMap; import java.util.Map; -import java.io.Writer; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.FileInputStream; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellReference; @@ -46,7 +41,7 @@ public class SXSSFSheet implements Sheet, Cloneable XSSFSheet _sh; TreeMap _rows=new TreeMap(); SheetDataWriter _writer; - int _randomAccessWindowSize=5000; + int _randomAccessWindowSize = SXSSFWorkbook.DEFAULT_WINDOW_SIZE; public SXSSFSheet(SXSSFWorkbook workbook,XSSFSheet xSheet) throws IOException { @@ -1243,7 +1238,7 @@ public class SXSSFSheet implements Sheet, Cloneable { _fd = File.createTempFile("sheet", ".xml"); _fd.deleteOnExit(); - _out = new FileWriter(_fd); + _out = new BufferedWriter(new FileWriter(_fd)); _out.write("\n"); } public int getNumberOfFlushedRows() @@ -1262,9 +1257,10 @@ public class SXSSFSheet implements Sheet, Cloneable { _fd.delete(); } - public InputStream getWorksheetXMLInputStream() throws IOException + public InputStream getWorksheetXMLInputStream() throws IOException { _out.write(""); + _out.flush(); _out.close(); return new FileInputStream(_fd); } @@ -1275,7 +1271,7 @@ public class SXSSFSheet implements Sheet, Cloneable * @param rownum 0-based row number * @param row a row */ - public void writeRow(int rownum,SXSSFRow row) throws IOException + public void writeRow(int rownum,SXSSFRow row) throws IOException { if(_numberOfFlushedRows==0) _lowestIndexOfFlushedRows=rownum; diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java index aa17b536a0..365e58b337 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java @@ -50,11 +50,56 @@ import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; */ public class SXSSFWorkbook implements Workbook { + /** + * Specifies how many rows can be accessed at most via getRow(). + * When a new node is created via createRow() and the total number + * of unflushed records would exeed the specified value, then the + * row with the lowest index value is flushed and cannot be accessed + * via getRow() anymore. + */ + public static final int DEFAULT_WINDOW_SIZE = 100; + XSSFWorkbook _wb=new XSSFWorkbook(); HashMap _sxFromXHash=new HashMap(); HashMap _xFromSxHash=new HashMap(); + int _randomAccessWindowSize = DEFAULT_WINDOW_SIZE; + + /** + * Construct a new workbook + */ + public SXSSFWorkbook(){ + + } + + /** + * Construct an empty workbook and specify the window for row access. + *

    + * When a new node is created via createRow() and the total number + * of unflushed records would exeed the specified value, then the + * row with the lowest index value is flushed and cannot be accessed + * via getRow() anymore. + *

    + *

    + * A value of -1 indicates unlimited access. In this case all + * records that have not been flushed by a call to flush() are available + * for random access. + *

    + *

    + * A value of 0 is not allowed because it would flush any newly created row + * without having a chance to specify any cells. + *

    + * + * @param rowAccessWindowSize + */ + public SXSSFWorkbook(int rowAccessWindowSize){ + if(rowAccessWindowSize == 0 || rowAccessWindowSize < -1) { + throw new IllegalArgumentException("rowAccessWindowSize must be greater than 0 or -1"); + } + _randomAccessWindowSize = rowAccessWindowSize; + } + XSSFSheet getXSSFSheet(SXSSFSheet sheet) { XSSFSheet result=_sxFromXHash.get(sheet); @@ -303,6 +348,7 @@ public class SXSSFWorkbook implements Workbook { throw new RuntimeException(ioe); } + sxSheet.setRandomAccessWindowSize(_randomAccessWindowSize); registerSheetMapping(sxSheet,xSheet); return sxSheet; } -- 2.39.5