diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
index 24b30180d..0e51637e9 100644
--- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
+++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
@@ -716,6 +716,9 @@ public final class InternalWorkbook {
// Bump down by one, so still points
// at the same sheet
nr.setSheetNumber(nr.getSheetNumber()-1);
+
+ // also update the link-table as otherwise references might point at invalid sheets
+ linkTable.updateIndexToInternalSheet(i, -1);
}
}
}
diff --git a/src/java/org/apache/poi/hssf/model/LinkTable.java b/src/java/org/apache/poi/hssf/model/LinkTable.java
index 1cec62de3..3304ae235 100644
--- a/src/java/org/apache/poi/hssf/model/LinkTable.java
+++ b/src/java/org/apache/poi/hssf/model/LinkTable.java
@@ -31,13 +31,17 @@ import org.apache.poi.hssf.record.NameCommentRecord;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SupBookRecord;
-import org.apache.poi.ss.formula.ptg.*;
+import org.apache.poi.ss.formula.ptg.Area3DPtg;
+import org.apache.poi.ss.formula.ptg.ErrPtg;
+import org.apache.poi.ss.formula.ptg.NameXPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.Ref3DPtg;
/**
* Link Table (OOO pdf reference: 4.10.3 )
*
* The main data of all types of references is stored in the Link Table inside the Workbook Globals
- * Substream (4.2.5). The Link Table itself is optional and occurs only, if there are any
+ * Substream (4.2.5). The Link Table itself is optional and occurs only if there are any
* references in the document.
*
*
@@ -63,9 +67,7 @@ import org.apache.poi.ss.formula.ptg.*;
*/
final class LinkTable {
-
// TODO make this class into a record aggregate
-
private static final class CRNBlock {
private final CRNCountRecord _countRecord;
@@ -174,7 +176,7 @@ final class LinkTable {
private final int _recordCount;
private final WorkbookRecordList _workbookRecordList; // TODO - would be nice to remove this
- public LinkTable(List inputList, int startIndex, WorkbookRecordList workbookRecordList, Map commentRecords) {
+ public LinkTable(List inputList, int startIndex, WorkbookRecordList workbookRecordList, Map commentRecords) {
_workbookRecordList = workbookRecordList;
RecordStream rs = new RecordStream(inputList, startIndex);
@@ -412,6 +414,10 @@ final class LinkTable {
public int getIndexToInternalSheet(int extRefIndex) {
return _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex);
}
+
+ public void updateIndexToInternalSheet(int extRefIndex, int offset) {
+ _externSheetRecord.adjustIndex(extRefIndex, offset);
+ }
public int getSheetIndexFromExternSheetIndex(int extRefIndex) {
if (extRefIndex >= _externSheetRecord.getNumOfRefs() || extRefIndex < 0) {
@@ -442,7 +448,6 @@ final class LinkTable {
return _externSheetRecord.addRef(thisWbIndex, sheetIndex, sheetIndex);
}
-
/**
* copied from Workbook
*/
@@ -533,8 +538,8 @@ final class LinkTable {
int supLinkIndex = 0;
// find the posistion of the Add-In SupBookRecord in the workbook stream,
// the created ExternalNameRecord will be appended to it
- for (Iterator iterator = _workbookRecordList.iterator(); iterator.hasNext(); supLinkIndex++) {
- Record record = (Record) iterator.next();
+ for (Iterator iterator = _workbookRecordList.iterator(); iterator.hasNext(); supLinkIndex++) {
+ Record record = iterator.next();
if (record instanceof SupBookRecord) {
if (((SupBookRecord) record).isAddInFunctions()) break;
}
diff --git a/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java b/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
index 963e325ab..4de0f60b0 100644
--- a/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
+++ b/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
@@ -41,6 +41,10 @@ public class ExternSheetRecord extends StandardRecord {
private int _firstSheetIndex; // may be -1 (0xFFFF)
private int _lastSheetIndex; // may be -1 (0xFFFF)
+ public void adjustIndex(int offset) {
+ _firstSheetIndex += offset;
+ _lastSheetIndex += offset;
+ }
/** a Constructor for making new sub record
*/
@@ -66,6 +70,7 @@ public class ExternSheetRecord extends StandardRecord {
return _lastSheetIndex;
}
+ @Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("extBook=").append(_extBookIndex);
@@ -122,6 +127,7 @@ public class ExternSheetRecord extends StandardRecord {
}
+ @Override
public String toString() {
StringBuffer sb = new StringBuffer();
int nItems = _list.size();
@@ -138,10 +144,12 @@ public class ExternSheetRecord extends StandardRecord {
return sb.toString();
}
+ @Override
protected int getDataSize() {
return 2 + _list.size() * RefSubRecord.ENCODED_SIZE;
}
+ @Override
public void serialize(LittleEndianOutput out) {
int nItems = _list.size();
@@ -156,9 +164,14 @@ public class ExternSheetRecord extends StandardRecord {
return _list.get(i);
}
+ public void adjustIndex(int extRefIndex, int offset) {
+ getRef(extRefIndex).adjustIndex(offset);
+ }
+
/**
* return the non static version of the id for this record.
*/
+ @Override
public short getSid() {
return sid;
}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java
index 1927727e4..88fa84ac2 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java
@@ -48,6 +48,7 @@ import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.formula.ptg.Area3DPtg;
import org.apache.poi.ss.usermodel.BaseTestWorkbook;
+import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.TempFile;
@@ -965,4 +966,53 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
HSSFWorkbook read = HSSFTestDataSamples.writeOutAndReadBack(wb);
assertSheetOrder(read, "Invoice", "Deferred", "Received", "Digest");
}
+
+ public void testBug54500() throws Exception {
+ String nameName = "AName";
+ String sheetName = "ASheet";
+ HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("54500.xls");
+
+ assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3");
+
+ wb.createSheet(sheetName);
+
+ assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3", "ASheet");
+
+ Name n = wb.createName();
+ n.setNameName(nameName);
+ n.setSheetIndex(3);
+ n.setRefersToFormula(sheetName + "!A1");
+
+ assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3", "ASheet");
+ assertEquals("ASheet!A1", wb.getName(nameName).getRefersToFormula());
+
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ wb.write(stream);
+
+ assertSheetOrder(wb, "Sheet1", "Sheet2", "Sheet3", "ASheet");
+ assertEquals("ASheet!A1", wb.getName(nameName).getRefersToFormula());
+
+ wb.removeSheetAt(1);
+
+ assertSheetOrder(wb, "Sheet1", "Sheet3", "ASheet");
+ assertEquals("ASheet!A1", wb.getName(nameName).getRefersToFormula());
+
+ ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
+ wb.write(stream2);
+
+ assertSheetOrder(wb, "Sheet1", "Sheet3", "ASheet");
+ assertEquals("ASheet!A1", wb.getName(nameName).getRefersToFormula());
+
+ expectName(
+ new HSSFWorkbook(new ByteArrayInputStream(stream.toByteArray())),
+ nameName, "ASheet!A1");
+ expectName(
+ new HSSFWorkbook(
+ new ByteArrayInputStream(stream2.toByteArray())),
+ nameName, "ASheet!A1");
+ }
+
+ private void expectName(HSSFWorkbook wb, String name, String expect) {
+ assertEquals(expect, wb.getName(name).getRefersToFormula());
+ }
}
diff --git a/test-data/spreadsheet/54500.xls b/test-data/spreadsheet/54500.xls
new file mode 100644
index 000000000..0cd18b51d
Binary files /dev/null and b/test-data/spreadsheet/54500.xls differ