git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@832584 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_6
<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> |
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; | ||||
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; | ||||
// - 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(); | ||||
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 | ||||
} | } | ||||
} | } | ||||
// 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() { |
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) |
* 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(); | ||||
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 | ||||
*/ | */ |
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; | ||||
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); | |||||
} | |||||
} | } |