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.ScenarioProtectRecord;
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.TopMarginRecord;
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.RecordAggregate;
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.util.CellRangeAddress;
import org.apache.poi.hssf.util.PaneInformation;
@ -121,7 +119,6 @@ public final class Sheet implements Model {
protected ArrayList records = null;
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 DimensionsRecord dims;
protected DefaultColWidthRecord defaultcolwidth = null;
@ -138,9 +135,7 @@ public final class Sheet implements Model {
protected SelectionRecord selection = null;
/** always present in this POI object, not always written to Excel file */
/*package*/ColumnInfoRecordsAggregate _columnInfos;
protected ValueRecordsAggregate cells = null;
protected RowRecordsAggregate _rowsAggregate = null;
private Iterator valueRecIterator = null;
private Iterator rowRecIterator = null;
protected int eofLoc = 0;
protected ProtectRecord protect = null;
@ -196,17 +191,8 @@ public final class Sheet implements Model {
boolean isfirstcell = true;
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);
if (rec.isValue() != (rec instanceof CellValueRecordInterface)) {
if (rec instanceof SharedFormulaRecord) {
} else {
"".length();
}
}
if ( rec.getSid() == DBCellRecord.sid ) {
continue;
}
@ -239,10 +225,10 @@ public final class Sheet implements Model {
retval._dataValidityTable = new DataValidityTable(rs);
k += rs.getCountRead() - 1; // TODO - convert this method result to be zero based
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;
if (retval._rowsAggregate == null) {
retval._rowsAggregate = new RowRecordsAggregate();
@ -251,6 +237,19 @@ public final class Sheet implements Model {
retval._rowsAggregate.insertRow(row);
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) {
RecordStream rs = new RecordStream(recs, k);
retval._mergedCellsTable = new MergedCellsTable(rs);
@ -290,20 +289,6 @@ public final class Sheet implements Model {
retval.dims = ( DimensionsRecord ) rec;
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)
{
retval.defaultcolwidth = ( DefaultColWidthRecord ) rec;
@ -381,17 +366,13 @@ public final class Sheet implements Model {
retval._columnBreaksRecord = (VerticalPageBreakRecord)rec;
}
if (rec != null)
{
records.add(rec);
}
}
if (retval.dimsloc < 0) {
throw new RuntimeException("DimensionsRecord was not found");
}
retval.records = records;
retval.checkRows();
retval.checkCells();
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited");
return retval;
@ -432,23 +413,19 @@ public final class Sheet implements Model {
//To cater for these artificial Record types
if (rec instanceof RowRecordsAggregate) {
RowRecordsAggregate rrAgg = (RowRecordsAggregate)rec;
for (Iterator rowIter = rrAgg.getIterator();rowIter.hasNext();) {
Record rowRec = (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();
for (Iterator rowIter = rrAgg.getAllRecordsIterator();rowIter.hasNext();) {
Record valRec = (Record)rowIter.next();
if (valRec instanceof FormulaRecordAggregate) {
FormulaRecordAggregate fmAgg = (FormulaRecordAggregate)valRec;
Record fmAggRec = fmAgg.getFormulaRecord();
if (fmAggRec != null)
if (fmAggRec != null) {
clonedRecords.add(fmAggRec);
}
fmAggRec = fmAgg.getStringRecord();
if (fmAggRec != null)
if (fmAggRec != null) {
clonedRecords.add(fmAggRec);
}
} else {
clonedRecords.add(valRec);
}
@ -547,7 +524,6 @@ public final class Sheet implements Model {
records.add(retval.dims);
retval.dimsloc = records.size()-1;
records.add(retval.windowTwo = retval.createWindowTwo());
retval.setLoc(records.size() - 1);
retval.selection = createSelection();
records.add(retval.selection);
records.add(EOFRecord.instance);
@ -559,23 +535,6 @@ public final class Sheet implements Model {
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()
{
if (_rowsAggregate == null)
@ -658,32 +617,6 @@ public final class Sheet implements Model {
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
* 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");
}
/**
* 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
* 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
// 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 (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
* @return the size of the serialized INDEX record
*/
private int serializeIndexRecord(final int bofRecordIndex, final int indexRecordOffset,
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...
private int serializeIndexRecord(int bofRecordIndex, int indexRecordOffset, byte[] data) {
// 'initial sheet records' are between INDEX and first ROW record.
int sizeOfInitialSheetRecords = 0;
@ -862,32 +747,7 @@ public final class Sheet implements Model {
if (_isUncalced) {
sizeOfInitialSheetRecords += UncalcedRecord.getStaticRecordSize();
}
// 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));
}
IndexRecord index = _rowsAggregate.createIndexRecord(indexRecordOffset, sizeOfInitialSheetRecords);
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 col the cell value record itself.
*/
public void addValueRecord(int row, CellValueRecordInterface col)
{
checkCells();
if(log.check(POILogger.DEBUG))
{
log.logFormatted(POILogger.DEBUG, "add value record row,loc %,%", new int[]
{
row, loc
});
public void addValueRecord(int row, CellValueRecordInterface col) {
if(log.check(POILogger.DEBUG)) {
log.log(POILogger.DEBUG, "add value record row" + row);
}
DimensionsRecord d = ( DimensionsRecord ) records.get(getDimsLoc());
@ -931,7 +786,7 @@ public final class Sheet implements Model {
{
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.
* @see org.apache.poi.hssf.record.CellValueRecordInterface
*/
public void removeValueRecord(int row, CellValueRecordInterface col)
{
checkCells();
public void removeValueRecord(int row, CellValueRecordInterface col) {
log.logFormatted(POILogger.DEBUG, "remove value record row,dimsloc %,%",
new int[]{row, dimsloc} );
loc = dimsloc;
cells.removeCell(col);
_rowsAggregate.removeCell(col);
}
/**
@ -962,10 +815,8 @@ public final class Sheet implements Model {
* be added.
*/
public void replaceValueRecord(CellValueRecordInterface newval)
{
checkCells();
setLoc(dimsloc);
public void replaceValueRecord(CellValueRecordInterface newval) {
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "replaceValueRecord ");
//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
//the previous instance of the key is retained, effectively using
//double the memory
cells.removeCell(newval);
cells.insertCell(newval);
_rowsAggregate.removeCell(newval);
_rowsAggregate.insertCell(newval);
}
/**
@ -1024,12 +875,8 @@ public final class Sheet implements Model {
*
* @param row the row record to remove
*/
public void removeRow(RowRecord row)
{
public void removeRow(RowRecord row) {
checkRows();
setLoc(getDimsLoc());
_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
* @see #setLoc(int)
*/
public CellValueRecordInterface getNextValueRecord()
{
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();
public CellValueRecordInterface[] getValueRecords() {
return _rowsAggregate.getValueRecords();
}
/**
@ -1077,11 +912,7 @@ public final class Sheet implements Model {
* @see #setLoc(int)
*
*/
public RowRecord getNextRow()
{
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "getNextRow loc= " + loc);
public RowRecord getNextRow() {
if (rowRecIterator == null)
{
rowRecIterator = _rowsAggregate.getIterator();
@ -1110,8 +941,6 @@ public final class Sheet implements Model {
*
*/
public RowRecord getRow(int rownum) {
if (log.check( POILogger.DEBUG ))
log.log(POILogger.DEBUG, "getNextRow loc= " + loc);
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
*/
public void checkDimsLoc(Record rec, int recloc)
{
if (rec.getSid() == DimensionsRecord.sid)
{
loc = recloc;
public void checkDimsLoc(Record rec, int recloc) {
if (rec.getSid() == DimensionsRecord.sid) {
dimsloc = recloc;
}
}
@ -1672,8 +1497,7 @@ public final class Sheet implements Model {
/**
* @return the serialized size of this sheet
*/
public int getSize()
{
public int getSize() {
int retval = 0;
for ( int k = 0; k < records.size(); k++) {
@ -1684,21 +1508,6 @@ public final class Sheet implements Model {
}
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
if (_isUncalced) {
retval += UncalcedRecord.getStaticRecordSize();

View File

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

View File

@ -1,4 +1,3 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@ -16,85 +15,90 @@
limitations under the License.
==================================================================== */
package org.apache.poi.hssf.record.aggregates;
import org.apache.poi.hssf.record.DBCellRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.RowRecord;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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 Jason Height (jheight at chariot dot net dot au)
*/
public final class RowRecordsAggregate extends Record {
private int firstrow = -1;
private int lastrow = -1;
private Map records = null; // TODO - use a proper key in this map
private int size = 0;
private int _firstrow = -1;
private int _lastrow = -1;
private final Map _rowRecords;
private final ValueRecordsAggregate _valuesAgg;
/** Creates a new instance of ValueRecordsAggregate */
public RowRecordsAggregate()
{
records = new TreeMap();
public RowRecordsAggregate() {
this(new TreeMap(), new ValueRecordsAggregate());
}
private RowRecordsAggregate(TreeMap rowRecords, ValueRecordsAggregate valuesAgg) {
_rowRecords = rowRecords;
_valuesAgg = valuesAgg;
}
public void insertRow(RowRecord row)
{
size += row.getRecordSize();
public void insertRow(RowRecord row) {
// Integer integer = new Integer(row.getRowNumber());
records.put(row, row);
if ((row.getRowNumber() < firstrow) || (firstrow == -1))
_rowRecords.put(new Integer(row.getRowNumber()), row);
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)
{
size -= row.getRecordSize();
// Integer integer = new Integer(row.getRowNumber());
records.remove(row);
public void removeRow(RowRecord row) {
int rowIndex = row.getRowNumber();
_valuesAgg.removeAllCellsValuesForRow(rowIndex);
Integer key = new Integer(rowIndex);
RowRecord rr = (RowRecord) _rowRecords.remove(key);
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) {
// Row must be between 0 and 65535
if(rownum < 0 || rownum > 65535) {
public RowRecord getRow(int rowIndex) {
if (rowIndex < 0 || rowIndex > 65535) {
throw new IllegalArgumentException("The row number must be between 0 and 65535");
}
RowRecord row = new RowRecord(rownum);
return ( RowRecord ) records.get(row);
return (RowRecord) _rowRecords.get(new Integer(rowIndex));
}
public int getPhysicalNumberOfRows()
{
return records.size();
return _rowRecords.size();
}
public int getFirstRowNum()
{
return firstrow;
return _firstrow;
}
public int getLastRowNum()
{
return lastrow;
return _lastrow;
}
/** Returns the number of row blocks.
@ -102,54 +106,60 @@ public final class RowRecordsAggregate extends Record {
* after them
*/
public int getRowBlockCount() {
int size = records.size()/DBCellRecord.BLOCK_SIZE;
if ((records.size() % DBCellRecord.BLOCK_SIZE) != 0)
int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE;
if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0)
size++;
return size;
}
public int getRowBlockSize(int block) {
return 20 * getRowCountForBlock(block);
private int getRowBlockSize(int block) {
return RowRecord.ENCODED_SIZE * getRowCountForBlock(block);
}
/** Returns the number of physical rows within a block*/
public int getRowCountForBlock(int block) {
int startIndex = block * DBCellRecord.BLOCK_SIZE;
int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1;
if (endIndex >= records.size())
endIndex = records.size()-1;
if (endIndex >= _rowRecords.size())
endIndex = _rowRecords.size()-1;
return endIndex-startIndex+1;
}
/** 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,
//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
//having to move it to the right position.
int startIndex = block * DBCellRecord.BLOCK_SIZE;
Iterator rowIter = records.values().iterator();
Iterator rowIter = _rowRecords.values().iterator();
RowRecord row = null;
//Position the iterator at the start of the block
for (int i=0; i<=startIndex;i++) {
row = (RowRecord)rowIter.next();
}
if (row == null) {
throw new RuntimeException("Did not find start row for block " + block);
}
return row.getRowNumber();
}
/** 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;
if (endIndex >= records.size())
endIndex = records.size()-1;
if (endIndex >= _rowRecords.size())
endIndex = _rowRecords.size()-1;
Iterator rowIter = records.values().iterator();
Iterator rowIter = _rowRecords.values().iterator();
RowRecord row = null;
for (int i=0; i<=endIndex;i++) {
row = (RowRecord)rowIter.next();
}
if (row == null) {
throw new RuntimeException("Did not find start row for block " + block);
}
return row.getRowNumber();
}
@ -159,7 +169,7 @@ public final class RowRecordsAggregate extends Record {
final int startIndex = block*DBCellRecord.BLOCK_SIZE;
final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE;
Iterator rowIterator = records.values().iterator();
Iterator rowIterator = _rowRecords.values().iterator();
int pos = offset;
//Given that we basically iterate through the rows in order,
@ -176,10 +186,6 @@ public final class RowRecordsAggregate extends Record {
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.
@ -190,9 +196,8 @@ public final class RowRecordsAggregate extends Record {
* @param data byte array containing instance data
* @return number of bytes written
*/
public int serialize(int offset, byte [] data, ValueRecordsAggregate cells)
{
public int serialize(int offset, byte [] data) {
ValueRecordsAggregate cells = _valuesAgg;
int pos = offset;
//DBCells are serialized before row records.
@ -209,7 +214,7 @@ public final class RowRecordsAggregate extends Record {
final int endRowNumber = getEndRowNumberForBlock(block);
DBCellRecord cellRecord = new DBCellRecord();
//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++) {
if (null != cells && cells.rowHasCells(row)) {
final int rowCellSize = cells.serializeCellRow(row, pos, data);
@ -254,29 +259,59 @@ public final class RowRecordsAggregate extends Record {
return -1000;
}
public int getRecordSize()
{
return size;
public int getRecordSize() {
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()
{
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
*/
public Object clone()
{
RowRecordsAggregate rec = new RowRecordsAggregate();
TreeMap rows = new TreeMap();
for ( Iterator rowIter = getIterator(); rowIter.hasNext(); )
{
//return the cloned Row Record & insert
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
contributor license agreements. See the NOTICE file distributed with
@ -16,14 +15,19 @@
limitations under the License.
==================================================================== */
package org.apache.poi.hssf.record.aggregates;
import org.apache.poi.hssf.record.*;
import java.util.ArrayList;
import java.util.Iterator;
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 Jason Height (jheight at chariot dot net dot au)
*/
public final class ValueRecordsAggregate
extends Record
{
public final static short sid = -1001; // 1000 clashes with RowRecordsAggregate
int firstcell = -1;
int lastcell = -1;
CellValueRecordInterface[][] records;
public final class ValueRecordsAggregate {
private int firstcell = -1;
private int lastcell = -1;
private CellValueRecordInterface[][] records;
/** Creates a new instance of ValueRecordsAggregate */
@ -85,18 +85,33 @@ public final class ValueRecordsAggregate
}
}
public void removeCell(CellValueRecordInterface cell)
{
if (cell != null) {
short column = cell.getColumn();
public void removeCell(CellValueRecordInterface cell) {
if (cell == null) {
throw new IllegalArgumentException("cell must not be null");
}
int row = cell.getRow();
if(row>=records.length) return;
CellValueRecordInterface[] rowCells=records[row];
if(rowCells==null) return;
if(column>=rowCells.length) return;
rowCells[column]=null;
if (row >= records.length) {
throw new RuntimeException("cell row is out of range");
}
CellValueRecordInterface[] rowCells = records[row];
if (rowCells == null) {
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;
}
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()
{
@ -207,21 +222,6 @@ public final class ValueRecordsAggregate
// 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
* that are attached to the rows in the range specified.
*/
@ -267,46 +267,26 @@ public final class ValueRecordsAggregate
return pos - offset;
}
public CellValueRecordInterface[] getValueRecords() {
List temp = new ArrayList();
/**
* You never fill an aggregate
*/
protected void fillFields(RecordInputStream in)
{
for (int i = 0; i < records.length; i++) {
CellValueRecordInterface[] rowCells = records[i];
if (rowCells == null) {
continue;
}
for (int j = 0; j < rowCells.length; j++) {
CellValueRecordInterface cell = rowCells[j];
if (cell != null) {
temp.add(cell);
}
}
}
/**
* called by constructor, should throw runtime exception in the event of a
* record passed with a differing ID.
*
* @param id alleged id for this record
*/
protected void validateSid(short id)
{
CellValueRecordInterface[] result = new CellValueRecordInterface[temp.size()];
temp.toArray(result);
return result;
}
/**
* 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()
{
return new MyIterator();

View File

@ -15,13 +15,6 @@
limitations under the License.
==================================================================== */
/*
* Cell.java
*
* Created on September 30, 2001, 3:46 PM
*/
package org.apache.poi.hssf.usermodel;
import java.text.DateFormat;
@ -74,9 +67,7 @@ import org.apache.poi.hssf.record.formula.Ptg;
* @author Yegor Kozlov cell comments support
* @version 1.0-pre
*/
public class HSSFCell
{
public final class HSSFCell {
/**
* Numeric Cell type (0)
@ -152,8 +143,6 @@ public class HSSFCell
*
* @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)
{
checkBounds(col);
@ -181,8 +170,6 @@ public class HSSFCell
* Type of cell
* @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,
int type)
{
@ -204,8 +191,6 @@ public class HSSFCell
* @param sheet - Sheet record of the sheet containing this cell
* @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,
CellValueRecordInterface cval)
{
@ -229,15 +214,9 @@ public class HSSFCell
}
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
@ -346,11 +325,6 @@ public class HSSFCell
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)
{
throw new RuntimeException("I have no idea what type that is!");
@ -501,10 +475,7 @@ public class HSSFCell
if (cellType != this.cellType &&
this.cellType!=-1 ) // Special Value to indicate an uninitialized Cell
{
int loc = sheet.getLoc();
sheet.replaceValueRecord(record);
sheet.setLoc(loc);
}
this.cellType = cellType;
}
@ -540,7 +511,7 @@ public class HSSFCell
setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex);
}
// Save into the apropriate record
// Save into the appropriate record
if(record instanceof FormulaRecordAggregate) {
(( FormulaRecordAggregate ) record).getFormulaRecord().setValue(value);
} else {
@ -670,9 +641,7 @@ public class HSSFCell
//only set to default if there is no extended format index already set
if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f);
FormulaParser fp = new FormulaParser(formula, book);
fp.parse();
Ptg[] ptg = fp.getRPNPtg();
Ptg[] ptgs = FormulaParser.parse(formula, book);
int size = 0;
// clear the Ptg Stack
@ -681,9 +650,9 @@ public class HSSFCell
}
// fill the Ptg Stack with Ptgs of new formula
for (int k = 0; k < ptg.length; k++) {
size += ptg[ k ].getSize();
frec.pushExpressionToken(ptg[ k ]);
for (int k = 0; k < ptgs.length; k++) {
size += ptgs[ k ].getSize();
frec.pushExpressionToken(ptgs[ k ]);
}
rec.getFormulaRecord().setExpressionLength(( short ) size);
//Workbook.currentBook = null;
@ -958,38 +927,6 @@ public class HSSFCell
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
*

View File

@ -98,7 +98,12 @@ public final class HSSFRow implements Comparable {
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.
* <p>
@ -109,26 +114,31 @@ public final class HSSFRow implements Comparable {
*
* @return HSSFCell a high level representation of the created cell.
*/
public HSSFCell createCell(short column)
public HSSFCell createCell(int columnIndex)
{
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.
* <p>
* The cell that is returned is a CELL_TYPE_BLANK. The type can be changed
* 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.
*/
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);
sheet.addValueRecord(getRowNum(), cell.getCellValueRecord());
@ -538,7 +548,7 @@ public final class HSSFRow implements Comparable {
public static class MissingCellPolicy {
private static int NEXT_ID = 1;
private final int id;
private MissingCellPolicy() {
/* package */ MissingCellPolicy() {
this.id = NEXT_ID++;
}
}

View File

@ -81,7 +81,7 @@ public final class HSSFSheet {
*/
private Sheet sheet;
private TreeMap rows;
private TreeMap rows; // TODO - use simple key into this map
protected Workbook book;
protected HSSFWorkbook workbook;
private int firstrow;
@ -130,21 +130,18 @@ public final class HSSFSheet {
/**
* 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();
boolean rowRecordsAlreadyPresent = row!=null;
while (row != null)
{
while (row != null) {
createRowFromRecord(row);
row = sheet.getNextRow();
}
sheet.setLoc(sloc);
CellValueRecordInterface cval = sheet.getNextValueRecord();
CellValueRecordInterface[] cvals = sheet.getValueRecords();
long timestart = System.currentTimeMillis();
if (log.check( POILogger.DEBUG ))
@ -152,14 +149,16 @@ public final class HSSFSheet {
new Long(timestart));
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();
HSSFRow hrow = lastrow;
if ( ( lastrow == null ) || ( lastrow.getRowNum() != cval.getRow() ) )
{
if (hrow == null || hrow.getRowNum() != cval.getRow()) {
hrow = getRow( cval.getRow() );
lastrow = hrow;
if (hrow == null) {
// 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.
@ -173,21 +172,13 @@ public final class HSSFSheet {
hrow = createRowFromRecord(rowRec);
}
}
if ( hrow != null )
{
lastrow = hrow;
if (log.check( POILogger.DEBUG ))
log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) );
hrow.createCellFromRecord( cval );
cval = sheet.getNextValueRecord();
if (log.check( POILogger.DEBUG ))
log.log( DEBUG, "record took ",
new Long( System.currentTimeMillis() - cellstart ) );
}
else
{
cval = null;
}
}
if (log.check( POILogger.DEBUG ))
log.log(DEBUG, "total sheet cell creation took ",
@ -230,10 +221,7 @@ public final class HSSFSheet {
*
* @param row representing a row to remove.
*/
public void removeRow(HSSFRow row)
{
sheet.setLoc(sheet.getDimsLoc());
public void removeRow(HSSFRow row) {
if (rows.size() > 0)
{
rows.remove(row);
@ -245,15 +233,6 @@ public final class HSSFSheet {
{
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());
}
}

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

View File

@ -106,9 +106,7 @@ public class TestValueRecordsAggregate extends TestCase
assertTrue( iterator.hasNext() );
}
public void testRemoveCell()
throws Exception
{
public void testRemoveCell() {
BlankRecord blankRecord1 = newBlankRecord();
valueRecord.insertCell( blankRecord1 );
BlankRecord blankRecord2 = newBlankRecord();
@ -118,10 +116,6 @@ public class TestValueRecordsAggregate extends TestCase
// removing an already empty cell just falls through
valueRecord.removeCell( blankRecord2 );
// even trying to remove null just falls through silently.
valueRecord.removeCell( null );
}
public void testGetPhysicalNumberOfCells() throws Exception
@ -204,22 +198,6 @@ public class TestValueRecordsAggregate extends TestCase
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
* 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.record.CellValueRecordInterface;
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.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.util.TempFile;
/**
@ -1208,18 +1206,16 @@ public final class TestBugs extends TestCase {
assertEquals(0.0, nc3.getNumericCellValue(), 0.00001);
assertEquals("90210", nc3.getRichStringCellValue().getString());
// Now check record level stuff too
ns.getSheet().setLoc(0);
int fn = 0;
CellValueRecordInterface cvr;
while((cvr = ns.getSheet().getNextValueRecord()) != null) {
CellValueRecordInterface[] cvrs = ns.getSheet().getValueRecords();
for (int i = 0; i < cvrs.length; i++) {
CellValueRecordInterface cvr = cvrs[i];
if(cvr instanceof FormulaRecordAggregate) {
FormulaRecordAggregate fr = (FormulaRecordAggregate)cvr;
if(fn == 0) {
if(i == 0) {
assertEquals(70164.0, fr.getFormulaRecord().getValue(), 0.0001);
assertNull(fr.getStringRecord());
} else if (fn == 1) {
} else if (i == 1) {
assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001);
assertNotNull(fr.getStringRecord());
assertEquals("70164", fr.getStringRecord().getString());
@ -1228,11 +1224,9 @@ public final class TestBugs extends TestCase {
assertNotNull(fr.getStringRecord());
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;
//get our minimum values
r = s.createRow((short)0);
c = r.createCell((short)1);
r = s.createRow(0);
c = r.createCell(1);
c.setCellFormula("A2" + operator + "A3");
for (short x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
r = s.createRow((short) x);
for (int x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
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 ref2=null;
@ -296,13 +296,13 @@ public final class TestFormulas extends TestCase {
refy2=(short)(y-3);
}
c = r.getCell((short) y);
c = r.getCell(y);
CellReference cr= new CellReference(refx1,refy1, false, false);
ref=cr.formatAsString();
cr=new CellReference(refx2,refy2, false, false);
ref2=cr.formatAsString();
c = r.createCell((short) y);
c = r.createCell(y);
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
if (s.getLastRowNum() < Short.MAX_VALUE) {
r = s.createRow((short)0);
c = r.createCell((short)0);
r = s.getRow(0);
c = r.createCell(0);
c.setCellFormula("" + "B1" + operator + "IV255");
}
@ -453,16 +453,16 @@ public final class TestFormulas extends TestCase {
HSSFCell c = null;
//get our minimum values
r = s.createRow((short)0);
c = r.createCell((short)1);
r = s.createRow(0);
c = r.createCell(1);
c.setCellFormula(1 + operator + 1);
for (short x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
r = s.createRow((short) x);
for (int x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) {
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);
}
@ -470,8 +470,8 @@ public final class TestFormulas extends TestCase {
//make sure we do the maximum value of the Int operator
if (s.getLastRowNum() < Short.MAX_VALUE) {
r = s.createRow((short)0);
c = r.createCell((short)0);
r = s.getRow(0);
c = r.createCell(0);
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.LabelSSTRecord;
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.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.TempFile;
@ -93,7 +93,7 @@ public final class TestWorkbook extends TestCase {
+ ((( double ) rownum / 1000)
+ (( double ) cellnum / 10000)));
c = r.createCell(( short ) (cellnum + 1));
c.setCellValue("TEST");
c.setCellValue(new HSSFRichTextString("TEST"));
}
}
wb.write(out);
@ -139,7 +139,7 @@ public final class TestWorkbook extends TestCase {
+ ((( double ) rownum / 1000)
+ (( double ) cellnum / 10000)));
c = r.createCell(( short ) (cellnum + 1));
c.setCellValue("TEST");
c.setCellValue(new HSSFRichTextString("TEST"));
}
}
for (short rownum = ( short ) 0; rownum < 25; rownum++)
@ -310,9 +310,9 @@ public final class TestWorkbook extends TestCase {
HSSFSheet sheet = workbook.getSheetAt(0);
HSSFCell cell = sheet.getRow(0).getCell(1);
cell.setCellValue(REPLACED);
cell.setCellValue(new HSSFRichTextString(REPLACED));
cell = sheet.getRow(1).getCell(0);
cell.setCellValue(REPLACED);
cell.setCellValue(new HSSFRichTextString(REPLACED));
workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook);
@ -380,11 +380,11 @@ public final class TestWorkbook extends TestCase {
HSSFSheet sheet = workbook.getSheetAt(0);
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.setCellValue(FIRST_NAME_VALUE);
cell.setCellValue(new HSSFRichTextString(FIRST_NAME_VALUE));
cell = sheet.getRow(5).getCell(2);
cell.setCellValue(SSN_VALUE);
cell.setCellValue(new HSSFRichTextString(SSN_VALUE));
workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook);
sheet = workbook.getSheetAt(0);
@ -494,11 +494,11 @@ public final class TestWorkbook extends TestCase {
cell = row.createCell(( short ) 2);
// workbook.write(new FileOutputStream("/a2.xls"));
ValueRecordsAggregate valueAggregate =
( ValueRecordsAggregate ) sheet.getSheet()
.findFirstRecordBySid(ValueRecordsAggregate.sid);
RowRecordsAggregate rra = (RowRecordsAggregate)
sheet.getSheet().findFirstRecordBySid((short)-1000);
int sstRecords = 0;
Iterator iterator = valueAggregate.getIterator();
Iterator iterator = rra.getAllRecordsIterator();
while (iterator.hasNext())
{
@ -511,16 +511,11 @@ public final class TestWorkbook extends TestCase {
}
public void testManyRows()
throws Exception
{
String testName = "TestManyRows";
File file = TempFile.createTempFile(testName, ".xls");
FileOutputStream out = new FileOutputStream(file);
public void testManyRows() {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
HSSFRow row = null;
HSSFCell cell = null;
HSSFRow row;
HSSFCell cell;
int 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.setCellValue(i);
}
workbook.write(out);
out.close();
sanityChecker.checkHSSFWorkbook(workbook);
assertEquals("LAST ROW == 32770", 32770, sheet.getLastRowNum());
cell = sheet.getRow(32770).getCell(0);
double lastVal = cell.getNumericCellValue();
FileInputStream in = new FileInputStream(file);
POIFSFileSystem fs = new POIFSFileSystem(in);
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFWorkbook wb = HSSFTestDataSamples.writeOutAndReadBack(workbook);
HSSFSheet s = wb.getSheetAt(0);
row = s.getRow(32770);
cell = row.getCell(( short ) 0);
cell = row.getCell(0);
assertEquals("Value from last row == 32770", lastVal, cell.getNumericCellValue(), 0);
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());
}
public static void main(String [] ignored_args)
{
junit.textui.TestRunner.run(TestWorkbook.class);
}
}