Bug 56325: fix Exception when removing sheets with named ranges in the workbook

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1595048 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dominik Stadler 2014-05-15 21:14:52 +00:00
parent d3a50a3388
commit e76448a83c
5 changed files with 76 additions and 10 deletions

View File

@ -716,11 +716,15 @@ 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);
}
}
// also tell the LinkTable about the removed sheet
// +1 because we already removed it from the count of sheets!
for(int i = sheetIndex+1;i < getNumSheets()+1;i++) {
// also update the link-table as otherwise references might point at invalid sheets
linkTable.removeSheet(i);
}
}
/**

View File

@ -414,9 +414,17 @@ final class LinkTable {
public int getIndexToInternalSheet(int extRefIndex) {
return _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex);
}
public void updateIndexToInternalSheet(int extRefIndex, int offset) {
_externSheetRecord.adjustIndex(extRefIndex, offset);
/**
* @deprecated Was prevously used for removing sheets, which we now do differently
*/
@Deprecated
public void updateIndexToInternalSheet(int extRefIndex, int offset) {
_externSheetRecord.adjustIndex(extRefIndex, offset);
}
public void removeSheet(int sheetIdx) {
_externSheetRecord.removeSheet(sheetIdx);
}
public int getSheetIndexFromExternSheetIndex(int extRefIndex) {
@ -453,8 +461,8 @@ final class LinkTable {
*/
private int findFirstRecordLocBySid(short sid) {
int index = 0;
for (Iterator iterator = _workbookRecordList.iterator(); iterator.hasNext(); ) {
Record record = ( Record ) iterator.next();
for (Iterator<Record> iterator = _workbookRecordList.iterator(); iterator.hasNext(); ) {
Record record = iterator.next();
if (record.getSid() == sid) {
return index;

View File

@ -164,8 +164,32 @@ public class ExternSheetRecord extends StandardRecord {
return _list.get(i);
}
public void adjustIndex(int extRefIndex, int offset) {
getRef(extRefIndex).adjustIndex(offset);
/**
* @deprecated Was prevously used for removing sheets, which we now do differently
*/
@Deprecated
public void adjustIndex(int extRefIndex, int offset) {
getRef(extRefIndex).adjustIndex(offset);
}
public void removeSheet(int sheetIdx) {
int nItems = _list.size();
int toRemove = -1;
for (int i = 0; i < nItems; i++) {
RefSubRecord refSubRecord = _list.get(i);
if(refSubRecord.getFirstSheetIndex() == sheetIdx &&
refSubRecord.getLastSheetIndex() == sheetIdx) {
toRemove = i;
} else if (refSubRecord.getFirstSheetIndex() > sheetIdx &&
refSubRecord.getLastSheetIndex() > sheetIdx) {
_list.set(i, new RefSubRecord(refSubRecord.getExtBookIndex(), refSubRecord.getFirstSheetIndex()-1, refSubRecord.getLastSheetIndex()-1));
}
}
// finally remove entries for sheet indexes that we remove
if(toRemove != -1) {
_list.remove(toRemove);
}
}
/**

View File

@ -27,9 +27,11 @@ import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
@ -2582,4 +2584,32 @@ public final class TestBugs extends BaseTestBugzillaIssues {
assertEquals(5, cf.getNumConditionalFormattings());
}
@Test
public void bug56325() throws IOException {
HSSFWorkbook wb;
File file = HSSFTestDataSamples.getSampleFile("56325.xls");
InputStream stream = new FileInputStream(file);
try {
POIFSFileSystem fs = new POIFSFileSystem(stream);
wb = new HSSFWorkbook(fs);
} finally {
stream.close();
}
assertEquals(3, wb.getNumberOfSheets());
wb.removeSheetAt(0);
assertEquals(2, wb.getNumberOfSheets());
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
assertEquals(2, wb.getNumberOfSheets());
wb.removeSheetAt(0);
assertEquals(1, wb.getNumberOfSheets());
wb.removeSheetAt(0);
assertEquals(0, wb.getNumberOfSheets());
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
assertEquals(0, wb.getNumberOfSheets());
}
}

Binary file not shown.