Index: src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java =================================================================== --- src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java (revision 1430930) +++ src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java (working copy) @@ -99,18 +99,6 @@ * * All three use cases can work in a combination. *

- * What is not supported: - * * * @param workbook the template workbook */ Index: src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java =================================================================== --- src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java (revision 1430930) +++ src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java (working copy) @@ -155,6 +155,13 @@ */ public void removeRow(Row row) { + // If the row belongs to the template, delete it from the template. + if (row.getSheet() == _sh) { + _sh.removeRow(row); + return; + } + + // Otherwise try to delete it from the row cache. if (row.getSheet() != this) { throw new IllegalArgumentException("Specified row does not belong to this sheet"); } @@ -179,7 +186,11 @@ */ public Row getRow(int rownum) { - return _rows.get(new Integer(rownum)); + Row row = _sh.getRow(rownum); + if (row == null) { + row = _rows.get(new Integer(rownum)); + } + return row; } /** @@ -189,7 +200,7 @@ */ public int getPhysicalNumberOfRows() { - return _rows.size()+_writer.getNumberOfFlushedRows(); + return _sh.getPhysicalNumberOfRows() + _rows.size()+_writer.getNumberOfFlushedRows(); } /** @@ -199,9 +210,14 @@ */ public int getFirstRowNum() { + int templateFirst = _sh.getPhysicalNumberOfRows() > 0 ? _sh.getFirstRowNum() : Integer.MAX_VALUE; + int newRowsFirst = Integer.MAX_VALUE; if(_writer.getNumberOfFlushedRows() > 0) - return _writer.getLowestIndexOfFlushedRows(); - return _rows.size() == 0 ? 0 : _rows.firstKey(); + newRowsFirst = _writer.getLowestIndexOfFlushedRows(); + else + newRowsFirst = _rows.size() == 0 ? Integer.MAX_VALUE : _rows.firstKey(); + int first = templateFirst < newRowsFirst ? templateFirst : newRowsFirst; + return first == Integer.MAX_VALUE ? 0 : first; } /** @@ -211,7 +227,9 @@ */ public int getLastRowNum() { - return _rows.size() == 0 ? 0 : _rows.lastKey(); + int newRowsLast = _rows.size() == 0 ? 0 : _rows.lastKey(); + int templateLast = _sh.getPhysicalNumberOfRows() > 0 ? _sh.getLastRowNum() : 0; + return newRowsLast > templateLast ? newRowsLast : templateLast; } /** @@ -424,7 +442,9 @@ } /** - * Returns an iterator of the physical rows + * Returns an iterator of the physical rows. This will ONLY iterate over those + * cached rows that have not yet been flushed to a temporary file and not over + * rows in the template sheet. * * @return an iterator of the PHYSICAL rows. Meaning the 3rd element may not * be the third row if say for instance the second row is undefined. @@ -1096,6 +1116,13 @@ */ public void groupRow(int fromRow, int toRow) { + // Increase the outline level of any template rows first. + for (int i = fromRow; i <= toRow; i++){ + if (_sh.getRow(i) != null){ + _sh.groupRow(i, i); + } + } + for(SXSSFRow row : _rows.subMap(fromRow, toRow + 1).values()){ int level = row.getOutlineLevel() + 1; row.setOutlineLevel(level);