Browse Source

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
tags/REL_3_5-FINAL
Yegor Kozlov 14 years ago
parent
commit
00b59a229a

+ 2
- 0
src/documentation/content/xdocs/status.xml 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>

+ 65
- 0
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java 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 {

}

}

+ 6
- 0
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java 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",

+ 32
- 2
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java 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);
}
}
}

/**

+ 52
- 0
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java 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 View File


BIN
test-data/spreadsheet/47813.xlsx View File


Loading…
Cancel
Save