git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@814176 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_5-FINAL
@@ -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> |
@@ -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 { | |||
} | |||
} |
@@ -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", |
@@ -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); | |||
} | |||
} | |||
} | |||
/** |
@@ -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)); | |||
} | |||
} |