Fix for bug 45698 - allow LinkTable to read EXTERNSHEET records

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@689704 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-08-28 02:54:47 +00:00
parent 9d343b5802
commit 05e4c39b9e
6 changed files with 248 additions and 198 deletions

View File

@ -37,6 +37,7 @@
<!-- Don't forget to update status.xml too! -->
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">45698 - Fix LinkTable to tolerate multiple EXTERNSHEET records</action>
<action dev="POI-DEVELOPERS" type="fix">45682 - Fix for cloning of CFRecordsAggregate</action>
<action dev="POI-DEVELOPERS" type="add">Initial support for evaluating external add-in functions like YEARFRAC</action>
<action dev="POI-DEVELOPERS" type="fix">45672 - Fix for MissingRecordAwareHSSFListener to prevent multiple LastCellOfRowDummyRecords when shared formulas are present</action>

View File

@ -34,6 +34,7 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1.1-alpha1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">45698 - Fix LinkTable to tolerate multiple EXTERNSHEET records</action>
<action dev="POI-DEVELOPERS" type="fix">45682 - Fix for cloning of CFRecordsAggregate</action>
<action dev="POI-DEVELOPERS" type="add">Initial support for evaluating external add-in functions like YEARFRAC</action>
<action dev="POI-DEVELOPERS" type="fix">45672 - Fix for MissingRecordAwareHSSFListener to prevent multiple LastCellOfRowDummyRecords when shared formulas are present</action>

View File

@ -159,8 +159,7 @@ final class LinkTable {
if (_externalBookBlocks.length > 0) {
// If any ExternalBookBlock present, there is always 1 of ExternSheetRecord
Record next = rs.getNext();
_externSheetRecord = (ExternSheetRecord) next;
_externSheetRecord = readExtSheetRecord(rs);
} else {
_externSheetRecord = null;
}
@ -176,6 +175,28 @@ final class LinkTable {
_workbookRecordList.getRecords().addAll(inputList.subList(startIndex, startIndex + _recordCount));
}
private static ExternSheetRecord readExtSheetRecord(RecordStream rs) {
List temp = new ArrayList(2);
while(rs.peekNextClass() == ExternSheetRecord.class) {
temp.add(rs.getNext());
}
int nItems = temp.size();
if (nItems < 1) {
throw new RuntimeException("Expected an EXTERNSHEET record but got ("
+ rs.peekNextClass().getName() + ")");
}
if (nItems == 1) {
// this is the normal case. There should be just one ExternSheetRecord
return (ExternSheetRecord) temp.get(0);
}
// Some apps generate multiple ExternSheetRecords (see bug 45698).
// It seems like the best thing to do might be to combine these into one
ExternSheetRecord[] esrs = new ExternSheetRecord[nItems];
temp.toArray(esrs);
return ExternSheetRecord.combine(esrs);
}
public LinkTable(short numberOfSheets, WorkbookRecordList workbookRecordList) {
_workbookRecordList = workbookRecordList;
_definedNames = new ArrayList();

View File

@ -260,4 +260,16 @@ public class ExternSheetRecord extends Record {
}
return -1;
}
public static ExternSheetRecord combine(ExternSheetRecord[] esrs) {
ExternSheetRecord result = new ExternSheetRecord();
for (int i = 0; i < esrs.length; i++) {
ExternSheetRecord esr = esrs[i];
int nRefs = esr.getNumOfREFRecords();
for (int j=0; j<nRefs; j++) {
result.addREFRecord(esr.getRef(j));
}
}
return result;
}
}

View File

@ -41,4 +41,19 @@ public final class TestLinkTable extends TestCase {
assertEquals("ipcSummenproduktIntern($C5,N$2,$A$9,N$1)", formula);
}
public void testMultipleExternSheetRecords_bug45698() {
HSSFWorkbook wb;
try {
wb = HSSFTestDataSamples.openSampleWorkbook("ex45698-22488.xls");
} catch (RuntimeException e) {
if ("Extern sheet is part of LinkTable".equals(e.getMessage())) {
throw new AssertionFailedError("Identified bug 45698");
}
throw e;
}
// some other sanity checks
assertEquals(7, wb.getNumberOfSheets());
}
}