<changes>
<release version="3.5-beta7" date="2009-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">47813 - fixed problems with XSSFWorkbook.removeSheetAt when workbook contains chart</action>
+ <action dev="POI-DEVELOPERS" type="fix">47737 - adjust sheet indices of named ranges when deleting sheets</action>
<action dev="POI-DEVELOPERS" type="fix">47770 - built-in positive formats don't need starting '('</action>
<action dev="POI-DEVELOPERS" type="add">47771 - Added method setFunction(boolean) for defined names</action>
<action dev="POI-DEVELOPERS" type="add">47768 - Implementation of Excel "Days360" and "Npv" functions</action>
--- /dev/null
+/* ====================================================================
+ 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.usermodel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
+
+/**
+ * High level representation of of Sheet Parts that are of type 'chartsheet'.
+ *
+ * TODO: current verion extends XSSFSheet although both should extend AbstractSheet
+ *
+ * @author Yegor Kozlov
+ */
+public class XSSFChartSheet extends XSSFSheet {
+
+ protected CTChartsheet chartsheet;
+
+ protected XSSFChartSheet(PackagePart part, PackageRelationship rel) {
+ super(part, rel);
+ }
+
+ protected void read(InputStream is) throws IOException {
+ try {
+ chartsheet = ChartsheetDocument.Factory.parse(is).getChartsheet();
+ } catch (XmlException e){
+ throw new POIXMLException(e);
+ }
+ }
+
+ /**
+ * Provide access to the CTWorksheet bean holding this sheet's data
+ *
+ * @return the CTWorksheet bean holding this sheet's data
+ */
+ public CTChartsheet getCTChartsheet() {
+ return chartsheet;
+ }
+
+ @Override
+ protected void commit() throws IOException {
+
+ }
+
+}
\ No newline at end of file
"/xl/worksheets/sheet#.xml",
XSSFSheet.class
);
+ public static final XSSFRelation CHARTSHEET = new XSSFRelation(
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet",
+ "/xl/chartsheets/sheet#.xml",
+ XSSFChartSheet.class
+ );
public static final XSSFRelation SHARED_STRINGS = new XSSFRelation(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
public void removeSheetAt(int index) {
validateSheetIndex(index);
+ onSheetDelete(index);
+
XSSFSheet sheet = getSheetAt(index);
removeRelation(sheet);
- this.sheets.remove(index);
- this.workbook.getSheets().removeSheet(index);
+ sheets.remove(index);
+ }
+
+ /**
+ * Gracefully remove references to the sheet being deleted
+ *
+ * @param index the 0-based index of the sheet to delete
+ */
+ private void onSheetDelete(int index) {
+ //delete the CTSheet reference from workbook.xml
+ workbook.getSheets().removeSheet(index);
+
+ //calculation chain is auxilary, remove it as it may contain orfan references to deleted cells
+ if(calcChain != null) {
+ removeRelation(calcChain);
+ calcChain = null;
+ }
+
+ //adjust indices of names ranges
+ for (Iterator<XSSFName> it = namedRanges.iterator(); it.hasNext();) {
+ XSSFName nm = it.next();
+ CTDefinedName ct = nm.getCTName();
+ if(!ct.isSetLocalSheetId()) continue;
+ if (ct.getLocalSheetId() == index) {
+ it.remove();
+ } else if (ct.getLocalSheetId() > index){
+ // Bump down by one, so still points at the same sheet
+ ct.setLocalSheetId(ct.getLocalSheetId()-1);
+ }
+ }
}
/**
assertEquals(crc0.getValue(), crc1.getValue());
}
+
+ /**
+ * When deleting a sheet make sure that we adjust sheet indices of named ranges
+ */
+ public void testBug47737() {
+ XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47737.xlsx");
+ assertEquals(2, wb.getNumberOfNames());
+ assertNotNull(wb.getCalculationChain());
+
+ XSSFName nm0 = wb.getNameAt(0);
+ assertTrue(nm0.getCTName().isSetLocalSheetId());
+ assertEquals(0, nm0.getCTName().getLocalSheetId());
+
+ XSSFName nm1 = wb.getNameAt(1);
+ assertTrue(nm1.getCTName().isSetLocalSheetId());
+ assertEquals(1, nm1.getCTName().getLocalSheetId());
+
+ wb.removeSheetAt(0);
+ assertEquals(1, wb.getNumberOfNames());
+ XSSFName nm2 = wb.getNameAt(0);
+ assertTrue(nm2.getCTName().isSetLocalSheetId());
+ assertEquals(0, nm2.getCTName().getLocalSheetId());
+ //calculation chain is removed as well
+ assertNull(wb.getCalculationChain());
+
+ }
+
+ /**
+ * Problems with XSSFWorkbook.removeSheetAt when workbook contains chart
+ */
+ public void testBug47813() {
+ XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47813.xlsx");
+ assertEquals(3, wb.getNumberOfSheets());
+ assertNotNull(wb.getCalculationChain());
+
+ assertEquals("Numbers", wb.getSheetName(0));
+ //the second sheet is of type 'chartsheet'
+ assertEquals("Chart", wb.getSheetName(1));
+ assertTrue(wb.getSheetAt(1) instanceof XSSFChartSheet);
+ assertEquals("SomeJunk", wb.getSheetName(2));
+
+ wb.removeSheetAt(2);
+ assertEquals(2, wb.getNumberOfSheets());
+ assertNull(wb.getCalculationChain());
+
+ wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
+ assertEquals(2, wb.getNumberOfSheets());
+ assertNull(wb.getCalculationChain());
+
+ assertEquals("Numbers", wb.getSheetName(0));
+ assertEquals("Chart", wb.getSheetName(1));
+ }
}