diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index f07ad2f35..9bb4ec1c7 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -66,6 +66,8 @@ Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx + Expose the name of Named Cell Styles via HSSFCellStyle (normally held on the parent style though) + 45978 - Fixed IOOBE in Ref3DPtg.toFormulaString() due eager initialisation of SheetReferences Made HSSFFormulaEvaluator no longer require initialisation with sheet or row Extended support for cached results of formula cells 45639 - Fixed AIOOBE due to bad index logic in ColumnInfoRecordsAggregate diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 0adf13d18..9c6d8d266 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -63,6 +63,8 @@ Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx + Expose the name of Named Cell Styles via HSSFCellStyle (normally held on the parent style though) + 45978 - Fixed IOOBE in Ref3DPtg.toFormulaString() due eager initialisation of SheetReferences Made HSSFFormulaEvaluator no longer require initialisation with sheet or row Extended support for cached results of formula cells 45639 - Fixed AIOOBE due to bad index logic in ColumnInfoRecordsAggregate diff --git a/src/java/org/apache/poi/hssf/model/LinkTable.java b/src/java/org/apache/poi/hssf/model/LinkTable.java index a64f134fe..2caab0fb5 100755 --- a/src/java/org/apache/poi/hssf/model/LinkTable.java +++ b/src/java/org/apache/poi/hssf/model/LinkTable.java @@ -348,10 +348,6 @@ final class LinkTable { return -1; } - public int getNumberOfREFStructures() { - return _externSheetRecord.getNumOfRefs(); - } - public String resolveNameXText(int refIndex, int definedNameIndex) { int extBookIndex = _externSheetRecord.getExtbookIndexFromRefIndex(refIndex); return _externalBookBlocks[extBookIndex].getNameText(definedNameIndex); diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java index 7976588d3..1e37a80ca 100644 --- a/src/java/org/apache/poi/hssf/model/Workbook.java +++ b/src/java/org/apache/poi/hssf/model/Workbook.java @@ -26,7 +26,6 @@ import org.apache.poi.ddf.*; import org.apache.poi.hssf.record.*; import org.apache.poi.hssf.record.formula.NameXPtg; import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.hssf.util.SheetReferences; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -774,6 +773,61 @@ public final class Workbook implements Model { numxfs++; return xf; } + + /** + * Returns the StyleRecord for the given + * xfIndex, or null if that ExtendedFormat doesn't + * have a Style set. + */ + public StyleRecord getStyleRecord(int xfIndex) { + // Style records always follow after + // the ExtendedFormat records + boolean done = false; + for(int i=records.getXfpos(); i= boundsheets.size()) { + // Not sure if this can ever happen (See bug 45798) + return ""; // Seems to be what excel would do in this case + } return getSheetName(indexToSheet); } diff --git a/src/java/org/apache/poi/hssf/record/StyleRecord.java b/src/java/org/apache/poi/hssf/record/StyleRecord.java index 6990a5efd..c6591f550 100644 --- a/src/java/org/apache/poi/hssf/record/StyleRecord.java +++ b/src/java/org/apache/poi/hssf/record/StyleRecord.java @@ -160,7 +160,10 @@ public final class StyleRecord extends Record { public void setName(String name) { field_4_name = name; - //TODO set name length and string options + + // Fix up the length + field_2_name_length = (short)name.length(); + //TODO set name string options } // end user defined diff --git a/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java index 8848cb603..2183cc2dd 100644 --- a/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java @@ -92,7 +92,7 @@ public final class Area3DPtg extends AreaPtgBase { public String toFormulaString(Workbook book) { // First do the sheet name StringBuffer retval = new StringBuffer(); - String sheetName = Ref3DPtg.getSheetName(book, field_1_index_extern_sheet); + String sheetName = book.findSheetNameFromExternSheet(field_1_index_extern_sheet); if(sheetName != null) { if(sheetName.length() == 0) { // What excel does if sheet has been deleted diff --git a/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java index dbb00c323..e72cbbc30 100644 --- a/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java @@ -160,20 +160,6 @@ public final class Ref3DPtg extends OperandPtg { } - // TODO - find a home for this method - // There is already a method on Workbook called getSheetName but it seems to do something different. - static String getSheetName(Workbook book, int externSheetIndex) { - // TODO - there are 3 ways this method can return null. Is each valid? - if (book == null) { - return null; - } - - SheetReferences refs = book.getSheetReferences(); - if (refs == null) { - return null; - } - return refs.getSheetName(externSheetIndex); - } /** * @return text representation of this cell reference that can be used in text * formulas. The sheet name will get properly delimited if required. @@ -181,7 +167,7 @@ public final class Ref3DPtg extends OperandPtg { public String toFormulaString(Workbook book) { StringBuffer retval = new StringBuffer(); - String sheetName = getSheetName(book, field_1_index_extern_sheet); + String sheetName = book.findSheetNameFromExternSheet(field_1_index_extern_sheet); if(sheetName != null) { SheetNameFormatter.appendFormat(retval, sheetName); retval.append( '!' ); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java index 9a3735c4d..76be1f9e5 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java @@ -21,6 +21,7 @@ package org.apache.poi.hssf.usermodel; import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.ExtendedFormatRecord; import org.apache.poi.hssf.record.FontRecord; +import org.apache.poi.hssf.record.StyleRecord; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; @@ -255,6 +256,22 @@ public class HSSFCellStyle implements CellStyle { return index; } + + /** + * Return the parent style for this cell style. + * In most cases this will be null, but in a few + * cases there'll be a fully defined parent. + */ + public HSSFCellStyle getParentStyle() { + if(format.getParentIndex() == 0) { + return null; + } + return new HSSFCellStyle( + format.getParentIndex(), + workbook.getExFormatAt(format.getParentIndex()), + workbook + ); + } /** * set the data format (must be a valid format) @@ -943,6 +960,37 @@ public class HSSFCellStyle implements CellStyle { return format.getFillForeground(); } + + /** + * Gets the name of the user defined style. + * Returns null for built in styles, and + * styles where no name has been defined + */ + public String getUserStyleName() { + StyleRecord sr = workbook.getStyleRecord(index); + if(sr == null) { + return null; + } + if(sr.getType() == StyleRecord.STYLE_BUILT_IN) { + return null; + } + return sr.getName(); + } + + /** + * Sets the name of the user defined style. + * Will complain if you try this on a built in style. + */ + public void setUserStyleName(String styleName) { + StyleRecord sr = workbook.getStyleRecord(index); + if(sr == null) { + sr = workbook.createStyleRecord(index); + } + if(sr.getType() == StyleRecord.STYLE_BUILT_IN) { + throw new IllegalArgumentException("Unable to set user specified style names for built in styles!"); + } + sr.setName(styleName); + } /** * Verifies that this style belongs to the supplied Workbook. diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 1d24ad392..dd808a341 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -35,7 +35,6 @@ import org.apache.poi.ddf.EscherBlipRecord; import org.apache.poi.ddf.EscherRecord; import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Workbook; -import org.apache.poi.hssf.model.DrawingManager2; import org.apache.poi.hssf.record.AbstractEscherHolderRecord; import org.apache.poi.hssf.record.BackupRecord; import org.apache.poi.hssf.record.DrawingGroupRecord; @@ -59,7 +58,6 @@ import org.apache.poi.hssf.record.formula.Ptg; import org.apache.poi.hssf.record.formula.Ref3DPtg; import org.apache.poi.hssf.record.formula.UnionPtg; import org.apache.poi.hssf.util.CellReference; -import org.apache.poi.hssf.util.SheetReferences; import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.CreationHelper; @@ -864,8 +862,13 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm return retval; } - public SheetReferences getSheetReferences() { - return workbook.getSheetReferences(); + /** + * @deprecated for POI internal use only (formula rendering). This method is likely to + * be removed in future versions of POI. + */ + public String findSheetNameFromExternSheet(int externSheetIndex){ + // TODO - don't expose internal ugliness like externSheet indexes to the user model API + return workbook.findSheetNameFromExternSheet(externSheetIndex); } /** @@ -1379,12 +1382,15 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm } /** - * TODO - make this less cryptic / move elsewhere + * @deprecated for POI internal use only (formula rendering). This method is likely to + * be removed in future versions of POI. + * * @param refIndex Index to REF entry in EXTERNSHEET record in the Link Table * @param definedNameIndex zero-based to DEFINEDNAME or EXTERNALNAME record * @return the string representation of the defined or external name */ public String resolveNameXText(int refIndex, int definedNameIndex) { + // TODO - make this less cryptic / move elsewhere return workbook.resolveNameXText(refIndex, definedNameIndex); } diff --git a/src/java/org/apache/poi/hssf/util/SheetReferences.java b/src/java/org/apache/poi/hssf/util/SheetReferences.java deleted file mode 100644 index d23ed27c6..000000000 --- a/src/java/org/apache/poi/hssf/util/SheetReferences.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - 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.hssf.util; - -/** - * Holds a collection of Sheet names and their associated - * reference numbers. - * - * @author Andrew C. Oliver (acoliver at apache dot org) - * - */ -public class SheetReferences extends org.apache.poi.ss.util.SheetReferences -{ -} diff --git a/src/ooxml/interfaces-jdk14/org/apache/poi/ss/usermodel/Workbook.java b/src/ooxml/interfaces-jdk14/org/apache/poi/ss/usermodel/Workbook.java index a31d03e4c..eca702a37 100644 --- a/src/ooxml/interfaces-jdk14/org/apache/poi/ss/usermodel/Workbook.java +++ b/src/ooxml/interfaces-jdk14/org/apache/poi/ss/usermodel/Workbook.java @@ -19,7 +19,6 @@ package org.apache.poi.ss.usermodel; import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.hssf.util.SheetReferences; /** * This is a JDK 1.4 compatible interface for HSSFWorkbook. @@ -39,7 +38,7 @@ public interface Workbook { String getSheetName(int sheet); HSSFSheet getSheetAt(int index); - SheetReferences getSheetReferences(); + String findSheetNameFromExternSheet(int externSheetIndex); int getSheetIndex(String name); int getSheetIndex(Sheet sheet); int getSheetIndexFromExternSheetIndex(int externSheetNumber); diff --git a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Workbook.java b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Workbook.java index dbc7fdc97..caafc634d 100644 --- a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Workbook.java +++ b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Workbook.java @@ -22,7 +22,6 @@ import java.io.OutputStream; import java.util.List; import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; -import org.apache.poi.ss.util.SheetReferences; public interface Workbook { @@ -218,7 +217,7 @@ public interface Workbook { void removeSheetAt(int index); - SheetReferences getSheetReferences(); + String findSheetNameFromExternSheet(int externSheetIndex); /** * determine whether the Excel GUI will backup the workbook when saving. diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index b90058e54..28cee4227 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -39,7 +39,6 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.StylesSource; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; -import org.apache.poi.ss.util.SheetReferences; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import org.apache.poi.xssf.model.CommentsTable; @@ -463,6 +462,14 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { public int getSheetIndexFromExternSheetIndex(int externSheetNumber) { return externSheetNumber; } + /** + * Doesn't do anything special - returns the same as getSheetName() + * TODO - figure out if this is a ole2 specific thing, or + * if we need to do something proper here too! + */ + public String findSheetNameFromExternSheet(int externSheetIndex) { + return getSheetName(externSheetIndex); + } public Sheet getSheet(String name) { CTSheet[] sheets = this.workbook.getSheets().getSheetArray(); @@ -509,14 +516,6 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { return this.workbook.getSheets().getSheetArray(sheet).getName(); } - public SheetReferences getSheetReferences() { - SheetReferences sr = new SheetReferences(); - for(int i=0; i @@ -41,27 +38,20 @@ import org.apache.poi.hssf.util.TestSheetReferences; */ public final class HSSFTests { - public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); - } - public static Test suite() { - TestSuite suite = new TestSuite("Tests for org.apache.poi.hssf"); - // $JUnit-BEGIN$ + TestSuite suite = new TestSuite(HSSFTests.class.getName()); suite.addTest(AllEventUserModelTests.suite()); suite.addTest(AllModelTests.suite()); suite.addTest(AllUserModelTests.suite()); suite.addTest(AllRecordTests.suite()); + suite.addTest(AllHSSFUtilTests.suite()); - suite.addTest(new TestSuite(TestAreaReference.class)); - suite.addTest(new TestSuite(TestCellReference.class)); - suite.addTest(new TestSuite(TestRangeAddress.class)); - suite.addTest(new TestSuite(TestRKUtil.class)); - suite.addTest(new TestSuite(TestSheetReferences.class)); + if (false) { // TODO - hook this test up + suite.addTest(new TestSuite(TestExcelExtractor.class)); + } suite.addTest(new TestSuite(TestEventRecordFactory.class)); suite.addTest(new TestSuite(TestModelFactory.class)); - // $JUnit-END$ return suite; } } diff --git a/src/testcases/org/apache/poi/hssf/data/WithExtendedStyles.xls b/src/testcases/org/apache/poi/hssf/data/WithExtendedStyles.xls new file mode 100644 index 000000000..4a80f56f5 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/WithExtendedStyles.xls differ diff --git a/src/testcases/org/apache/poi/hssf/data/ex45978-extraLinkTableSheets.xls b/src/testcases/org/apache/poi/hssf/data/ex45978-extraLinkTableSheets.xls new file mode 100644 index 000000000..5e496142c Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/ex45978-extraLinkTableSheets.xls differ diff --git a/src/testcases/org/apache/poi/hssf/eventusermodel/TestEventWorkbookBuilder.java b/src/testcases/org/apache/poi/hssf/eventusermodel/TestEventWorkbookBuilder.java index c8beb7b78..e88d274ea 100644 --- a/src/testcases/org/apache/poi/hssf/eventusermodel/TestEventWorkbookBuilder.java +++ b/src/testcases/org/apache/poi/hssf/eventusermodel/TestEventWorkbookBuilder.java @@ -16,6 +16,7 @@ ==================================================================== */ package org.apache.poi.hssf.eventusermodel; + import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -32,7 +33,6 @@ import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.formula.Ptg; import org.apache.poi.hssf.record.formula.Ref3DPtg; import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.util.SheetReferences; import org.apache.poi.poifs.filesystem.POIFSFileSystem; /** * Tests for {@link EventWorkbookBuilder} @@ -66,9 +66,6 @@ public final class TestEventWorkbookBuilder extends TestCase { public void testGetStubWorkbooks() { assertNotNull(listener.getStubWorkbook()); assertNotNull(listener.getStubHSSFWorkbook()); - - assertNotNull(listener.getStubWorkbook().getSheetReferences()); - assertNotNull(listener.getStubHSSFWorkbook().getSheetReferences()); } public void testContents() { @@ -78,10 +75,10 @@ public final class TestEventWorkbookBuilder extends TestCase { assertEquals(3, listener.getStubWorkbook().getNumSheets()); - SheetReferences ref = listener.getStubWorkbook().getSheetReferences(); - assertEquals("Sh3", ref.getSheetName(0)); - assertEquals("Sheet1", ref.getSheetName(1)); - assertEquals("S2", ref.getSheetName(2)); + Workbook ref = listener.getStubWorkbook(); + assertEquals("Sh3", ref.findSheetNameFromExternSheet(0)); + assertEquals("Sheet1", ref.findSheetNameFromExternSheet(1)); + assertEquals("S2", ref.findSheetNameFromExternSheet(2)); } public void testFormulas() { diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java b/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java index 1dc826cc6..a4cf005a0 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java @@ -29,6 +29,8 @@ import java.io.*; import java.util.*; import junit.framework.*; + +import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.util.TempFile; /** @@ -41,6 +43,10 @@ public class TestCellStyle extends TestCase { + private static HSSFWorkbook openSample(String sampleFileName) { + return HSSFTestDataSamples.openSampleWorkbook(sampleFileName); + } + /** Creates a new instance of TestCellStyle */ public TestCellStyle(String name) @@ -303,6 +309,54 @@ public class TestCellStyle assertFalse(fmtClone.getFormat("Test##") == fmt.getFormat("Test##")); assertEquals(5, wbClone.getNumberOfFonts()); } + + public void testStyleNames() throws Exception { + HSSFWorkbook wb = openSample("WithExtendedStyles.xls"); + HSSFSheet s = wb.getSheetAt(0); + HSSFCell c1 = s.getRow(0).getCell(0); + HSSFCell c2 = s.getRow(1).getCell(0); + HSSFCell c3 = s.getRow(2).getCell(0); + + HSSFCellStyle cs1 = c1.getCellStyle(); + HSSFCellStyle cs2 = c2.getCellStyle(); + HSSFCellStyle cs3 = c3.getCellStyle(); + + assertNotNull(cs1); + assertNotNull(cs2); + assertNotNull(cs3); + + // Check we got the styles we'd expect + assertEquals(10, cs1.getFont(wb).getFontHeightInPoints()); + assertEquals(9, cs2.getFont(wb).getFontHeightInPoints()); + assertEquals(12, cs3.getFont(wb).getFontHeightInPoints()); + + assertEquals(15, cs1.getIndex()); + assertEquals(23, cs2.getIndex()); + assertEquals(24, cs3.getIndex()); + + assertNull(cs1.getParentStyle()); + assertNotNull(cs2.getParentStyle()); + assertNotNull(cs3.getParentStyle()); + + assertEquals(21, cs2.getParentStyle().getIndex()); + assertEquals(22, cs3.getParentStyle().getIndex()); + + // Now check we can get style records for + // the parent ones + assertNull(wb.getWorkbook().getStyleRecord(15)); + assertNull(wb.getWorkbook().getStyleRecord(23)); + assertNull(wb.getWorkbook().getStyleRecord(24)); + + assertNotNull(wb.getWorkbook().getStyleRecord(21)); + assertNotNull(wb.getWorkbook().getStyleRecord(22)); + + // Now check the style names + assertEquals(null, cs1.getUserStyleName()); + assertEquals(null, cs2.getUserStyleName()); + assertEquals(null, cs3.getUserStyleName()); + assertEquals("style1", cs2.getParentStyle().getUserStyleName()); + assertEquals("style2", cs3.getParentStyle().getUserStyleName()); + } public static void main(String [] ignored_args) { diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestLinkTable.java b/src/testcases/org/apache/poi/hssf/usermodel/TestLinkTable.java index d8b4e9521..e8542edd8 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestLinkTable.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestLinkTable.java @@ -6,7 +6,7 @@ import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; /** * Tests for LinkTable - * + * * @author Josh Micich */ public final class TestLinkTable extends TestCase { @@ -14,9 +14,9 @@ public final class TestLinkTable extends TestCase { /** * The example file attached to bugzilla 45046 is a clear example of Name records being present * without an External Book (SupBook) record. Excel has no trouble reading this file.
- * TODO get OOO documentation updated to reflect this (that EXTERNALBOOK is optional). - * - * It's not clear what exact steps need to be taken in Excel to create such a workbook + * TODO get OOO documentation updated to reflect this (that EXTERNALBOOK is optional). + * + * It's not clear what exact steps need to be taken in Excel to create such a workbook */ public void testLinkTableWithoutExternalBookRecord_bug45046() { HSSFWorkbook wb; @@ -32,16 +32,16 @@ public final class TestLinkTable extends TestCase { // some other sanity checks assertEquals(3, wb.getNumberOfSheets()); String formula = wb.getSheetAt(0).getRow(4).getCell(13).getCellFormula(); - + if ("ipcSummenproduktIntern($P5,N$6,$A$9,N$5)".equals(formula)) { - // The reported symptom of this bugzilla is an earlier bug (already fixed) - throw new AssertionFailedError("Identified bug 41726"); + // The reported symptom of this bugzilla is an earlier bug (already fixed) + throw new AssertionFailedError("Identified bug 41726"); // This is observable in version 3.0 } - + assertEquals("ipcSummenproduktIntern($C5,N$2,$A$9,N$1)", formula); } - + public void testMultipleExternSheetRecords_bug45698() { HSSFWorkbook wb; @@ -56,4 +56,45 @@ public final class TestLinkTable extends TestCase { // some other sanity checks assertEquals(7, wb.getNumberOfSheets()); } + + public void testExtraSheetRefs_bug45978() { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("ex45978-extraLinkTableSheets.xls"); + /* + ex45978-extraLinkTableSheets.xls is a cut-down version of attachment 22561. + The original file produces the same error. + + This bug was caused by a combination of invalid sheet indexes in the EXTERNSHEET + record, and eager initialisation of the extern sheet references. Note - the worbook + has 2 sheets, but the EXTERNSHEET record refers to sheet indexes 0, 1 and 2. + + Offset 0x3954 (14676) + recordid = 0x17, size = 32 + [EXTERNSHEET] + numOfRefs = 5 + refrec #0: extBook=0 firstSheet=0 lastSheet=0 + refrec #1: extBook=1 firstSheet=2 lastSheet=2 + refrec #2: extBook=2 firstSheet=1 lastSheet=1 + refrec #3: extBook=0 firstSheet=-1 lastSheet=-1 + refrec #4: extBook=0 firstSheet=1 lastSheet=1 + [/EXTERNSHEET] + + As it turns out, the formula in question doesn't even use externSheetIndex #1 - it + uses #4, which resolves to sheetIndex 1 -> 'Data'. + + It is not clear exactly what externSheetIndex #4 would refer to. Excel seems to + display such a formula as "''!$A2", but then complains of broken link errors. + */ + + HSSFCell cell = wb.getSheetAt(0).getRow(1).getCell(1); + String cellFormula; + try { + cellFormula = cell.getCellFormula(); + } catch (IndexOutOfBoundsException e) { + if (e.getMessage().equals("Index: 2, Size: 2")) { + throw new AssertionFailedError("Identified bug 45798"); + } + throw e; + } + assertEquals("Data!$A2", cellFormula); + } } diff --git a/src/testcases/org/apache/poi/hssf/util/AllHSSFUtilTests.java b/src/testcases/org/apache/poi/hssf/util/AllHSSFUtilTests.java index ec88e5c43..45c96e6c4 100755 --- a/src/testcases/org/apache/poi/hssf/util/AllHSSFUtilTests.java +++ b/src/testcases/org/apache/poi/hssf/util/AllHSSFUtilTests.java @@ -34,7 +34,6 @@ public class AllHSSFUtilTests { result.addTestSuite(TestHSSFColor.class); result.addTestSuite(TestRangeAddress.class); result.addTestSuite(TestRKUtil.class); - result.addTestSuite(TestSheetReferences.class); return result; } } diff --git a/src/testcases/org/apache/poi/hssf/util/TestSheetReferences.java b/src/testcases/org/apache/poi/hssf/util/TestSheetReferences.java deleted file mode 100644 index 4464d768c..000000000 --- a/src/testcases/org/apache/poi/hssf/util/TestSheetReferences.java +++ /dev/null @@ -1,51 +0,0 @@ - -/* ==================================================================== - 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.hssf.util; - -import junit.framework.TestCase; - -/** - * Tests the SheetReferences class. - * @author Andrew C. Oliver (acoliver at apache dot org) - */ -public class TestSheetReferences - extends TestCase -{ - public TestSheetReferences(String s) - { - super(s); - } - - /** - * Test that the SheetReferences class can add references and give them - * out - */ - public void testSheetRefs() - throws Exception - { - SheetReferences refs = new SheetReferences(); - refs.addSheetReference("A", 0); - refs.addSheetReference("B", 1); - refs.addSheetReference("C", 3); - assertTrue("ref 0 == A", refs.getSheetName(0).equals("A")); - assertTrue("ref 1 == B", refs.getSheetName(1).equals("B")); - assertTrue("ref 3 == C", refs.getSheetName(3).equals("C")); - } -}