Index: src/ooxml/testcases/org/apache/poi/xssf/streaming/TestOutlining.java =================================================================== --- src/ooxml/testcases/org/apache/poi/xssf/streaming/TestOutlining.java (revision 0) +++ src/ooxml/testcases/org/apache/poi/xssf/streaming/TestOutlining.java (revision 0) @@ -0,0 +1,56 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.apache.poi.xssf.streaming; + +import junit.framework.TestCase; + +public final class TestOutlining extends TestCase { + public TestOutlining() { + } + + public void testSetRowGroupCollapsed() throws Exception { + + SXSSFWorkbook wb2 = new SXSSFWorkbook(100); + wb2.setCompressTempFiles(true); + SXSSFSheet sheet2 = (SXSSFSheet) wb2.createSheet("new sheet"); + + int rowCount = 20; + for (int i = 0; i < rowCount; i++) { + sheet2.createRow(i); + } + + sheet2.groupRow(4, 9); + sheet2.groupRow(11, 19); + + sheet2.setRowGroupCollapsed(4, true); + + SXSSFRow r = (SXSSFRow) sheet2.getRow(8); + assertTrue(r.getHidden()); + r = (SXSSFRow) sheet2.getRow(10); + assertTrue(r.getCollapsed()); + r = (SXSSFRow) sheet2.getRow(12); + if (r.getHidden() == null) + assertNull(r.getHidden()); + else + assertFalse(r.getHidden()); + wb2.dispose(); + } + +} 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. * Index: src/examples/src/org/apache/poi/xssf/streaming/examples/Outlining.java =================================================================== --- src/examples/src/org/apache/poi/xssf/streaming/examples/Outlining.java (revision 0) +++ src/examples/src/org/apache/poi/xssf/streaming/examples/Outlining.java (revision 0) @@ -0,0 +1,51 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.xssf.streaming.examples; + +import java.io.FileOutputStream; + +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; + +public class Outlining { + + public static void main(String[] args) throws Exception { + Outlining o = new Outlining(); + o.collapseRow(); + } + + private void collapseRow() throws Exception { + SXSSFWorkbook wb2 = new SXSSFWorkbook(100); + SXSSFSheet sheet2 = (SXSSFSheet) wb2.createSheet("new sheet"); + + int rowCount = 20; + for (int i = 0; i < rowCount; i++) { + sheet2.createRow(i); + } + + sheet2.groupRow(4, 9); + sheet2.groupRow(11, 19); + + sheet2.setRowGroupCollapsed(4, true); + + FileOutputStream fileOut = new FileOutputStream("outlining_collapsed.xlsx"); + wb2.write(fileOut); + fileOut.close(); + wb2.dispose(); + } +}