improved XSSFWorkbook.removeSheetAt, see Bugzilla 47737 and 47813

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@814176 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2009-09-12 16:01:18 +00:00
parent 4dc5210eb6
commit 00b59a229a
7 changed files with 157 additions and 2 deletions

View File

@ -33,6 +33,8 @@
<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>

View File

@ -0,0 +1,65 @@
/* ====================================================================
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 {
}
}

View File

@ -90,6 +90,12 @@ public final class XSSFRelation extends POIXMLRelation {
"/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",

View File

@ -781,10 +781,40 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
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);
}
}
}
/**

View File

@ -304,4 +304,56 @@ public final class TestXSSFWorkbook extends BaseTestWorkbook {
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));
}
}

BIN
test-data/spreadsheet/47737.xlsx Executable file

Binary file not shown.

BIN
test-data/spreadsheet/47813.xlsx Executable file

Binary file not shown.