git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@814176 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_5-FINAL
<changes> | <changes> | ||||
<release version="3.5-beta7" date="2009-??-??"> | <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="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">47771 - Added method setFunction(boolean) for defined names</action> | ||||
<action dev="POI-DEVELOPERS" type="add">47768 - Implementation of Excel "Days360" and "Npv" functions</action> | <action dev="POI-DEVELOPERS" type="add">47768 - Implementation of Excel "Days360" and "Npv" functions</action> |
/* ==================================================================== | |||||
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 { | |||||
} | |||||
} |
"/xl/worksheets/sheet#.xml", | "/xl/worksheets/sheet#.xml", | ||||
XSSFSheet.class | 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( | public static final XSSFRelation SHARED_STRINGS = new XSSFRelation( | ||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml", | "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml", | ||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", | "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", |
public void removeSheetAt(int index) { | public void removeSheetAt(int index) { | ||||
validateSheetIndex(index); | validateSheetIndex(index); | ||||
onSheetDelete(index); | |||||
XSSFSheet sheet = getSheetAt(index); | XSSFSheet sheet = getSheetAt(index); | ||||
removeRelation(sheet); | 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()); | 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)); | |||||
} | |||||
} | } |