mirror of https://github.com/apache/poi.git
Hopefully fix #45672 properly - improve handling by MissingRecordAwareHSSFListener of records that cover multiple cells (MulBlankRecord and MulRKRecord)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@832584 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
35c07feabe
commit
509c7bcb93
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.6-beta1" date="2009-??-??">
|
<release version="3.6-beta1" date="2009-??-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">45672 - improve handling by MissingRecordAwareHSSFListener of records that cover multiple cells (MulBlankRecord and MulRKRecord)</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">48096 - relaxed validation check in RecalcIdRecord</action>
|
<action dev="POI-DEVELOPERS" type="fix">48096 - relaxed validation check in RecalcIdRecord</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">48085 - improved error checking in BlockAllocationTableReader to trap unreasonable field values</action>
|
<action dev="POI-DEVELOPERS" type="fix">48085 - improved error checking in BlockAllocationTableReader to trap unreasonable field values</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">47924 - fixed logic for matching cells and comments in HSSFCell.getCellComment()</action>
|
<action dev="POI-DEVELOPERS" type="fix">47924 - fixed logic for matching cells and comments in HSSFCell.getCellComment()</action>
|
||||||
|
|
|
@ -21,9 +21,14 @@ import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
|
||||||
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
|
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
|
||||||
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord;
|
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord;
|
||||||
import org.apache.poi.hssf.record.BOFRecord;
|
import org.apache.poi.hssf.record.BOFRecord;
|
||||||
|
import org.apache.poi.hssf.record.BlankRecord;
|
||||||
import org.apache.poi.hssf.record.CellValueRecordInterface;
|
import org.apache.poi.hssf.record.CellValueRecordInterface;
|
||||||
|
import org.apache.poi.hssf.record.MulBlankRecord;
|
||||||
|
import org.apache.poi.hssf.record.MulRKRecord;
|
||||||
import org.apache.poi.hssf.record.NoteRecord;
|
import org.apache.poi.hssf.record.NoteRecord;
|
||||||
|
import org.apache.poi.hssf.record.NumberRecord;
|
||||||
import org.apache.poi.hssf.record.Record;
|
import org.apache.poi.hssf.record.Record;
|
||||||
|
import org.apache.poi.hssf.record.RecordFactory;
|
||||||
import org.apache.poi.hssf.record.RowRecord;
|
import org.apache.poi.hssf.record.RowRecord;
|
||||||
import org.apache.poi.hssf.record.SharedFormulaRecord;
|
import org.apache.poi.hssf.record.SharedFormulaRecord;
|
||||||
|
|
||||||
|
@ -62,7 +67,7 @@ public final class MissingRecordAwareHSSFListener implements HSSFListener {
|
||||||
public void processRecord(Record record) {
|
public void processRecord(Record record) {
|
||||||
int thisRow;
|
int thisRow;
|
||||||
int thisColumn;
|
int thisColumn;
|
||||||
|
CellValueRecordInterface[] expandedRecords = null;
|
||||||
|
|
||||||
if (record instanceof CellValueRecordInterface) {
|
if (record instanceof CellValueRecordInterface) {
|
||||||
CellValueRecordInterface valueRec = (CellValueRecordInterface) record;
|
CellValueRecordInterface valueRec = (CellValueRecordInterface) record;
|
||||||
|
@ -105,6 +110,19 @@ public final class MissingRecordAwareHSSFListener implements HSSFListener {
|
||||||
// - so don't fire off the LastCellOfRowDummyRecord yet
|
// - so don't fire off the LastCellOfRowDummyRecord yet
|
||||||
childListener.processRecord(record);
|
childListener.processRecord(record);
|
||||||
return;
|
return;
|
||||||
|
case MulBlankRecord.sid:
|
||||||
|
// These appear in the middle of the cell records, to
|
||||||
|
// specify that the next bunch are empty but styled
|
||||||
|
// Expand this out into multiple blank cells
|
||||||
|
MulBlankRecord mbr = (MulBlankRecord)record;
|
||||||
|
expandedRecords = RecordFactory.convertBlankRecords(mbr);
|
||||||
|
break;
|
||||||
|
case MulRKRecord.sid:
|
||||||
|
// This is multiple consecutive number cells in one record
|
||||||
|
// Exand this out into multiple regular number cells
|
||||||
|
MulRKRecord mrk = (MulRKRecord)record;
|
||||||
|
expandedRecords = RecordFactory.convertRKRecords(mrk);
|
||||||
|
break;
|
||||||
case NoteRecord.sid:
|
case NoteRecord.sid:
|
||||||
NoteRecord nrec = (NoteRecord) record;
|
NoteRecord nrec = (NoteRecord) record;
|
||||||
thisRow = nrec.getRow();
|
thisRow = nrec.getRow();
|
||||||
|
@ -112,6 +130,13 @@ public final class MissingRecordAwareHSSFListener implements HSSFListener {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First part of expanded record handling
|
||||||
|
if(expandedRecords != null && expandedRecords.length > 0) {
|
||||||
|
thisRow = expandedRecords[0].getRow();
|
||||||
|
thisColumn = expandedRecords[0].getColumn();
|
||||||
|
}
|
||||||
|
|
||||||
// If we're on cells, and this cell isn't in the same
|
// If we're on cells, and this cell isn't in the same
|
||||||
// row as the last one, then fire the
|
// row as the last one, then fire the
|
||||||
// dummy end-of-row records
|
// dummy end-of-row records
|
||||||
|
@ -148,13 +173,26 @@ public final class MissingRecordAwareHSSFListener implements HSSFListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Next part of expanded record handling
|
||||||
|
if(expandedRecords != null && expandedRecords.length > 0) {
|
||||||
|
thisColumn = expandedRecords[expandedRecords.length-1].getColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update cell and row counts as needed
|
// Update cell and row counts as needed
|
||||||
if(thisColumn != -1) {
|
if(thisColumn != -1) {
|
||||||
lastCellColumn = thisColumn;
|
lastCellColumn = thisColumn;
|
||||||
lastCellRow = thisRow;
|
lastCellRow = thisRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
childListener.processRecord(record);
|
// Pass along the record(s)
|
||||||
|
if(expandedRecords != null && expandedRecords.length > 0) {
|
||||||
|
for(CellValueRecordInterface r : expandedRecords) {
|
||||||
|
childListener.processRecord((Record)r);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
childListener.processRecord(record);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetCounts() {
|
private void resetCounts() {
|
||||||
|
|
|
@ -56,6 +56,13 @@ public final class MulBlankRecord extends StandardRecord {
|
||||||
public int getFirstColumn() {
|
public int getFirstColumn() {
|
||||||
return _firstCol;
|
return _firstCol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ending column (last cell this holds in the row). Zero based
|
||||||
|
*/
|
||||||
|
public int getLastColumn() {
|
||||||
|
return _lastCol;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the number of columns this contains (last-first +1)
|
* get the number of columns this contains (last-first +1)
|
||||||
|
|
|
@ -281,7 +281,6 @@ public final class RecordFactory {
|
||||||
* Converts a {@link MulRKRecord} into an equivalent array of {@link NumberRecord}s
|
* Converts a {@link MulRKRecord} into an equivalent array of {@link NumberRecord}s
|
||||||
*/
|
*/
|
||||||
public static NumberRecord[] convertRKRecords(MulRKRecord mrk) {
|
public static NumberRecord[] convertRKRecords(MulRKRecord mrk) {
|
||||||
|
|
||||||
NumberRecord[] mulRecs = new NumberRecord[mrk.getNumColumns()];
|
NumberRecord[] mulRecs = new NumberRecord[mrk.getNumColumns()];
|
||||||
for (int k = 0; k < mrk.getNumColumns(); k++) {
|
for (int k = 0; k < mrk.getNumColumns(); k++) {
|
||||||
NumberRecord nr = new NumberRecord();
|
NumberRecord nr = new NumberRecord();
|
||||||
|
@ -295,6 +294,22 @@ public final class RecordFactory {
|
||||||
return mulRecs;
|
return mulRecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a {@link MulBlankRecord} into an equivalent array of {@link BlankRecord}s
|
||||||
|
*/
|
||||||
|
public static BlankRecord[] convertBlankRecords(MulBlankRecord mbk) {
|
||||||
|
BlankRecord[] mulRecs = new BlankRecord[mbk.getNumColumns()];
|
||||||
|
for (int k = 0; k < mbk.getNumColumns(); k++) {
|
||||||
|
BlankRecord br = new BlankRecord();
|
||||||
|
|
||||||
|
br.setColumn((short) (k + mbk.getFirstColumn()));
|
||||||
|
br.setRow(mbk.getRow());
|
||||||
|
br.setXFIndex(mbk.getXFAt(k));
|
||||||
|
mulRecs[k] = br;
|
||||||
|
}
|
||||||
|
return mulRecs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return an array of all the SIDS for all known records
|
* @return an array of all the SIDS for all known records
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,7 +29,9 @@ import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
|
||||||
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
|
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
|
||||||
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord;
|
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord;
|
||||||
import org.apache.poi.hssf.record.BOFRecord;
|
import org.apache.poi.hssf.record.BOFRecord;
|
||||||
|
import org.apache.poi.hssf.record.BlankRecord;
|
||||||
import org.apache.poi.hssf.record.LabelSSTRecord;
|
import org.apache.poi.hssf.record.LabelSSTRecord;
|
||||||
|
import org.apache.poi.hssf.record.MulBlankRecord;
|
||||||
import org.apache.poi.hssf.record.Record;
|
import org.apache.poi.hssf.record.Record;
|
||||||
import org.apache.poi.hssf.record.RowRecord;
|
import org.apache.poi.hssf.record.RowRecord;
|
||||||
import org.apache.poi.hssf.record.SharedFormulaRecord;
|
import org.apache.poi.hssf.record.SharedFormulaRecord;
|
||||||
|
@ -422,4 +424,41 @@ public final class TestMissingRecordAwareHSSFListener extends TestCase {
|
||||||
assertEquals(1, eorCount);
|
assertEquals(1, eorCount);
|
||||||
assertEquals(1, sfrCount);
|
assertEquals(1, sfrCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MulBlank records hold multiple blank cells. Check we
|
||||||
|
* can handle them correctly.
|
||||||
|
*/
|
||||||
|
public void testMulBlankHandling() {
|
||||||
|
readRecords("45672.xls");
|
||||||
|
|
||||||
|
// Check that we don't have any MulBlankRecords, but do
|
||||||
|
// have lots of BlankRecords
|
||||||
|
Record[] rr = r;
|
||||||
|
int eorCount=0;
|
||||||
|
int mbrCount=0;
|
||||||
|
int brCount=0;
|
||||||
|
for (int i = 0; i < rr.length; i++) {
|
||||||
|
Record record = rr[i];
|
||||||
|
if (record instanceof MulBlankRecord) {
|
||||||
|
mbrCount++;
|
||||||
|
}
|
||||||
|
if (record instanceof BlankRecord) {
|
||||||
|
brCount++;
|
||||||
|
}
|
||||||
|
if (record instanceof LastCellOfRowDummyRecord) {
|
||||||
|
eorCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mbrCount > 0) {
|
||||||
|
throw new AssertionFailedError("Identified bug 45672");
|
||||||
|
}
|
||||||
|
if (brCount < 20) {
|
||||||
|
throw new AssertionFailedError("Identified bug 45672");
|
||||||
|
}
|
||||||
|
if (eorCount != 2) {
|
||||||
|
throw new AssertionFailedError("Identified bug 45672");
|
||||||
|
}
|
||||||
|
assertEquals(2, eorCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue