Consolidating ValueRecordsAggregate within RowRecordsAggregate

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@683758 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-08-07 23:49:10 +00:00
parent 7f985ab0aa
commit ea84181642
12 changed files with 754 additions and 1001 deletions

View File

@ -66,7 +66,6 @@ import org.apache.poi.hssf.record.SCLRecord;
import org.apache.poi.hssf.record.SaveRecalcRecord; import org.apache.poi.hssf.record.SaveRecalcRecord;
import org.apache.poi.hssf.record.ScenarioProtectRecord; import org.apache.poi.hssf.record.ScenarioProtectRecord;
import org.apache.poi.hssf.record.SelectionRecord; import org.apache.poi.hssf.record.SelectionRecord;
import org.apache.poi.hssf.record.SharedFormulaRecord;
import org.apache.poi.hssf.record.StringRecord; import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.record.TopMarginRecord; import org.apache.poi.hssf.record.TopMarginRecord;
import org.apache.poi.hssf.record.UncalcedRecord; import org.apache.poi.hssf.record.UncalcedRecord;
@ -82,7 +81,6 @@ import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.aggregates.MergedCellsTable; import org.apache.poi.hssf.record.aggregates.MergedCellsTable;
import org.apache.poi.hssf.record.aggregates.RecordAggregate; import org.apache.poi.hssf.record.aggregates.RecordAggregate;
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor; import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
import org.apache.poi.hssf.util.CellRangeAddress; import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.hssf.util.PaneInformation; import org.apache.poi.hssf.util.PaneInformation;
@ -121,7 +119,6 @@ public final class Sheet implements Model {
protected ArrayList records = null; protected ArrayList records = null;
int preoffset = 0; // offset of the sheet in a new file int preoffset = 0; // offset of the sheet in a new file
int loc = 0;
protected int dimsloc = -1; // TODO - is it legal for dims record to be missing? protected int dimsloc = -1; // TODO - is it legal for dims record to be missing?
protected DimensionsRecord dims; protected DimensionsRecord dims;
protected DefaultColWidthRecord defaultcolwidth = null; protected DefaultColWidthRecord defaultcolwidth = null;
@ -138,9 +135,7 @@ public final class Sheet implements Model {
protected SelectionRecord selection = null; protected SelectionRecord selection = null;
/** always present in this POI object, not always written to Excel file */ /** always present in this POI object, not always written to Excel file */
/*package*/ColumnInfoRecordsAggregate _columnInfos; /*package*/ColumnInfoRecordsAggregate _columnInfos;
protected ValueRecordsAggregate cells = null;
protected RowRecordsAggregate _rowsAggregate = null; protected RowRecordsAggregate _rowsAggregate = null;
private Iterator valueRecIterator = null;
private Iterator rowRecIterator = null; private Iterator rowRecIterator = null;
protected int eofLoc = 0; protected int eofLoc = 0;
protected ProtectRecord protect = null; protected ProtectRecord protect = null;
@ -196,17 +191,8 @@ public final class Sheet implements Model {
boolean isfirstcell = true; boolean isfirstcell = true;
int bofEofNestingLevel = 0; int bofEofNestingLevel = 0;
for (int k = offset; k < recs.size(); k++) for (int k = offset; k < recs.size(); k++) {
{
Record rec = ( Record ) recs.get(k); Record rec = ( Record ) recs.get(k);
if (rec.isValue() != (rec instanceof CellValueRecordInterface)) {
if (rec instanceof SharedFormulaRecord) {
} else {
"".length();
}
}
if ( rec.getSid() == DBCellRecord.sid ) { if ( rec.getSid() == DBCellRecord.sid ) {
continue; continue;
} }
@ -239,10 +225,10 @@ public final class Sheet implements Model {
retval._dataValidityTable = new DataValidityTable(rs); retval._dataValidityTable = new DataValidityTable(rs);
k += rs.getCountRead() - 1; // TODO - convert this method result to be zero based k += rs.getCountRead() - 1; // TODO - convert this method result to be zero based
records.add(retval._dataValidityTable); records.add(retval._dataValidityTable);
continue; // TODO continue;
} }
if ( rec.getSid() == RowRecord.sid ) // TODO construct RowRecordsAggregate from RecordStream
{ if ( rec.getSid() == RowRecord.sid ) {
RowRecord row = (RowRecord)rec; RowRecord row = (RowRecord)rec;
if (retval._rowsAggregate == null) { if (retval._rowsAggregate == null) {
retval._rowsAggregate = new RowRecordsAggregate(); retval._rowsAggregate = new RowRecordsAggregate();
@ -251,6 +237,19 @@ public final class Sheet implements Model {
retval._rowsAggregate.insertRow(row); retval._rowsAggregate.insertRow(row);
continue; continue;
} }
if ( rec.isValue() && bofEofNestingLevel == 1 ) {
if (isfirstcell) {
isfirstcell = false;
if (retval._rowsAggregate == null) {
retval._rowsAggregate = new RowRecordsAggregate();
records.add(retval._rowsAggregate); //only add the aggregate once
}
retval._rowsAggregate.constructCellValues( k, recs );
}
continue;
}
if (rec.getSid() == MergeCellsRecord.sid) { if (rec.getSid() == MergeCellsRecord.sid) {
RecordStream rs = new RecordStream(recs, k); RecordStream rs = new RecordStream(recs, k);
retval._mergedCellsTable = new MergedCellsTable(rs); retval._mergedCellsTable = new MergedCellsTable(rs);
@ -290,20 +289,6 @@ public final class Sheet implements Model {
retval.dims = ( DimensionsRecord ) rec; retval.dims = ( DimensionsRecord ) rec;
retval.dimsloc = records.size(); retval.dimsloc = records.size();
} }
else if ( rec.isValue() && bofEofNestingLevel == 1 )
{
if ( isfirstcell )
{
retval.cells = new ValueRecordsAggregate();
rec = retval.cells;
retval.cells.construct( k, recs );
isfirstcell = false;
}
else
{
rec = null;
}
}
else if (rec.getSid() == DefaultColWidthRecord.sid) else if (rec.getSid() == DefaultColWidthRecord.sid)
{ {
retval.defaultcolwidth = ( DefaultColWidthRecord ) rec; retval.defaultcolwidth = ( DefaultColWidthRecord ) rec;
@ -381,17 +366,13 @@ public final class Sheet implements Model {
retval._columnBreaksRecord = (VerticalPageBreakRecord)rec; retval._columnBreaksRecord = (VerticalPageBreakRecord)rec;
} }
if (rec != null)
{
records.add(rec); records.add(rec);
} }
}
if (retval.dimsloc < 0) { if (retval.dimsloc < 0) {
throw new RuntimeException("DimensionsRecord was not found"); throw new RuntimeException("DimensionsRecord was not found");
} }
retval.records = records; retval.records = records;
retval.checkRows(); retval.checkRows();
retval.checkCells();
if (log.check( POILogger.DEBUG )) if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited"); log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited");
return retval; return retval;
@ -432,23 +413,19 @@ public final class Sheet implements Model {
//To cater for these artificial Record types //To cater for these artificial Record types
if (rec instanceof RowRecordsAggregate) { if (rec instanceof RowRecordsAggregate) {
RowRecordsAggregate rrAgg = (RowRecordsAggregate)rec; RowRecordsAggregate rrAgg = (RowRecordsAggregate)rec;
for (Iterator rowIter = rrAgg.getIterator();rowIter.hasNext();) { for (Iterator rowIter = rrAgg.getAllRecordsIterator();rowIter.hasNext();) {
Record rowRec = (Record)rowIter.next(); Record valRec = (Record)rowIter.next();
clonedRecords.add(rowRec);
}
} else if (rec instanceof ValueRecordsAggregate) {
ValueRecordsAggregate vrAgg = (ValueRecordsAggregate)rec;
for (Iterator cellIter = vrAgg.getIterator();cellIter.hasNext();) {
Record valRec = (Record)cellIter.next();
if (valRec instanceof FormulaRecordAggregate) { if (valRec instanceof FormulaRecordAggregate) {
FormulaRecordAggregate fmAgg = (FormulaRecordAggregate)valRec; FormulaRecordAggregate fmAgg = (FormulaRecordAggregate)valRec;
Record fmAggRec = fmAgg.getFormulaRecord(); Record fmAggRec = fmAgg.getFormulaRecord();
if (fmAggRec != null) if (fmAggRec != null) {
clonedRecords.add(fmAggRec); clonedRecords.add(fmAggRec);
}
fmAggRec = fmAgg.getStringRecord(); fmAggRec = fmAgg.getStringRecord();
if (fmAggRec != null) if (fmAggRec != null) {
clonedRecords.add(fmAggRec); clonedRecords.add(fmAggRec);
}
} else { } else {
clonedRecords.add(valRec); clonedRecords.add(valRec);
} }
@ -547,7 +524,6 @@ public final class Sheet implements Model {
records.add(retval.dims); records.add(retval.dims);
retval.dimsloc = records.size()-1; retval.dimsloc = records.size()-1;
records.add(retval.windowTwo = retval.createWindowTwo()); records.add(retval.windowTwo = retval.createWindowTwo());
retval.setLoc(records.size() - 1);
retval.selection = createSelection(); retval.selection = createSelection();
records.add(retval.selection); records.add(retval.selection);
records.add(EOFRecord.instance); records.add(EOFRecord.instance);
@ -559,23 +535,6 @@ public final class Sheet implements Model {
return retval; return retval;
} }
private void checkCells()
{
if (cells == null)
{
cells = new ValueRecordsAggregate();
// In the worksheet stream, the row records always occur before the cell (value)
// records. Therefore POI's aggregates (RowRecordsAggregate, ValueRecordsAggregate)
// should follow suit. Some methods in this class tolerate either order, while
// others have been found to fail (see bug 45145).
int rraIndex = getDimsLoc() + 1;
if (records.get(rraIndex).getClass() != RowRecordsAggregate.class) {
throw new IllegalStateException("Cannot create value records before row records exist");
}
records.add(rraIndex+1, cells);
}
}
private void checkRows() private void checkRows()
{ {
if (_rowsAggregate == null) if (_rowsAggregate == null)
@ -658,32 +617,6 @@ public final class Sheet implements Model {
return getConditionalFormattingTable().size(); return getConditionalFormattingTable().size();
} }
/**
* Returns the number of low level binary records in this sheet. This adjusts things for the so called
* AgregateRecords.
*
* @see org.apache.poi.hssf.record.Record
*/
public int getNumRecords()
{
checkCells();
checkRows();
if (log.check( POILogger.DEBUG ))
{
log.log(POILogger.DEBUG, "Sheet.getNumRecords");
log.logFormatted(POILogger.DEBUG, "returning % + % + % - 2 = %", new int[]
{
records.size(), cells.getPhysicalNumberOfCells(),
_rowsAggregate.getPhysicalNumberOfRows(),
records.size() + cells.getPhysicalNumberOfCells()
+ _rowsAggregate.getPhysicalNumberOfRows() - 2
});
}
return records.size() + cells.getPhysicalNumberOfCells()
+ _rowsAggregate.getPhysicalNumberOfRows() - 2;
}
/** /**
* Per an earlier reported bug in working with Andy Khan's excel read library. This * Per an earlier reported bug in working with Andy Khan's excel read library. This
* sets the values in the sheet's DimensionsRecord object to be correct. Excel doesn't * sets the values in the sheet's DimensionsRecord object to be correct. Excel doesn't
@ -711,42 +644,6 @@ public final class Sheet implements Model {
log.log(POILogger.DEBUG, "Sheet.setDimensions exiting"); log.log(POILogger.DEBUG, "Sheet.setDimensions exiting");
} }
/**
* set the locator for where we should look for the next value record. The
* algorithm will actually start here and find the correct location so you
* can set this to 0 and watch performance go down the tubes but it will work.
* After a value is set this is automatically advanced. Its also set by the
* create method. So you probably shouldn't mess with this unless you have
* a compelling reason why or the help for the method you're calling says so.
* Check the other methods for whether they care about
* the loc pointer. Many of the "modify" and "remove" methods re-initialize this
* to "dimsloc" which is the location of the Dimensions Record and presumably the
* start of the value section (at or around 19 dec).
*
* @param loc the record number to start at
*
*/
public void setLoc(int loc)
{
valueRecIterator = null;
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "sheet.setLoc(): " + loc);
this.loc = loc;
}
/**
* Returns the location pointer to the first record to look for when adding rows/values
*
*/
public int getLoc()
{
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "sheet.getLoc():" + loc);
return loc;
}
/** /**
* Set the preoffset when using DBCELL records (currently unused) - this is * Set the preoffset when using DBCELL records (currently unused) - this is
* the position of this sheet within the whole file. * the position of this sheet within the whole file.
@ -800,13 +697,7 @@ public final class Sheet implements Model {
// Once the rows have been found in the list of records, start // Once the rows have been found in the list of records, start
// writing out the blocked row information. This includes the DBCell references // writing out the blocked row information. This includes the DBCell references
if (record instanceof RowRecordsAggregate) {
pos += ((RowRecordsAggregate)record).serialize(pos, data, cells);
} else if (record instanceof ValueRecordsAggregate) {
//Do nothing here. The records were serialized during the RowRecordAggregate block serialization
} else {
pos += record.serialize(pos, data); pos += record.serialize(pos, data);
}
// If the BOF record was just serialized then add the IndexRecord // If the BOF record was just serialized then add the IndexRecord
if (record instanceof BOFRecord) { if (record instanceof BOFRecord) {
@ -838,13 +729,7 @@ public final class Sheet implements Model {
* @param indexRecordOffset also happens to be the end of the BOF record * @param indexRecordOffset also happens to be the end of the BOF record
* @return the size of the serialized INDEX record * @return the size of the serialized INDEX record
*/ */
private int serializeIndexRecord(final int bofRecordIndex, final int indexRecordOffset, private int serializeIndexRecord(int bofRecordIndex, int indexRecordOffset, byte[] data) {
byte[] data) {
IndexRecord index = new IndexRecord();
index.setFirstRow(_rowsAggregate.getFirstRowNum());
index.setLastRowAdd1(_rowsAggregate.getLastRowNum() + 1);
// Calculate the size of the records from the end of the BOF
// and up to the RowRecordsAggregate...
// 'initial sheet records' are between INDEX and first ROW record. // 'initial sheet records' are between INDEX and first ROW record.
int sizeOfInitialSheetRecords = 0; int sizeOfInitialSheetRecords = 0;
@ -862,32 +747,7 @@ public final class Sheet implements Model {
if (_isUncalced) { if (_isUncalced) {
sizeOfInitialSheetRecords += UncalcedRecord.getStaticRecordSize(); sizeOfInitialSheetRecords += UncalcedRecord.getStaticRecordSize();
} }
IndexRecord index = _rowsAggregate.createIndexRecord(indexRecordOffset, sizeOfInitialSheetRecords);
// Add the references to the DBCells in the IndexRecord (one for each block)
// Note: The offsets are relative to the Workbook BOF. Assume that this is
// 0 for now.....
int blockCount = _rowsAggregate.getRowBlockCount();
// Calculate the size of this IndexRecord
int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount);
int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords;
for (int block = 0; block < blockCount; block++) {
// each row-block has a DBCELL record.
// The offset of each DBCELL record needs to be updated in the INDEX record
// account for row records in this row-block
currentOffset += _rowsAggregate.getRowBlockSize(block);
// account for cell value records after those
currentOffset += null == cells ? 0 : cells.getRowCellBlockSize(_rowsAggregate
.getStartRowNumberForBlock(block), _rowsAggregate.getEndRowNumberForBlock(block));
// currentOffset is now the location of the DBCELL record for this row-block
index.addDbcell(currentOffset);
// Add space required to write the DBCELL record (whose reference was just added).
currentOffset += (8 + (_rowsAggregate.getRowCountForBlock(block) * 2));
}
return index.serialize(indexRecordOffset, data); return index.serialize(indexRecordOffset, data);
} }
@ -911,15 +771,10 @@ public final class Sheet implements Model {
* @param row the row to add the cell value to * @param row the row to add the cell value to
* @param col the cell value record itself. * @param col the cell value record itself.
*/ */
public void addValueRecord(int row, CellValueRecordInterface col) public void addValueRecord(int row, CellValueRecordInterface col) {
{
checkCells(); if(log.check(POILogger.DEBUG)) {
if(log.check(POILogger.DEBUG)) log.log(POILogger.DEBUG, "add value record row" + row);
{
log.logFormatted(POILogger.DEBUG, "add value record row,loc %,%", new int[]
{
row, loc
});
} }
DimensionsRecord d = ( DimensionsRecord ) records.get(getDimsLoc()); DimensionsRecord d = ( DimensionsRecord ) records.get(getDimsLoc());
@ -931,7 +786,7 @@ public final class Sheet implements Model {
{ {
d.setFirstCol(col.getColumn()); d.setFirstCol(col.getColumn());
} }
cells.insertCell(col); _rowsAggregate.insertCell(col);
} }
/** /**
@ -943,13 +798,11 @@ public final class Sheet implements Model {
* @param col - a record supporting the CellValueRecordInterface. * @param col - a record supporting the CellValueRecordInterface.
* @see org.apache.poi.hssf.record.CellValueRecordInterface * @see org.apache.poi.hssf.record.CellValueRecordInterface
*/ */
public void removeValueRecord(int row, CellValueRecordInterface col) public void removeValueRecord(int row, CellValueRecordInterface col) {
{
checkCells();
log.logFormatted(POILogger.DEBUG, "remove value record row,dimsloc %,%", log.logFormatted(POILogger.DEBUG, "remove value record row,dimsloc %,%",
new int[]{row, dimsloc} ); new int[]{row, dimsloc} );
loc = dimsloc; _rowsAggregate.removeCell(col);
cells.removeCell(col);
} }
/** /**
@ -962,10 +815,8 @@ public final class Sheet implements Model {
* be added. * be added.
*/ */
public void replaceValueRecord(CellValueRecordInterface newval) public void replaceValueRecord(CellValueRecordInterface newval) {
{
checkCells();
setLoc(dimsloc);
if (log.check( POILogger.DEBUG )) if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "replaceValueRecord "); log.log(POILogger.DEBUG, "replaceValueRecord ");
//The ValueRecordsAggregate use a tree map underneath. //The ValueRecordsAggregate use a tree map underneath.
@ -973,8 +824,8 @@ public final class Sheet implements Model {
//key and the value, if we dont do a remove, then //key and the value, if we dont do a remove, then
//the previous instance of the key is retained, effectively using //the previous instance of the key is retained, effectively using
//double the memory //double the memory
cells.removeCell(newval); _rowsAggregate.removeCell(newval);
cells.insertCell(newval); _rowsAggregate.insertCell(newval);
} }
/** /**
@ -1024,12 +875,8 @@ public final class Sheet implements Model {
* *
* @param row the row record to remove * @param row the row record to remove
*/ */
public void removeRow(RowRecord row) {
public void removeRow(RowRecord row)
{
checkRows(); checkRows();
setLoc(getDimsLoc());
_rowsAggregate.removeRow(row); _rowsAggregate.removeRow(row);
} }
@ -1047,20 +894,8 @@ public final class Sheet implements Model {
* @return CellValueRecordInterface representing the next value record or NULL if there are no more * @return CellValueRecordInterface representing the next value record or NULL if there are no more
* @see #setLoc(int) * @see #setLoc(int)
*/ */
public CellValueRecordInterface[] getValueRecords() {
public CellValueRecordInterface getNextValueRecord() return _rowsAggregate.getValueRecords();
{
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "getNextValue loc= " + loc);
if (valueRecIterator == null)
{
valueRecIterator = cells.getIterator();
}
if (!valueRecIterator.hasNext())
{
return null;
}
return ( CellValueRecordInterface ) valueRecIterator.next();
} }
/** /**
@ -1077,11 +912,7 @@ public final class Sheet implements Model {
* @see #setLoc(int) * @see #setLoc(int)
* *
*/ */
public RowRecord getNextRow() {
public RowRecord getNextRow()
{
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "getNextRow loc= " + loc);
if (rowRecIterator == null) if (rowRecIterator == null)
{ {
rowRecIterator = _rowsAggregate.getIterator(); rowRecIterator = _rowsAggregate.getIterator();
@ -1110,8 +941,6 @@ public final class Sheet implements Model {
* *
*/ */
public RowRecord getRow(int rownum) { public RowRecord getRow(int rownum) {
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "getNextRow loc= " + loc);
return _rowsAggregate.getRow(rownum); return _rowsAggregate.getRow(rownum);
} }
@ -1659,12 +1488,8 @@ public final class Sheet implements Model {
/** /**
* in the event the record is a dimensions record, resets both the loc index and dimsloc index * in the event the record is a dimensions record, resets both the loc index and dimsloc index
*/ */
public void checkDimsLoc(Record rec, int recloc) {
public void checkDimsLoc(Record rec, int recloc) if (rec.getSid() == DimensionsRecord.sid) {
{
if (rec.getSid() == DimensionsRecord.sid)
{
loc = recloc;
dimsloc = recloc; dimsloc = recloc;
} }
} }
@ -1672,8 +1497,7 @@ public final class Sheet implements Model {
/** /**
* @return the serialized size of this sheet * @return the serialized size of this sheet
*/ */
public int getSize() public int getSize() {
{
int retval = 0; int retval = 0;
for ( int k = 0; k < records.size(); k++) { for ( int k = 0; k < records.size(); k++) {
@ -1684,21 +1508,6 @@ public final class Sheet implements Model {
} }
retval += record.getRecordSize(); retval += record.getRecordSize();
} }
if (_rowsAggregate != null) {
// Add space for the IndexRecord and DBCell records
final int nBlocks = _rowsAggregate.getRowBlockCount();
int nRows = 0;
if (cells != null) {
for (Iterator itr = _rowsAggregate.getIterator(); itr.hasNext();) {
RowRecord row = (RowRecord)itr.next();
if (cells.rowHasCells(row.getRowNumber())) {
nRows++;
}
}
}
retval += IndexRecord.getRecordSizeForBlockCount(nBlocks);
retval += DBCellRecord.calculateSizeOfRecords(nBlocks, nRows);
}
// Add space for UncalcedRecord // Add space for UncalcedRecord
if (_isUncalced) { if (_isUncalced) {
retval += UncalcedRecord.getStaticRecordSize(); retval += UncalcedRecord.getStaticRecordSize();

View File

@ -22,15 +22,17 @@ import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
/** /**
* Title: Row Record<P> * Title: Row Record (0x0208)<P/>
* Description: stores the row information for the sheet. <P> * Description: stores the row information for the sheet. <P/>
* REFERENCE: PG 379 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P> * REFERENCE: PG 379 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
* @author Andrew C. Oliver (acoliver at apache dot org) * @author Andrew C. Oliver (acoliver at apache dot org)
* @author Jason Height (jheight at chariot dot net dot au) * @author Jason Height (jheight at chariot dot net dot au)
* @version 2.0-pre * @version 2.0-pre
*/ */
public final class RowRecord extends Record implements Comparable { public final class RowRecord extends Record implements Comparable {
public final static short sid = 0x208; public final static short sid = 0x0208;
public static final int ENCODED_SIZE = 20;
private static final int OPTION_BITS_ALWAYS_SET = 0x0100; private static final int OPTION_BITS_ALWAYS_SET = 0x0100;
private static final int DEFAULT_HEIGHT_BIT = 0x8000; private static final int DEFAULT_HEIGHT_BIT = 0x8000;
@ -407,23 +409,23 @@ public final class RowRecord extends Record implements Comparable {
public int serialize(int offset, byte [] data) public int serialize(int offset, byte [] data)
{ {
LittleEndian.putShort(data, 0 + offset, sid); LittleEndian.putUShort(data, 0 + offset, sid);
LittleEndian.putShort(data, 2 + offset, ( short ) 16); LittleEndian.putUShort(data, 2 + offset, ENCODED_SIZE - 4);
LittleEndian.putShort(data, 4 + offset, ( short ) getRowNumber()); LittleEndian.putUShort(data, 4 + offset, getRowNumber());
LittleEndian.putShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol()); LittleEndian.putUShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol());
LittleEndian.putShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol()); LittleEndian.putUShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol());
LittleEndian.putShort(data, 10 + offset, getHeight()); LittleEndian.putUShort(data, 10 + offset, getHeight());
LittleEndian.putShort(data, 12 + offset, getOptimize()); LittleEndian.putUShort(data, 12 + offset, getOptimize());
LittleEndian.putShort(data, 14 + offset, field_6_reserved); LittleEndian.putUShort(data, 14 + offset, field_6_reserved);
LittleEndian.putShort(data, 16 + offset, getOptionFlags()); LittleEndian.putUShort(data, 16 + offset, getOptionFlags());
LittleEndian.putShort(data, 18 + offset, getXFIndex()); LittleEndian.putUShort(data, 18 + offset, getXFIndex());
return getRecordSize(); return ENCODED_SIZE;
} }
public int getRecordSize() public int getRecordSize()
{ {
return 20; return ENCODED_SIZE;
} }
public short getSid() public short getSid()

View File

@ -1,4 +1,3 @@
/* ==================================================================== /* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
@ -16,85 +15,90 @@
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
package org.apache.poi.hssf.record.aggregates; package org.apache.poi.hssf.record.aggregates;
import org.apache.poi.hssf.record.DBCellRecord; import java.util.ArrayList;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.RowRecord;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.DBCellRecord;
import org.apache.poi.hssf.record.IndexRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordBase;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.RowRecord;
/** /**
* *
* @author andy * @author andy
* @author Jason Height (jheight at chariot dot net dot au) * @author Jason Height (jheight at chariot dot net dot au)
*/ */
public final class RowRecordsAggregate extends Record { public final class RowRecordsAggregate extends Record {
private int firstrow = -1; private int _firstrow = -1;
private int lastrow = -1; private int _lastrow = -1;
private Map records = null; // TODO - use a proper key in this map private final Map _rowRecords;
private int size = 0; private final ValueRecordsAggregate _valuesAgg;
/** Creates a new instance of ValueRecordsAggregate */ /** Creates a new instance of ValueRecordsAggregate */
public RowRecordsAggregate() public RowRecordsAggregate() {
{ this(new TreeMap(), new ValueRecordsAggregate());
records = new TreeMap(); }
private RowRecordsAggregate(TreeMap rowRecords, ValueRecordsAggregate valuesAgg) {
_rowRecords = rowRecords;
_valuesAgg = valuesAgg;
} }
public void insertRow(RowRecord row) public void insertRow(RowRecord row) {
{
size += row.getRecordSize();
// Integer integer = new Integer(row.getRowNumber()); // Integer integer = new Integer(row.getRowNumber());
records.put(row, row); _rowRecords.put(new Integer(row.getRowNumber()), row);
if ((row.getRowNumber() < firstrow) || (firstrow == -1)) if ((row.getRowNumber() < _firstrow) || (_firstrow == -1))
{ {
firstrow = row.getRowNumber(); _firstrow = row.getRowNumber();
} }
if ((row.getRowNumber() > lastrow) || (lastrow == -1)) if ((row.getRowNumber() > _lastrow) || (_lastrow == -1))
{ {
lastrow = row.getRowNumber(); _lastrow = row.getRowNumber();
} }
} }
public void removeRow(RowRecord row) public void removeRow(RowRecord row) {
{ int rowIndex = row.getRowNumber();
size -= row.getRecordSize(); _valuesAgg.removeAllCellsValuesForRow(rowIndex);
Integer key = new Integer(rowIndex);
// Integer integer = new Integer(row.getRowNumber()); RowRecord rr = (RowRecord) _rowRecords.remove(key);
records.remove(row); if (rr == null) {
throw new RuntimeException("Invalid row index (" + key.intValue() + ")");
}
if (row != rr) {
_rowRecords.put(key, rr);
throw new RuntimeException("Attempt to remove row that does not belong to this sheet");
}
} }
public RowRecord getRow(int rownum) { public RowRecord getRow(int rowIndex) {
// Row must be between 0 and 65535 if (rowIndex < 0 || rowIndex > 65535) {
if(rownum < 0 || rownum > 65535) {
throw new IllegalArgumentException("The row number must be between 0 and 65535"); throw new IllegalArgumentException("The row number must be between 0 and 65535");
} }
return (RowRecord) _rowRecords.get(new Integer(rowIndex));
RowRecord row = new RowRecord(rownum);
return ( RowRecord ) records.get(row);
} }
public int getPhysicalNumberOfRows() public int getPhysicalNumberOfRows()
{ {
return records.size(); return _rowRecords.size();
} }
public int getFirstRowNum() public int getFirstRowNum()
{ {
return firstrow; return _firstrow;
} }
public int getLastRowNum() public int getLastRowNum()
{ {
return lastrow; return _lastrow;
} }
/** Returns the number of row blocks. /** Returns the number of row blocks.
@ -102,54 +106,60 @@ public final class RowRecordsAggregate extends Record {
* after them * after them
*/ */
public int getRowBlockCount() { public int getRowBlockCount() {
int size = records.size()/DBCellRecord.BLOCK_SIZE; int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE;
if ((records.size() % DBCellRecord.BLOCK_SIZE) != 0) if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0)
size++; size++;
return size; return size;
} }
public int getRowBlockSize(int block) { private int getRowBlockSize(int block) {
return 20 * getRowCountForBlock(block); return RowRecord.ENCODED_SIZE * getRowCountForBlock(block);
} }
/** Returns the number of physical rows within a block*/ /** Returns the number of physical rows within a block*/
public int getRowCountForBlock(int block) { public int getRowCountForBlock(int block) {
int startIndex = block * DBCellRecord.BLOCK_SIZE; int startIndex = block * DBCellRecord.BLOCK_SIZE;
int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1; int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1;
if (endIndex >= records.size()) if (endIndex >= _rowRecords.size())
endIndex = records.size()-1; endIndex = _rowRecords.size()-1;
return endIndex-startIndex+1; return endIndex-startIndex+1;
} }
/** Returns the physical row number of the first row in a block*/ /** Returns the physical row number of the first row in a block*/
public int getStartRowNumberForBlock(int block) { private int getStartRowNumberForBlock(int block) {
//Given that we basically iterate through the rows in order, //Given that we basically iterate through the rows in order,
//For a performance improvement, it would be better to return an instance of // TODO - For a performance improvement, it would be better to return an instance of
//an iterator and use that instance throughout, rather than recreating one and //an iterator and use that instance throughout, rather than recreating one and
//having to move it to the right position. //having to move it to the right position.
int startIndex = block * DBCellRecord.BLOCK_SIZE; int startIndex = block * DBCellRecord.BLOCK_SIZE;
Iterator rowIter = records.values().iterator(); Iterator rowIter = _rowRecords.values().iterator();
RowRecord row = null; RowRecord row = null;
//Position the iterator at the start of the block //Position the iterator at the start of the block
for (int i=0; i<=startIndex;i++) { for (int i=0; i<=startIndex;i++) {
row = (RowRecord)rowIter.next(); row = (RowRecord)rowIter.next();
} }
if (row == null) {
throw new RuntimeException("Did not find start row for block " + block);
}
return row.getRowNumber(); return row.getRowNumber();
} }
/** Returns the physical row number of the end row in a block*/ /** Returns the physical row number of the end row in a block*/
public int getEndRowNumberForBlock(int block) { private int getEndRowNumberForBlock(int block) {
int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1; int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1;
if (endIndex >= records.size()) if (endIndex >= _rowRecords.size())
endIndex = records.size()-1; endIndex = _rowRecords.size()-1;
Iterator rowIter = records.values().iterator(); Iterator rowIter = _rowRecords.values().iterator();
RowRecord row = null; RowRecord row = null;
for (int i=0; i<=endIndex;i++) { for (int i=0; i<=endIndex;i++) {
row = (RowRecord)rowIter.next(); row = (RowRecord)rowIter.next();
} }
if (row == null) {
throw new RuntimeException("Did not find start row for block " + block);
}
return row.getRowNumber(); return row.getRowNumber();
} }
@ -159,7 +169,7 @@ public final class RowRecordsAggregate extends Record {
final int startIndex = block*DBCellRecord.BLOCK_SIZE; final int startIndex = block*DBCellRecord.BLOCK_SIZE;
final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE; final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE;
Iterator rowIterator = records.values().iterator(); Iterator rowIterator = _rowRecords.values().iterator();
int pos = offset; int pos = offset;
//Given that we basically iterate through the rows in order, //Given that we basically iterate through the rows in order,
@ -176,10 +186,6 @@ public final class RowRecordsAggregate extends Record {
return pos - offset; return pos - offset;
} }
public int serialize(int offset, byte [] data) {
throw new RuntimeException("The serialize method that passes in cells should be used");
}
/** /**
* called by the class that is responsible for writing this sucker. * called by the class that is responsible for writing this sucker.
@ -190,9 +196,8 @@ public final class RowRecordsAggregate extends Record {
* @param data byte array containing instance data * @param data byte array containing instance data
* @return number of bytes written * @return number of bytes written
*/ */
public int serialize(int offset, byte [] data) {
public int serialize(int offset, byte [] data, ValueRecordsAggregate cells) ValueRecordsAggregate cells = _valuesAgg;
{
int pos = offset; int pos = offset;
//DBCells are serialized before row records. //DBCells are serialized before row records.
@ -209,7 +214,7 @@ public final class RowRecordsAggregate extends Record {
final int endRowNumber = getEndRowNumberForBlock(block); final int endRowNumber = getEndRowNumberForBlock(block);
DBCellRecord cellRecord = new DBCellRecord(); DBCellRecord cellRecord = new DBCellRecord();
//Note: Cell references start from the second row... //Note: Cell references start from the second row...
int cellRefOffset = (rowBlockSize-20); int cellRefOffset = (rowBlockSize-RowRecord.ENCODED_SIZE);
for (int row=startRowNumber;row<=endRowNumber;row++) { for (int row=startRowNumber;row<=endRowNumber;row++) {
if (null != cells && cells.rowHasCells(row)) { if (null != cells && cells.rowHasCells(row)) {
final int rowCellSize = cells.serializeCellRow(row, pos, data); final int rowCellSize = cells.serializeCellRow(row, pos, data);
@ -254,29 +259,59 @@ public final class RowRecordsAggregate extends Record {
return -1000; return -1000;
} }
public int getRecordSize() public int getRecordSize() {
{
return size; int retval = this._rowRecords.size() * RowRecord.ENCODED_SIZE;
for (Iterator itr = _valuesAgg.getIterator(); itr.hasNext();) {
RecordBase record = (RecordBase) itr.next();
retval += record.getRecordSize();
}
// Add space for the IndexRecord and DBCell records
final int nBlocks = getRowBlockCount();
int nRows = 0;
for (Iterator itr = getIterator(); itr.hasNext();) {
RowRecord row = (RowRecord)itr.next();
if (_valuesAgg.rowHasCells(row.getRowNumber())) {
nRows++;
}
}
retval += IndexRecord.getRecordSizeForBlockCount(nBlocks);
retval += DBCellRecord.calculateSizeOfRecords(nBlocks, nRows);
return retval;
} }
public Iterator getIterator() public Iterator getIterator()
{ {
return records.values().iterator(); return _rowRecords.values().iterator();
} }
public Iterator getAllRecordsIterator() {
List result = new ArrayList(_rowRecords.size() * 2);
result.addAll(_rowRecords.values());
Iterator vi = _valuesAgg.getIterator();
while (vi.hasNext()) {
result.add(vi.next());
}
return result.iterator();
}
/** /**
* Performs a deep clone of the record * Performs a deep clone of the record
*/ */
public Object clone() public Object clone()
{ {
RowRecordsAggregate rec = new RowRecordsAggregate(); TreeMap rows = new TreeMap();
for ( Iterator rowIter = getIterator(); rowIter.hasNext(); ) for ( Iterator rowIter = getIterator(); rowIter.hasNext(); )
{ {
//return the cloned Row Record & insert //return the cloned Row Record & insert
RowRecord row = (RowRecord) ( (RowRecord) rowIter.next() ).clone(); RowRecord row = (RowRecord) ( (RowRecord) rowIter.next() ).clone();
rec.insertRow( row ); rows.put(row, row);
} }
return rec; ValueRecordsAggregate valuesAgg = (ValueRecordsAggregate) _valuesAgg.clone();
return new RowRecordsAggregate(rows, valuesAgg);
} }
@ -449,5 +484,52 @@ public final class RowRecordsAggregate extends Record {
} }
} }
public CellValueRecordInterface[] getValueRecords() {
return _valuesAgg.getValueRecords();
}
public IndexRecord createIndexRecord(int indexRecordOffset, int sizeOfInitialSheetRecords) {
IndexRecord result = new IndexRecord();
result.setFirstRow(_firstrow);
result.setLastRowAdd1(_lastrow + 1);
// Calculate the size of the records from the end of the BOF
// and up to the RowRecordsAggregate...
// Add the references to the DBCells in the IndexRecord (one for each block)
// Note: The offsets are relative to the Workbook BOF. Assume that this is
// 0 for now.....
int blockCount = getRowBlockCount();
// Calculate the size of this IndexRecord
int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount);
int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords;
for (int block = 0; block < blockCount; block++) {
// each row-block has a DBCELL record.
// The offset of each DBCELL record needs to be updated in the INDEX record
// account for row records in this row-block
currentOffset += getRowBlockSize(block);
// account for cell value records after those
currentOffset += _valuesAgg.getRowCellBlockSize(
getStartRowNumberForBlock(block), getEndRowNumberForBlock(block));
// currentOffset is now the location of the DBCELL record for this row-block
result.addDbcell(currentOffset);
// Add space required to write the DBCELL record (whose reference was just added).
currentOffset += (8 + (getRowCountForBlock(block) * 2));
}
return result;
}
public void constructCellValues(int offset, List records) {
_valuesAgg.construct(offset, records);
}
public void insertCell(CellValueRecordInterface cvRec) {
_valuesAgg.insertCell(cvRec);
}
public void removeCell(CellValueRecordInterface cvRec) {
_valuesAgg.removeCell(cvRec);
}
} }

View File

@ -1,4 +1,3 @@
/* ==================================================================== /* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
@ -16,14 +15,19 @@
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
package org.apache.poi.hssf.record.aggregates; package org.apache.poi.hssf.record.aggregates;
import org.apache.poi.hssf.record.*; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.EOFRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SharedFormulaRecord;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.record.UnknownRecord;
/** /**
* *
@ -33,14 +37,10 @@ import java.util.List;
* @author Glen Stampoultzis (glens at apache.org) * @author Glen Stampoultzis (glens at apache.org)
* @author Jason Height (jheight at chariot dot net dot au) * @author Jason Height (jheight at chariot dot net dot au)
*/ */
public final class ValueRecordsAggregate {
public final class ValueRecordsAggregate private int firstcell = -1;
extends Record private int lastcell = -1;
{ private CellValueRecordInterface[][] records;
public final static short sid = -1001; // 1000 clashes with RowRecordsAggregate
int firstcell = -1;
int lastcell = -1;
CellValueRecordInterface[][] records;
/** Creates a new instance of ValueRecordsAggregate */ /** Creates a new instance of ValueRecordsAggregate */
@ -85,18 +85,33 @@ public final class ValueRecordsAggregate
} }
} }
public void removeCell(CellValueRecordInterface cell) public void removeCell(CellValueRecordInterface cell) {
{ if (cell == null) {
if (cell != null) { throw new IllegalArgumentException("cell must not be null");
short column = cell.getColumn(); }
int row = cell.getRow(); int row = cell.getRow();
if(row>=records.length) return; if (row >= records.length) {
throw new RuntimeException("cell row is out of range");
}
CellValueRecordInterface[] rowCells = records[row]; CellValueRecordInterface[] rowCells = records[row];
if(rowCells==null) return; if (rowCells == null) {
if(column>=rowCells.length) return; throw new RuntimeException("cell row is already empty");
}
short column = cell.getColumn();
if (column >= rowCells.length) {
throw new RuntimeException("cell column is out of range");
}
rowCells[column] = null; rowCells[column] = null;
} }
public void removeAllCellsValuesForRow(int rowIndex) {
if (rowIndex >= records.length) {
throw new IllegalArgumentException("Specified rowIndex " + rowIndex
+ " is outside the allowable range (0.." +records.length + ")");
} }
records[rowIndex] = null;
}
public int getPhysicalNumberOfCells() public int getPhysicalNumberOfCells()
{ {
@ -207,21 +222,6 @@ public final class ValueRecordsAggregate
// could log an info message here since this is a fairly unusual occurrence. // could log an info message here since this is a fairly unusual occurrence.
} }
/**
* called by the class that is responsible for writing this sucker.
* Subclasses should implement this so that their data is passed back in a
* byte array.
*
* @param offset to begin writing at
* @param data byte array containing instance data
* @return number of bytes written
*/
public int serialize(int offset, byte [] data)
{
throw new RuntimeException("This method shouldnt be called. ValueRecordsAggregate.serializeCellRow() should be called from RowRecordsAggregate.");
}
/** Tallies a count of the size of the cell records /** Tallies a count of the size of the cell records
* that are attached to the rows in the range specified. * that are attached to the rows in the range specified.
*/ */
@ -267,46 +267,26 @@ public final class ValueRecordsAggregate
return pos - offset; return pos - offset;
} }
public CellValueRecordInterface[] getValueRecords() {
List temp = new ArrayList();
/** for (int i = 0; i < records.length; i++) {
* You never fill an aggregate CellValueRecordInterface[] rowCells = records[i];
*/ if (rowCells == null) {
protected void fillFields(RecordInputStream in) continue;
{ }
for (int j = 0; j < rowCells.length; j++) {
CellValueRecordInterface cell = rowCells[j];
if (cell != null) {
temp.add(cell);
}
}
} }
/** CellValueRecordInterface[] result = new CellValueRecordInterface[temp.size()];
* called by constructor, should throw runtime exception in the event of a temp.toArray(result);
* record passed with a differing ID. return result;
*
* @param id alleged id for this record
*/
protected void validateSid(short id)
{
} }
/**
* return the non static version of the id for this record.
*/
public short getSid()
{
return sid;
}
public int getRecordSize() {
int size = 0;
Iterator irecs = this.getIterator();
while (irecs.hasNext()) {
size += (( Record ) irecs.next()).getRecordSize();
}
return size;
}
public Iterator getIterator() public Iterator getIterator()
{ {
return new MyIterator(); return new MyIterator();

View File

@ -15,13 +15,6 @@
limitations under the License. limitations under the License.
==================================================================== */ ==================================================================== */
/*
* Cell.java
*
* Created on September 30, 2001, 3:46 PM
*/
package org.apache.poi.hssf.usermodel; package org.apache.poi.hssf.usermodel;
import java.text.DateFormat; import java.text.DateFormat;
@ -74,9 +67,7 @@ import org.apache.poi.hssf.record.formula.Ptg;
* @author Yegor Kozlov cell comments support * @author Yegor Kozlov cell comments support
* @version 1.0-pre * @version 1.0-pre
*/ */
public final class HSSFCell {
public class HSSFCell
{
/** /**
* Numeric Cell type (0) * Numeric Cell type (0)
@ -152,8 +143,6 @@ public class HSSFCell
* *
* @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short) * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short)
*/ */
//protected HSSFCell(Workbook book, Sheet sheet, short row, short col)
protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col) protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col)
{ {
checkBounds(col); checkBounds(col);
@ -181,8 +170,6 @@ public class HSSFCell
* Type of cell * Type of cell
* @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short,int) * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short,int)
*/ */
//protected HSSFCell(Workbook book, Sheet sheet, short row, short col,
protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col, protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col,
int type) int type)
{ {
@ -204,8 +191,6 @@ public class HSSFCell
* @param sheet - Sheet record of the sheet containing this cell * @param sheet - Sheet record of the sheet containing this cell
* @param cval - the Cell Value Record we wish to represent * @param cval - the Cell Value Record we wish to represent
*/ */
//protected HSSFCell(Workbook book, Sheet sheet, short row,
protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row,
CellValueRecordInterface cval) CellValueRecordInterface cval)
{ {
@ -229,15 +214,9 @@ public class HSSFCell
} }
ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(cval.getXFIndex()); ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(cval.getXFIndex());
setCellStyle(new HSSFCellStyle(( short ) cval.getXFIndex(), xf, book)); setCellStyle(new HSSFCellStyle(cval.getXFIndex(), xf, book));
} }
/**
* private constructor to prevent blank construction
*/
private HSSFCell()
{
}
/** /**
* used internally -- given a cell value record, figure out its type * used internally -- given a cell value record, figure out its type
@ -346,11 +325,6 @@ public class HSSFCell
private void setCellType(int cellType, boolean setValue, int row,short col, short styleIndex) private void setCellType(int cellType, boolean setValue, int row,short col, short styleIndex)
{ {
// if (cellType == CELL_TYPE_FORMULA)
// {
// throw new RuntimeException(
// "Formulas have not been implemented in this release");
// }
if (cellType > CELL_TYPE_ERROR) if (cellType > CELL_TYPE_ERROR)
{ {
throw new RuntimeException("I have no idea what type that is!"); throw new RuntimeException("I have no idea what type that is!");
@ -501,10 +475,7 @@ public class HSSFCell
if (cellType != this.cellType && if (cellType != this.cellType &&
this.cellType!=-1 ) // Special Value to indicate an uninitialized Cell this.cellType!=-1 ) // Special Value to indicate an uninitialized Cell
{ {
int loc = sheet.getLoc();
sheet.replaceValueRecord(record); sheet.replaceValueRecord(record);
sheet.setLoc(loc);
} }
this.cellType = cellType; this.cellType = cellType;
} }
@ -540,7 +511,7 @@ public class HSSFCell
setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex); setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex);
} }
// Save into the apropriate record // Save into the appropriate record
if(record instanceof FormulaRecordAggregate) { if(record instanceof FormulaRecordAggregate) {
(( FormulaRecordAggregate ) record).getFormulaRecord().setValue(value); (( FormulaRecordAggregate ) record).getFormulaRecord().setValue(value);
} else { } else {
@ -670,9 +641,7 @@ public class HSSFCell
//only set to default if there is no extended format index already set //only set to default if there is no extended format index already set
if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f); if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f);
FormulaParser fp = new FormulaParser(formula, book); Ptg[] ptgs = FormulaParser.parse(formula, book);
fp.parse();
Ptg[] ptg = fp.getRPNPtg();
int size = 0; int size = 0;
// clear the Ptg Stack // clear the Ptg Stack
@ -681,9 +650,9 @@ public class HSSFCell
} }
// fill the Ptg Stack with Ptgs of new formula // fill the Ptg Stack with Ptgs of new formula
for (int k = 0; k < ptg.length; k++) { for (int k = 0; k < ptgs.length; k++) {
size += ptg[ k ].getSize(); size += ptgs[ k ].getSize();
frec.pushExpressionToken(ptg[ k ]); frec.pushExpressionToken(ptgs[ k ]);
} }
rec.getFormulaRecord().setExpressionLength(( short ) size); rec.getFormulaRecord().setExpressionLength(( short ) size);
//Workbook.currentBook = null; //Workbook.currentBook = null;
@ -958,38 +927,6 @@ public class HSSFCell
return new HSSFCellStyle(styleIndex, xf, book); return new HSSFCellStyle(styleIndex, xf, book);
} }
/**
* used for internationalization, currently -1 for unchanged, 0 for compressed unicode or 1 for 16-bit
*
* @see #ENCODING_UNCHANGED
* @see #ENCODING_COMPRESSED_UNICODE
* @see #ENCODING_UTF_16
*
* @return -1, 1 or 0 for unchanged, compressed or uncompressed (used only with String type)
*
* @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding.
*/
public short getEncoding()
{
return encoding;
}
/**
* set the encoding to either 8 or 16 bit. (US/UK use 8-bit, rest of the western world use 16bit)
*
* @see #ENCODING_UNCHANGED
* @see #ENCODING_COMPRESSED_UNICODE
* @see #ENCODING_UTF_16
*
* @param encoding either ENCODING_COMPRESSED_UNICODE (0) or ENCODING_UTF_16 (1)
* @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding.
*/
public void setEncoding(short encoding)
{
this.encoding = encoding;
}
/** /**
* Should only be used by HSSFSheet and friends. Returns the low level CellValueRecordInterface record * Should only be used by HSSFSheet and friends. Returns the low level CellValueRecordInterface record
* *

View File

@ -98,7 +98,12 @@ public final class HSSFRow implements Comparable {
setRowNum(record.getRowNumber()); setRowNum(record.getRowNumber());
} }
/**
* @deprecated (Aug 2008) use {@link HSSFRow#createCell(int) }
*/
public HSSFCell createCell(short columnIndex) {
return createCell((int)columnIndex);
}
/** /**
* Use this to create new cells within the row and return it. * Use this to create new cells within the row and return it.
* <p> * <p>
@ -109,26 +114,31 @@ public final class HSSFRow implements Comparable {
* *
* @return HSSFCell a high level representation of the created cell. * @return HSSFCell a high level representation of the created cell.
*/ */
public HSSFCell createCell(int columnIndex)
public HSSFCell createCell(short column)
{ {
return this.createCell(column,HSSFCell.CELL_TYPE_BLANK); return this.createCell(columnIndex,HSSFCell.CELL_TYPE_BLANK);
} }
/**
* @deprecated (Aug 2008) use {@link HSSFRow#createCell(int, int) }
*/
public HSSFCell createCell(short columnIndex, int type) {
return createCell((int)columnIndex, type);
}
/** /**
* Use this to create new cells within the row and return it. * Use this to create new cells within the row and return it.
* <p> * <p>
* The cell that is returned is a CELL_TYPE_BLANK. The type can be changed * The cell that is returned is a CELL_TYPE_BLANK. The type can be changed
* either through calling setCellValue or setCellType. * either through calling setCellValue or setCellType.
* *
* @param column - the column number this cell represents * @param columnIndex - the column number this cell represents
* *
* @return HSSFCell a high level representation of the created cell. * @return HSSFCell a high level representation of the created cell.
*/ */
public HSSFCell createCell(short column, int type) public HSSFCell createCell(int columnIndex, int type)
{ {
HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), column, type); HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), (short)columnIndex, type);
addCell(cell); addCell(cell);
sheet.addValueRecord(getRowNum(), cell.getCellValueRecord()); sheet.addValueRecord(getRowNum(), cell.getCellValueRecord());
@ -538,7 +548,7 @@ public final class HSSFRow implements Comparable {
public static class MissingCellPolicy { public static class MissingCellPolicy {
private static int NEXT_ID = 1; private static int NEXT_ID = 1;
private final int id; private final int id;
private MissingCellPolicy() { /* package */ MissingCellPolicy() {
this.id = NEXT_ID++; this.id = NEXT_ID++;
} }
} }

View File

@ -81,7 +81,7 @@ public final class HSSFSheet {
*/ */
private Sheet sheet; private Sheet sheet;
private TreeMap rows; private TreeMap rows; // TODO - use simple key into this map
protected Workbook book; protected Workbook book;
protected HSSFWorkbook workbook; protected HSSFWorkbook workbook;
private int firstrow; private int firstrow;
@ -130,21 +130,18 @@ public final class HSSFSheet {
/** /**
* used internally to set the properties given a Sheet object * used internally to set the properties given a Sheet object
*/ */
private void setPropertiesFromSheet(Sheet sheet) {
private void setPropertiesFromSheet(Sheet sheet)
{
int sloc = sheet.getLoc();
RowRecord row = sheet.getNextRow(); RowRecord row = sheet.getNextRow();
boolean rowRecordsAlreadyPresent = row!=null; boolean rowRecordsAlreadyPresent = row!=null;
while (row != null) while (row != null) {
{
createRowFromRecord(row); createRowFromRecord(row);
row = sheet.getNextRow(); row = sheet.getNextRow();
} }
sheet.setLoc(sloc);
CellValueRecordInterface cval = sheet.getNextValueRecord(); CellValueRecordInterface[] cvals = sheet.getValueRecords();
long timestart = System.currentTimeMillis(); long timestart = System.currentTimeMillis();
if (log.check( POILogger.DEBUG )) if (log.check( POILogger.DEBUG ))
@ -152,14 +149,16 @@ public final class HSSFSheet {
new Long(timestart)); new Long(timestart));
HSSFRow lastrow = null; HSSFRow lastrow = null;
while (cval != null) // Add every cell to its row
{ for (int i = 0; i < cvals.length; i++) {
CellValueRecordInterface cval = cvals[i];
long cellstart = System.currentTimeMillis(); long cellstart = System.currentTimeMillis();
HSSFRow hrow = lastrow; HSSFRow hrow = lastrow;
if ( ( lastrow == null ) || ( lastrow.getRowNum() != cval.getRow() ) ) if (hrow == null || hrow.getRowNum() != cval.getRow()) {
{
hrow = getRow( cval.getRow() ); hrow = getRow( cval.getRow() );
lastrow = hrow;
if (hrow == null) { if (hrow == null) {
// Some tools (like Perl module Spreadsheet::WriteExcel - bug 41187) skip the RowRecords // Some tools (like Perl module Spreadsheet::WriteExcel - bug 41187) skip the RowRecords
// Excel, OpenOffice.org and GoogleDocs are all OK with this, so POI should be too. // Excel, OpenOffice.org and GoogleDocs are all OK with this, so POI should be too.
@ -173,21 +172,13 @@ public final class HSSFSheet {
hrow = createRowFromRecord(rowRec); hrow = createRowFromRecord(rowRec);
} }
} }
if ( hrow != null )
{
lastrow = hrow;
if (log.check( POILogger.DEBUG )) if (log.check( POILogger.DEBUG ))
log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) ); log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) );
hrow.createCellFromRecord( cval ); hrow.createCellFromRecord( cval );
cval = sheet.getNextValueRecord();
if (log.check( POILogger.DEBUG )) if (log.check( POILogger.DEBUG ))
log.log( DEBUG, "record took ", log.log( DEBUG, "record took ",
new Long( System.currentTimeMillis() - cellstart ) ); new Long( System.currentTimeMillis() - cellstart ) );
}
else
{
cval = null;
}
} }
if (log.check( POILogger.DEBUG )) if (log.check( POILogger.DEBUG ))
log.log(DEBUG, "total sheet cell creation took ", log.log(DEBUG, "total sheet cell creation took ",
@ -230,10 +221,7 @@ public final class HSSFSheet {
* *
* @param row representing a row to remove. * @param row representing a row to remove.
*/ */
public void removeRow(HSSFRow row) {
public void removeRow(HSSFRow row)
{
sheet.setLoc(sheet.getDimsLoc());
if (rows.size() > 0) if (rows.size() > 0)
{ {
rows.remove(row); rows.remove(row);
@ -245,15 +233,6 @@ public final class HSSFSheet {
{ {
firstrow = findFirstRow(firstrow); firstrow = findFirstRow(firstrow);
} }
Iterator iter = row.cellIterator();
while (iter.hasNext())
{
HSSFCell cell = (HSSFCell) iter.next();
sheet.removeValueRecord(row.getRowNum(),
cell.getCellValueRecord());
}
sheet.removeRow(row.getRowRecord()); sheet.removeRow(row.getRowRecord());
} }
} }

View File

@ -40,7 +40,6 @@ import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.record.UncalcedRecord; import org.apache.poi.hssf.record.UncalcedRecord;
import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate; import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
import org.apache.poi.hssf.util.CellRangeAddress; import org.apache.poi.hssf.util.CellRangeAddress;
/** /**
@ -62,7 +61,6 @@ public final class TestSheet extends TestCase {
assertTrue( sheet.records.get(pos++) instanceof ColumnInfoRecordsAggregate ); assertTrue( sheet.records.get(pos++) instanceof ColumnInfoRecordsAggregate );
assertTrue( sheet.records.get(pos++) instanceof DimensionsRecord ); assertTrue( sheet.records.get(pos++) instanceof DimensionsRecord );
assertTrue( sheet.records.get(pos++) instanceof RowRecordsAggregate ); assertTrue( sheet.records.get(pos++) instanceof RowRecordsAggregate );
assertTrue( sheet.records.get(pos++) instanceof ValueRecordsAggregate );
assertTrue( sheet.records.get(pos++) instanceof EOFRecord ); assertTrue( sheet.records.get(pos++) instanceof EOFRecord );
} }
@ -434,12 +432,12 @@ public final class TestSheet extends TestCase {
throw new AssertionFailedError("Identified bug 45145"); throw new AssertionFailedError("Identified bug 45145");
} }
if (false) {
// make sure that RRA and VRA are in the right place // make sure that RRA and VRA are in the right place
int rraIx = sheet.getDimsLoc()+1; // (Aug 2008) since the VRA is now part of the RRA, there is much less chance that
List recs = sheet.getRecords(); // they could get out of order. Still, one could write serialize the sheet here,
assertEquals(RowRecordsAggregate.class, recs.get(rraIx).getClass()); // and read back with EventRecordFactory to make sure...
assertEquals(ValueRecordsAggregate.class, recs.get(rraIx+1).getClass()); }
assertEquals(242, dbCellRecordPos); assertEquals(242, dbCellRecordPos);
} }

View File

@ -106,9 +106,7 @@ public class TestValueRecordsAggregate extends TestCase
assertTrue( iterator.hasNext() ); assertTrue( iterator.hasNext() );
} }
public void testRemoveCell() public void testRemoveCell() {
throws Exception
{
BlankRecord blankRecord1 = newBlankRecord(); BlankRecord blankRecord1 = newBlankRecord();
valueRecord.insertCell( blankRecord1 ); valueRecord.insertCell( blankRecord1 );
BlankRecord blankRecord2 = newBlankRecord(); BlankRecord blankRecord2 = newBlankRecord();
@ -118,10 +116,6 @@ public class TestValueRecordsAggregate extends TestCase
// removing an already empty cell just falls through // removing an already empty cell just falls through
valueRecord.removeCell( blankRecord2 ); valueRecord.removeCell( blankRecord2 );
// even trying to remove null just falls through silently.
valueRecord.removeCell( null );
} }
public void testGetPhysicalNumberOfCells() throws Exception public void testGetPhysicalNumberOfCells() throws Exception
@ -204,22 +198,6 @@ public class TestValueRecordsAggregate extends TestCase
return blankRecord; return blankRecord;
} }
public void testGetRecordSize() throws Exception
{
List records = testData();
valueRecord.construct( 0, records );
assertEquals( 36, valueRecord.getRecordSize() );
}
public void testClone() throws Exception
{
List records = testData();
valueRecord.construct( 0, records );
valueRecord = (ValueRecordsAggregate) valueRecord.clone();
assertEquals( 36, valueRecord.getRecordSize() );
}
/** /**
* Sometimes the 'shared formula' flag (<tt>FormulaRecord.isSharedFormula()</tt>) is set when * Sometimes the 'shared formula' flag (<tt>FormulaRecord.isSharedFormula()</tt>) is set when
* there is no corresponding SharedFormulaRecord available. SharedFormulaRecord definitions do * there is no corresponding SharedFormulaRecord available. SharedFormulaRecord definitions do

View File

@ -31,12 +31,10 @@ import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.CellValueRecordInterface; import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord; import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.NameRecord; import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.DeletedArea3DPtg; import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
import org.apache.poi.hssf.util.CellRangeAddress; import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.util.TempFile; import org.apache.poi.util.TempFile;
/** /**
@ -1208,18 +1206,16 @@ public final class TestBugs extends TestCase {
assertEquals(0.0, nc3.getNumericCellValue(), 0.00001); assertEquals(0.0, nc3.getNumericCellValue(), 0.00001);
assertEquals("90210", nc3.getRichStringCellValue().getString()); assertEquals("90210", nc3.getRichStringCellValue().getString());
// Now check record level stuff too CellValueRecordInterface[] cvrs = ns.getSheet().getValueRecords();
ns.getSheet().setLoc(0); for (int i = 0; i < cvrs.length; i++) {
int fn = 0; CellValueRecordInterface cvr = cvrs[i];
CellValueRecordInterface cvr;
while((cvr = ns.getSheet().getNextValueRecord()) != null) {
if(cvr instanceof FormulaRecordAggregate) { if(cvr instanceof FormulaRecordAggregate) {
FormulaRecordAggregate fr = (FormulaRecordAggregate)cvr; FormulaRecordAggregate fr = (FormulaRecordAggregate)cvr;
if(fn == 0) { if(i == 0) {
assertEquals(70164.0, fr.getFormulaRecord().getValue(), 0.0001); assertEquals(70164.0, fr.getFormulaRecord().getValue(), 0.0001);
assertNull(fr.getStringRecord()); assertNull(fr.getStringRecord());
} else if (fn == 1) { } else if (i == 1) {
assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001); assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001);
assertNotNull(fr.getStringRecord()); assertNotNull(fr.getStringRecord());
assertEquals("70164", fr.getStringRecord().getString()); assertEquals("70164", fr.getStringRecord().getString());
@ -1228,11 +1224,9 @@ public final class TestBugs extends TestCase {
assertNotNull(fr.getStringRecord()); assertNotNull(fr.getStringRecord());
assertEquals("90210", fr.getStringRecord().getString()); assertEquals("90210", fr.getStringRecord().getString());
} }
fn++;
} }
} }
assertEquals(3, fn); assertEquals(3, cvrs.length);
} }
/** /**

View File

@ -265,14 +265,14 @@ public final class TestFormulas extends TestCase {
HSSFCell c = null; HSSFCell c = null;
//get our minimum values //get our minimum values
r = s.createRow((short)0); r = s.createRow(0);
c = r.createCell((short)1); c = r.createCell(1);
c.setCellFormula("A2" + operator + "A3"); c.setCellFormula("A2" + operator + "A3");
for (short x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) { for (int x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
r = s.createRow((short) x); r = s.createRow(x);
for (short y = 1; y < 256 && y > 0; y++) { for (int y = 1; y < 256 && y > 0; y++) {
String ref=null; String ref=null;
String ref2=null; String ref2=null;
@ -296,13 +296,13 @@ public final class TestFormulas extends TestCase {
refy2=(short)(y-3); refy2=(short)(y-3);
} }
c = r.getCell((short) y); c = r.getCell(y);
CellReference cr= new CellReference(refx1,refy1, false, false); CellReference cr= new CellReference(refx1,refy1, false, false);
ref=cr.formatAsString(); ref=cr.formatAsString();
cr=new CellReference(refx2,refy2, false, false); cr=new CellReference(refx2,refy2, false, false);
ref2=cr.formatAsString(); ref2=cr.formatAsString();
c = r.createCell((short) y); c = r.createCell(y);
c.setCellFormula("" + ref + operator + ref2); c.setCellFormula("" + ref + operator + ref2);
@ -312,8 +312,8 @@ public final class TestFormulas extends TestCase {
//make sure we do the maximum value of the Int operator //make sure we do the maximum value of the Int operator
if (s.getLastRowNum() < Short.MAX_VALUE) { if (s.getLastRowNum() < Short.MAX_VALUE) {
r = s.createRow((short)0); r = s.getRow(0);
c = r.createCell((short)0); c = r.createCell(0);
c.setCellFormula("" + "B1" + operator + "IV255"); c.setCellFormula("" + "B1" + operator + "IV255");
} }
@ -453,16 +453,16 @@ public final class TestFormulas extends TestCase {
HSSFCell c = null; HSSFCell c = null;
//get our minimum values //get our minimum values
r = s.createRow((short)0); r = s.createRow(0);
c = r.createCell((short)1); c = r.createCell(1);
c.setCellFormula(1 + operator + 1); c.setCellFormula(1 + operator + 1);
for (short x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) { for (int x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
r = s.createRow((short) x); r = s.createRow(x);
for (short y = 1; y < 256 && y > 0; y++) { for (int y = 1; y < 256 && y > 0; y++) {
c = r.createCell((short) y); c = r.createCell(y);
c.setCellFormula("" + x + operator + y); c.setCellFormula("" + x + operator + y);
} }
@ -470,8 +470,8 @@ public final class TestFormulas extends TestCase {
//make sure we do the maximum value of the Int operator //make sure we do the maximum value of the Int operator
if (s.getLastRowNum() < Short.MAX_VALUE) { if (s.getLastRowNum() < Short.MAX_VALUE) {
r = s.createRow((short)0); r = s.getRow(0);
c = r.createCell((short)0); c = r.createCell(0);
c.setCellFormula("" + Short.MAX_VALUE + operator + Short.MAX_VALUE); c.setCellFormula("" + Short.MAX_VALUE + operator + Short.MAX_VALUE);
} }

View File

@ -30,7 +30,7 @@ import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.BackupRecord; import org.apache.poi.hssf.record.BackupRecord;
import org.apache.poi.hssf.record.LabelSSTRecord; import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate; import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
import org.apache.poi.hssf.util.CellRangeAddress; import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.TempFile; import org.apache.poi.util.TempFile;
@ -93,7 +93,7 @@ public final class TestWorkbook extends TestCase {
+ ((( double ) rownum / 1000) + ((( double ) rownum / 1000)
+ (( double ) cellnum / 10000))); + (( double ) cellnum / 10000)));
c = r.createCell(( short ) (cellnum + 1)); c = r.createCell(( short ) (cellnum + 1));
c.setCellValue("TEST"); c.setCellValue(new HSSFRichTextString("TEST"));
} }
} }
wb.write(out); wb.write(out);
@ -139,7 +139,7 @@ public final class TestWorkbook extends TestCase {
+ ((( double ) rownum / 1000) + ((( double ) rownum / 1000)
+ (( double ) cellnum / 10000))); + (( double ) cellnum / 10000)));
c = r.createCell(( short ) (cellnum + 1)); c = r.createCell(( short ) (cellnum + 1));
c.setCellValue("TEST"); c.setCellValue(new HSSFRichTextString("TEST"));
} }
} }
for (short rownum = ( short ) 0; rownum < 25; rownum++) for (short rownum = ( short ) 0; rownum < 25; rownum++)
@ -310,9 +310,9 @@ public final class TestWorkbook extends TestCase {
HSSFSheet sheet = workbook.getSheetAt(0); HSSFSheet sheet = workbook.getSheetAt(0);
HSSFCell cell = sheet.getRow(0).getCell(1); HSSFCell cell = sheet.getRow(0).getCell(1);
cell.setCellValue(REPLACED); cell.setCellValue(new HSSFRichTextString(REPLACED));
cell = sheet.getRow(1).getCell(0); cell = sheet.getRow(1).getCell(0);
cell.setCellValue(REPLACED); cell.setCellValue(new HSSFRichTextString(REPLACED));
workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook); workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook);
@ -380,11 +380,11 @@ public final class TestWorkbook extends TestCase {
HSSFSheet sheet = workbook.getSheetAt(0); HSSFSheet sheet = workbook.getSheetAt(0);
HSSFCell cell = sheet.getRow(3).getCell(2); HSSFCell cell = sheet.getRow(3).getCell(2);
cell.setCellValue(LAST_NAME_VALUE); cell.setCellValue(new HSSFRichTextString(LAST_NAME_VALUE));
cell = sheet.getRow(4).getCell(2); cell = sheet.getRow(4).getCell(2);
cell.setCellValue(FIRST_NAME_VALUE); cell.setCellValue(new HSSFRichTextString(FIRST_NAME_VALUE));
cell = sheet.getRow(5).getCell(2); cell = sheet.getRow(5).getCell(2);
cell.setCellValue(SSN_VALUE); cell.setCellValue(new HSSFRichTextString(SSN_VALUE));
workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook); workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook);
sheet = workbook.getSheetAt(0); sheet = workbook.getSheetAt(0);
@ -494,11 +494,11 @@ public final class TestWorkbook extends TestCase {
cell = row.createCell(( short ) 2); cell = row.createCell(( short ) 2);
// workbook.write(new FileOutputStream("/a2.xls")); // workbook.write(new FileOutputStream("/a2.xls"));
ValueRecordsAggregate valueAggregate = RowRecordsAggregate rra = (RowRecordsAggregate)
( ValueRecordsAggregate ) sheet.getSheet() sheet.getSheet().findFirstRecordBySid((short)-1000);
.findFirstRecordBySid(ValueRecordsAggregate.sid);
int sstRecords = 0; int sstRecords = 0;
Iterator iterator = valueAggregate.getIterator(); Iterator iterator = rra.getAllRecordsIterator();
while (iterator.hasNext()) while (iterator.hasNext())
{ {
@ -511,16 +511,11 @@ public final class TestWorkbook extends TestCase {
} }
public void testManyRows() public void testManyRows() {
throws Exception
{
String testName = "TestManyRows";
File file = TempFile.createTempFile(testName, ".xls");
FileOutputStream out = new FileOutputStream(file);
HSSFWorkbook workbook = new HSSFWorkbook(); HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet(); HSSFSheet sheet = workbook.createSheet();
HSSFRow row = null; HSSFRow row;
HSSFCell cell = null; HSSFCell cell;
int i, j; int i, j;
for ( i = 0, j = 32771; j > 0; i++, j-- ) for ( i = 0, j = 32771; j > 0; i++, j-- )
{ {
@ -528,22 +523,17 @@ public final class TestWorkbook extends TestCase {
cell = row.createCell((short) 0); cell = row.createCell((short) 0);
cell.setCellValue(i); cell.setCellValue(i);
} }
workbook.write(out);
out.close();
sanityChecker.checkHSSFWorkbook(workbook); sanityChecker.checkHSSFWorkbook(workbook);
assertEquals("LAST ROW == 32770", 32770, sheet.getLastRowNum()); assertEquals("LAST ROW == 32770", 32770, sheet.getLastRowNum());
cell = sheet.getRow(32770).getCell(0);
double lastVal = cell.getNumericCellValue(); double lastVal = cell.getNumericCellValue();
FileInputStream in = new FileInputStream(file); HSSFWorkbook wb = HSSFTestDataSamples.writeOutAndReadBack(workbook);
POIFSFileSystem fs = new POIFSFileSystem(in);
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet s = wb.getSheetAt(0); HSSFSheet s = wb.getSheetAt(0);
row = s.getRow(32770); row = s.getRow(32770);
cell = row.getCell(( short ) 0); cell = row.getCell(0);
assertEquals("Value from last row == 32770", lastVal, cell.getNumericCellValue(), 0); assertEquals("Value from last row == 32770", lastVal, cell.getNumericCellValue(), 0);
assertEquals("LAST ROW == 32770", 32770, s.getLastRowNum()); assertEquals("LAST ROW == 32770", 32770, s.getLastRowNum());
in.close();
file.deleteOnExit();
} }
/** /**
@ -570,10 +560,4 @@ public final class TestWorkbook extends TestCase {
assertTrue("file exists",file.exists()); assertTrue("file exists",file.exists());
} }
public static void main(String [] ignored_args)
{
junit.textui.TestRunner.run(TestWorkbook.class);
}
} }