Index: .project =================================================================== --- .project (revision 1813841) +++ .project (working copy) @@ -1,6 +1,6 @@ - ApachePOI + ApachePOI-bug61699 Index: src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java =================================================================== --- src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java (revision 1813841) +++ src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java (working copy) @@ -37,6 +37,7 @@ import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; +import java.util.function.Predicate; import java.util.regex.Pattern; import javax.xml.namespace.QName; @@ -95,24 +96,7 @@ import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookView; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookViews; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalReference; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCache; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotCaches; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheets; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookProtection; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.STSheetState; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; /** * High level representation of a SpreadsheetML workbook. This is the first object most users @@ -1852,19 +1836,92 @@ } return embedds; } + + /** + * Add a window (view) to the workbook + * + * @return the index of the added workbook view + * @since POI 4.0.0 + */ + public int addWorkbookView() { + final CTBookViews bookviews = workbook.getBookViews(); + final CTBookView bookview = bookviews.addNewWorkbookView(); + // Assume that workbook view array doesn't contain any gaps and + // new workbook views are added onto the end + // if this is not the case, we'll need to for-loop over the views + // to find the index of the newly added workbook view + // We want to avoid expensive O(n) operations + //return views.getWorkbookViewList().indexOf(view); + final int windowViewIndex = bookviews.getWorkbookViewArray().length - 1; + + // Excel defines sheet views on every sheet (seems redundant) + for (final XSSFSheet sheet : sheets) { + final CTSheetView sheetview = sheet.getCTWorksheet().getSheetViews().addNewSheetView(); + //sheetview.setTabSelected(tabSelected); + sheetview.setWorkbookViewId(windowViewIndex); + } + return windowViewIndex; + } + /** + * Remove a window (view) from the workbook + * + * @param windowViewIndex the index of the workbook view to delete + * @since POI 4.0.0 + */ + public void removeWorkbookView(int windowViewIndex) { + final CTBookViews views = workbook.getBookViews(); + if (0 > windowViewIndex || windowViewIndex >= views.getWorkbookViewArray().length) { + throw new IllegalArgumentException("Cannot remove window " + windowViewIndex + " from workbook."); + } + views.removeWorkbookView(windowViewIndex); + + // Remove sheet views that referred to the deleted workbook view + final Predicate refersToBookView = p -> p.getWorkbookViewId() == windowViewIndex; + for (final XSSFSheet sheet : sheets) { + final CTSheetViews sheetviews = sheet.getCTWorksheet().getSheetViews(); + sheetviews.getSheetViewList().removeIf(refersToBookView); + } + } + @Override - @NotImplemented public boolean isHidden() { - throw new RuntimeException("Not implemented yet"); + return isHidden(0); } @Override - @NotImplemented public void setHidden(boolean hiddenFlag) { - throw new RuntimeException("Not implemented yet"); + setHidden(0, hiddenFlag); } + + /** + * @return true if this workbook view is not visible in the GUI + * @see #isHidden() + * @since POI 4.0.0 + */ + public boolean isHidden(int windowViewIndex) { + final CTBookView firstWorkbookView = workbook.getBookViews().getWorkbookViewArray(windowViewIndex); + // default (unset) visibility: visible + // workbook view is hidden or very hidden + boolean hidden = firstWorkbookView.isSetVisibility() && firstWorkbookView.getVisibility() != STVisibility.VISIBLE; + return hidden; + } + /** + * @param hiddenFlag pass true to hide the workbook in the GUI + * @see #setHidden(boolean) + * @since POI 4.0.0 + */ + public void setHidden(int windowViewIndex, boolean hiddenFlag) { + final CTBookView firstWorkbookView = workbook.getBookViews().getWorkbookViewArray(windowViewIndex); + // default (unset) visibility: visible + if (hiddenFlag) { + firstWorkbookView.setVisibility(STVisibility.HIDDEN); + } else { + firstWorkbookView.unsetVisibility(); + } + } + @Override public boolean isSheetHidden(int sheetIx) { validateSheetIndex(sheetIx); Index: src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java =================================================================== --- src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java (revision 1813841) +++ src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java (working copy) @@ -34,6 +34,8 @@ import java.util.Iterator; import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.hssf.record.WindowOneRecord; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType; import org.apache.poi.ss.util.CellRangeAddress; @@ -953,5 +955,30 @@ } wb.close(); } + + /** + * Tests for {@link Workbook#isHidden()} etc + * @throws IOException + */ + @Test + public void hidden() throws IOException { + Workbook wb = _testDataProvider.createWorkbook(); + assertEquals(false, wb.isHidden()); + + wb.setHidden(true); + assertEquals(true, wb.isHidden()); + + Workbook wbBack = _testDataProvider.writeOutAndReadBack(wb); + + wbBack.setHidden(true); + assertEquals(true, wbBack.isHidden()); + + wbBack.setHidden(false); + assertEquals(false, wbBack.isHidden()); + + wbBack.close(); + wb.close(); + } + }