Index: src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java =================================================================== --- src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java (revision 1510967) +++ src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java (working copy) @@ -40,7 +40,9 @@ short _height=-1; boolean _zHeight = false; int _outlineLevel = 0; // Outlining level of the row, when outlining is on - + Boolean _hidden; + Boolean _collapsed; + public SXSSFRow(SXSSFSheet sheet, int initialSize) { _sheet=sheet; @@ -61,7 +63,22 @@ void setOutlineLevel(int level){ _outlineLevel = level; } + + public Boolean getHidden() { + return _hidden; + } + + public void setHidden(Boolean hidden) { + this._hidden = hidden; + } + public Boolean getCollapsed() { + return _collapsed; + } + + public void setCollapsed(Boolean collapsed) { + this._collapsed = collapsed; + } //begin of interface implementation public Iterator iterator() { Index: src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java =================================================================== --- src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java (revision 1510481) +++ src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java (working copy) @@ -142,6 +142,13 @@ if (row.getOutlineLevel() != 0) { _out.write(" outlineLevel=\"" + row.getOutlineLevel() + "\""); } + if(row.getHidden() != null) { + _out.write(" hidden=\"" + (row.getHidden() ? "1" : "0") + "\""); + } + if(row.getCollapsed() != null) { + _out.write(" collapsed=\"" + (row.getCollapsed() ? "1" : "0") + "\""); + } + _out.write(">\n"); this._rownum = rownum; _rowContainedNullCells = false; Index: src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java =================================================================== --- src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java (revision 1510481) +++ src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java (working copy) @@ -1115,10 +1115,61 @@ */ public void setRowGroupCollapsed(int row, boolean collapse) { - //_sh.setRowGroupCollapsed(row, collapse); - throw new RuntimeException("Not Implemented"); + if (collapse) { + collapseRow(row); + } else { + //expandRow(rowIndex); + throw new RuntimeException("Not Implemented"); + } } + + /** + * @param rowIndex the zero based row index to collapse + */ + private void collapseRow(int rowIndex) { + SXSSFRow row = (SXSSFRow) getRow(rowIndex); + if (row != null) { + int startRow = findStartOfRowOutlineGroup(rowIndex); + // Hide all the columns until the end of the group + int lastRow = writeHidden(row, startRow, true); + SXSSFRow lastRowObj = (SXSSFRow) getRow(lastRow); + if (lastRowObj != null) { + lastRowObj.setCollapsed(true); + } else { + SXSSFRow newRow = (SXSSFRow) createRow(lastRow); + newRow.setCollapsed(true); + } + } + } + + /** + * @param rowIndex the zero based row index to find from + */ + private int findStartOfRowOutlineGroup(int rowIndex) { + // Find the start of the group. + int level = ((SXSSFRow) getRow(rowIndex)).getOutlineLevel(); + int currentRow = rowIndex; + while (getRow(currentRow) != null) { + if (((SXSSFRow) getRow(currentRow)).getOutlineLevel() < level) + return currentRow + 1; + currentRow--; + } + return currentRow; + } + + private int writeHidden(SXSSFRow xRow, int rowIndex, boolean hidden) { + int level = xRow.getOutlineLevel(); + SXSSFRow currRow = (SXSSFRow) getRow(rowIndex); + + while (currRow != null && currRow.getOutlineLevel() >= level) { + currRow.setHidden(hidden); + rowIndex++; + currRow = (SXSSFRow) getRow(rowIndex); + } + return rowIndex; + } + /** * Sets the default column style for a given column. POI will only apply this style to new cells added to the sheet. *