Beginnings of the performance-branch merge.

PR:
Obtained from:
Submitted by:
Reviewed by:
CVS: ----------------------------------------------------------------------
CVS: PR:
CVS:   If this change addresses a PR in the problem report tracking
CVS:   database, then enter the PR number(s) here.
CVS: Obtained from:
CVS:   If this change has been taken from another system, such as NCSA,
CVS:   then name the system in this line, otherwise delete it.
CVS: Submitted by:
CVS:   If this code has been contributed to Apache by someone else; i.e.,
CVS:   they sent us a patch or a new module, then include their name/email
CVS:   address here. If this is your work then delete this line.
CVS: Reviewed by:
CVS:   If we are doing pre-commit code reviews and someone else has
CVS:   reviewed your changes, include their name(s) here.
CVS:   If you have not had it reviewed then delete this line.


git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353222 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew C. Oliver 2003-07-19 02:48:17 +00:00
parent cd3ac5e91f
commit bdea32fe42
9 changed files with 920 additions and 380 deletions

View File

@ -2,9 +2,13 @@
<classpath> <classpath>
<classpathentry kind="src" path="src/testcases"/> <classpathentry kind="src" path="src/testcases"/>
<classpathentry kind="src" path="src/java"/> <classpathentry kind="src" path="src/java"/>
<classpathentry kind="src" path="src/examples/src"/> <classpathentry kind="var" path="JRE_LIB" sourcepath="JRE_SRC"/>
<classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/> <classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/ant.jar"/>
<classpathentry kind="lib" path="tools/cents/junit.cent/lib/junit-3.7.jar"/> <classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/junit.jar"/>
<classpathentry kind="lib" path="lib/core/commons-logging-1.0.jar"/> <classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/commons-logging.jar"/>
<classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/xerces-2.3.0.jar"/>
<classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/xercesImpl.jar"/>
<classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/xml-apis.jar"/>
<classpathentry kind="lib" path="/Users/andrewoliver/projects/jakarta/poimerge/jakarta-poi/lib/xalan-2.2.0.jar"/>
<classpathentry kind="output" path="build"/> <classpathentry kind="output" path="build"/>
</classpath> </classpath>

View File

@ -234,16 +234,18 @@ public class Sheet implements Model
} }
else if ( rec.getSid() == RowRecord.sid ) else if ( rec.getSid() == RowRecord.sid )
{ {
RowRecord row = (RowRecord)rec;
if (!isfirstrow) rec = null; //only add the aggregate once
if ( isfirstrow ) if ( isfirstrow )
{ {
retval.rows = new RowRecordsAggregate(); retval.rows = new RowRecordsAggregate();
rec = retval.rows; rec = retval.rows;
retval.rows.construct( k, recs );
isfirstrow = false; isfirstrow = false;
} }
retval.rows.insertRow(row); else
{
rec = null;
}
} }
else if ( rec.getSid() == PrintGridlinesRecord.sid ) else if ( rec.getSid() == PrintGridlinesRecord.sid )
{ {
@ -261,10 +263,6 @@ public class Sheet implements Model
{ {
retval.printSetup = (PrintSetupRecord) rec; retval.printSetup = (PrintSetupRecord) rec;
} }
else if ( rec.getSid() == SelectionRecord.sid )
{
retval.selection = (SelectionRecord) rec;
}
if (rec != null) if (rec != null)
{ {
@ -527,6 +525,11 @@ public class Sheet implements Model
return numMergedRegions; return numMergedRegions;
} }
public CellValueRecordInterface getValueRecord (int row, short col) {
return cells.getCell(row, col);
}
/** /**
* This is basically a kludge to deal with the now obsolete Label records. If * This is basically a kludge to deal with the now obsolete Label records. If
* you have to read in a sheet that contains Label records, be aware that the rest * you have to read in a sheet that contains Label records, be aware that the rest
@ -1134,6 +1137,7 @@ public class Sheet implements Model
setLoc(getDimsLoc()); setLoc(getDimsLoc());
rows.removeRow(row); rows.removeRow(row);
cells.removeRow(row.getRowNumber());
/* /*
* for (int k = loc; k < records.size(); k++) * for (int k = loc; k < records.size(); k++)
@ -1310,6 +1314,9 @@ public class Sheet implements Model
public RowRecord getRow(int rownum) public RowRecord getRow(int rownum)
{ {
log.log(log.DEBUG, "getNextRow loc= " + loc); log.log(log.DEBUG, "getNextRow loc= " + loc);
if (rows == null) {
return null;
}
return rows.getRow(rownum); return rows.getRow(rownum);
/* /*
@ -1334,6 +1341,15 @@ public class Sheet implements Model
// return null; // return null;
} }
public Iterator rowRecordIterator() {
return rows.getIterator();
}
public Iterator rowCellIterator(int row) {
return this.cells.getRowCellIterator(row);
}
/** /**
* Not currently used method to calculate and add dbcell records * Not currently used method to calculate and add dbcell records
* *
@ -1412,6 +1428,15 @@ public class Sheet implements Model
} }
} }
public int getFirstRow() {
return rows.getFirstRowNum();
}
public int getLastRow() {
return rows.getLastRowNum();
}
/** not currently used */ /** not currently used */
private DBCellRecord createDBCell(int offset, IntList rowoffsets, private DBCellRecord createDBCell(int offset, IntList rowoffsets,
@ -1868,7 +1893,7 @@ public class Sheet implements Model
for (k = 0; k < columnSizes.size(); k++) for (k = 0; k < columnSizes.size(); k++)
{ {
ci = ( ColumnInfoRecord ) columnSizes.get(k); ci = ( ColumnInfoRecord ) columnSizes.get(k);
if ((ci.getFirstColumn() <= column) if ((ci.getFirstColumn() >= column)
&& (column <= ci.getLastColumn())) && (column <= ci.getLastColumn()))
{ {
break; break;
@ -1907,7 +1932,7 @@ public class Sheet implements Model
for (k = 0; k < columnSizes.size(); k++) for (k = 0; k < columnSizes.size(); k++)
{ {
ci = ( ColumnInfoRecord ) columnSizes.get(k); ci = ( ColumnInfoRecord ) columnSizes.get(k);
if ((ci.getFirstColumn() <= column) if ((ci.getFirstColumn() >= column)
&& (column <= ci.getLastColumn())) && (column <= ci.getLastColumn()))
{ {
break; break;
@ -2136,6 +2161,32 @@ public class Sheet implements Model
return new EOFRecord(); return new EOFRecord();
} }
public void setLastColForRow(int row, short col) {
this.getRow(row).setLastCol(col);
}
public void setFirstColForRow(int row, short col) {
this.getRow(row).setFirstCol(col);
}
public short getLastColForRow(int row) {
return this.getRow(row).getLastCol();
}
public short getFirstColForRow(int row) {
return this.getRow(row).getFirstCol();
}
public void setCellValue(int row, short col, double val) {
this.cells.setValue(row, col, val);
}
public void setCellStyle(int row, short col, short xf) {
this.cells.setStyle(row, col, xf);
}
/** /**
* get the location of the DimensionsRecord (which is the last record before the value section) * get the location of the DimensionsRecord (which is the last record before the value section)
* @return location in the array of records of the DimensionsRecord * @return location in the array of records of the DimensionsRecord
@ -2168,6 +2219,7 @@ public class Sheet implements Model
{ {
retval += (( Record ) records.get(k)).getRecordSize(); retval += (( Record ) records.get(k)).getRecordSize();
} }
return retval; return retval;
} }
@ -2203,6 +2255,11 @@ public class Sheet implements Model
return null; return null;
} }
public int getPhysicalNumberOfRows() {
return rows.getPhysicalNumberOfRows();
}
/** /**
* Sets the SCL record or creates it in the correct place if it does not * Sets the SCL record or creates it in the correct place if it does not
* already exist. * already exist.

View File

@ -342,6 +342,14 @@ public class FormulaRecord
return field_8_parsed_expr; return field_8_parsed_expr;
} }
/**
* sets the stack with a list
*/
public void setParsedExpression(List ptgs) {
field_8_parsed_expr = new Stack();
field_8_parsed_expr.addAll(ptgs);
}
/** /**
* called by constructor, should throw runtime exception in the event of a * called by constructor, should throw runtime exception in the event of a
* record passed with a differing ID. * record passed with a differing ID.

View File

@ -2,7 +2,7 @@
/* ==================================================================== /* ====================================================================
* The Apache Software License, Version 1.1 * The Apache Software License, Version 1.1
* *
* Copyright (c) 2003 The Apache Software Foundation. All rights * Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved. * reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -75,10 +75,12 @@ public class RowRecordsAggregate
{ {
int firstrow = -1; int firstrow = -1;
int lastrow = -1; int lastrow = -1;
boolean firstdirty = false;
boolean lastdirty = false;
Map records = null; Map records = null;
int size = 0; int size = 0;
/** Creates a new instance of ValueRecordsAggregate */ /** Creates a new instance of RowRecordsAggregate */
public RowRecordsAggregate() public RowRecordsAggregate()
{ {
@ -107,6 +109,12 @@ public class RowRecordsAggregate
size -= row.getRecordSize(); size -= row.getRecordSize();
// Integer integer = new Integer(row.getRowNumber()); // Integer integer = new Integer(row.getRowNumber());
if (lastrow == row.getRowNumber()) {
lastdirty = true;
}
if (firstrow == row.getRowNumber()) {
firstdirty = true;
}
records.remove(row); records.remove(row);
} }
@ -127,17 +135,20 @@ public class RowRecordsAggregate
public int getFirstRowNum() public int getFirstRowNum()
{ {
if (firstdirty) {
firstrow = findFirstRow();
}
return firstrow; return firstrow;
} }
public int getLastRowNum() public int getLastRowNum()
{ {
if (lastdirty) {
lastrow = findLastRow();
}
return lastrow; return lastrow;
} }
/*
* No need to go through all the records as we're just collecting RowRecords
public int construct(int offset, List records) public int construct(int offset, List records)
{ {
int k = 0; int k = 0;
@ -157,7 +168,7 @@ public class RowRecordsAggregate
} }
return k; return k;
} }
*/
/** /**
* called by the class that is responsible for writing this sucker. * called by the class that is responsible for writing this sucker.
* Subclasses should implement this so that their data is passed back in a * Subclasses should implement this so that their data is passed back in a
@ -222,7 +233,43 @@ public class RowRecordsAggregate
{ {
return records.values().iterator(); return records.values().iterator();
} }
/**
* used internally to refresh the "last row" when the last row is removed.
*/
private int findLastRow()
{
int rownum = lastrow-1;
RowRecord r = getRow(rownum);
while (r == null && rownum >= 0)
{
r = this.getRow(--rownum);
}
return rownum;
}
/**
* used internally to refresh the "first row" when the first row is removed.
*/
private int findFirstRow()
{
int rownum = firstrow+1;
RowRecord r = getRow(rownum);
while (r == null && rownum <= getLastRowNum())
{
r = getRow(++rownum);
}
if (rownum > getLastRowNum())
return -1;
return rownum;
}
/** Performs a deep clone of the record*/ /** Performs a deep clone of the record*/
public Object clone() { public Object clone() {
RowRecordsAggregate rec = new RowRecordsAggregate(); RowRecordsAggregate rec = new RowRecordsAggregate();

View File

@ -2,7 +2,7 @@
/* ==================================================================== /* ====================================================================
* The Apache Software License, Version 1.1 * The Apache Software License, Version 1.1
* *
* Copyright (c) 2003 The Apache Software Foundation. All rights * Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved. * reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -55,17 +55,22 @@
package org.apache.poi.hssf.record.aggregates; package org.apache.poi.hssf.record.aggregates;
import org.apache.poi.hssf.usermodel.HSSFCell; //kludge shouldn't refer to this
import org.apache.poi.hssf.record.*; import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.util.DoubleList;
import org.apache.poi.util.IntList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.TreeMap; import java.util.ArrayList;
/** /**
* *
* Aggregate value records together. Things are easier to handle that way. * Aggregate value records together. Things are easier to handle that way.
* *
* @author andy * @author Andrew C. Oliver
* @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)
*/ */
@ -76,63 +81,72 @@ public class ValueRecordsAggregate
public final static short sid = -1000; public final static short sid = -1000;
int firstcell = -1; int firstcell = -1;
int lastcell = -1; int lastcell = -1;
TreeMap records = null; //TreeMap records = null;
// int size = 0;
/** Creates a new instance of ValueRecordsAggregate */ private final static int DEFAULT_ROWS=10000;
private final static int DEFAULT_COLS=256;
List celltype = null;
List xfs = null;
List numericcells = null;
List formulaptgs = null;
List stringvals = null;
IntList populatedRows = null;
int physCells; //physical number of cells
public CellValueRecordInterface getCell(int row, short col) {
return constructRecord(row, col);
public ValueRecordsAggregate()
{
records = new TreeMap();
} }
public void insertCell(CellValueRecordInterface cell) public int getRecordSize() {
{ //throw new RuntimeException("Not Implemented getRecordSize");
/* if (records.get(cell) == null)
{ int size = 0;
size += (( Record ) cell).getRecordSize(); Iterator irecs = getIterator();
while (irecs.hasNext()) {
size += (( Record ) irecs.next()).getRecordSize();
} }
else
return size;
// return size;
}
public int serialize(int offset, byte [] data)
{
//throw new RuntimeException("Not Implemented serialize");
int pos = offset;
Iterator irecs = getIterator();
while (irecs.hasNext()) {
pos += (( Record ) irecs.next()).serialize(pos,data);
}
/* Iterator itr = records.values().iterator();
int pos = offset;
while (itr.hasNext())
{ {
size += (( Record ) cell).getRecordSize() pos += (( Record ) itr.next()).serialize(pos, data);
- (( Record ) records.get(cell)).getRecordSize();
}*/ }*/
return pos - offset;
// XYLocator xy = new XYLocator(cell.getRow(), cell.getColumn());
Object o = records.put(cell, cell);
if ((cell.getColumn() < firstcell) || (firstcell == -1))
{
firstcell = cell.getColumn();
}
if ((cell.getColumn() > lastcell) || (lastcell == -1))
{
lastcell = cell.getColumn();
}
} }
public void removeCell(CellValueRecordInterface cell) public ValueRecordsAggregate() {
{ celltype = new ArrayList(DEFAULT_ROWS);
// size -= (( Record ) cell).getRecordSize(); xfs = new ArrayList(DEFAULT_ROWS);
numericcells = new ArrayList(DEFAULT_ROWS);
// XYLocator xy = new XYLocator(cell.getRow(), cell.getColumn()); formulaptgs = new ArrayList(DEFAULT_ROWS);
records.remove(cell); stringvals = new ArrayList(DEFAULT_ROWS);
populatedRows = new IntList(DEFAULT_ROWS);
physCells = 0;
} }
public int getPhysicalNumberOfCells() public Iterator getIterator() {
{ return new VRAIterator(this);
return records.size();
} }
public int getFirstCellNum()
{
return firstcell;
}
public int getLastCellNum()
{
return lastcell;
}
public int construct(int offset, List records) public int construct(int offset, List records)
{ {
@ -157,11 +171,6 @@ public class ValueRecordsAggregate
{ {
lastFormulaAggregate.setStringRecord((StringRecord)rec); lastFormulaAggregate.setStringRecord((StringRecord)rec);
} }
else if (rec instanceof SharedFormulaRecord)
{
//these follow the first formula in a group
lastFormulaAggregate.setSharedFormulaRecord((SharedFormulaRecord)rec);
}
else if (rec.isValue()) else if (rec.isValue())
{ {
insertCell(( CellValueRecordInterface ) rec); insertCell(( CellValueRecordInterface ) rec);
@ -170,140 +179,449 @@ public class ValueRecordsAggregate
return k; return k;
} }
/** public int getPhysicalNumberOfCells() {
* called by the class that is responsible for writing this sucker. return physCells;
* 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) public int getPhysicalNumberOfCellsInRow(int row) {
int count = -1;
int col = -1;
boolean firsttime = true;
while (col > 0 || count == -1) {
col = findNextPopulatedCell(row,col);
count++;
}
return count;
}
public void setValue(int row, short cell, double val) {
((DoubleList)numericcells.get(row)).set(cell, val);
}
public void setStyle(int row, short cell, short xf) {
((IntList)xfs.get(row)).set(cell, xf);
}
public Iterator getRowCellIterator(int row) {
return new VRAIterator(this, row);
}
public void removeRow(int row) {
Iterator iterator = this.getRowCellIterator(row);
while(iterator.hasNext()) {
iterator.next();
iterator.remove();
}
}
public void removeCell(CellValueRecordInterface cell) {
int rownum = cell.getRow();
int colnum = cell.getColumn();
int xf = cell.getXFIndex();
int type = determineType(cell);
if (rownum < celltype.size() && colnum < ((IntList)celltype.get(rownum)).size()) {
IntList ctRow = (IntList)celltype.get(rownum);
if (ctRow.size()-1 == colnum) {
ctRow.remove(colnum);
if (ctRow.size() == 0 && celltype.size()-1 == rownum) {
celltype.remove(rownum);
int remp = populatedRows.indexOf(rownum);
System.err.println("remp == "+remp);
populatedRows.removeValue(rownum);
}
} else {
ctRow.set(colnum,-1);
}
physCells--;
} else {
//this cell doesn't exist...
throw new RuntimeException("Tried to remove a cell that does not exist r,c="+rownum+","+colnum);
}
}
public void insertCell(CellValueRecordInterface cell) {
int rownum = cell.getRow();
int colnum = cell.getColumn();
int xf = cell.getXFIndex();
int type = determineType(cell);
if (celltype.size() < rownum+1) {
populatedRows.add(rownum); //this means we must never have had this row inserted
}
ensureRows(rownum);
IntList ctRow = (IntList)celltype.get(rownum);
IntList xfRow = (IntList)xfs.get(rownum);
adjustIntList(ctRow, colnum+1);
adjustIntList(xfRow, colnum+1);
ctRow.set(colnum, type);
xfRow.set(colnum, xf);
insertCell(cell, type);
}
CellValueRecordInterface constructRecord(int row, int col) {
if (celltype.size() < row || ((IntList)celltype.get(row)).size() < col) {
throw new ArrayIndexOutOfBoundsException("constructRecord called with row = "+row+
"and col ="+col+" but there are only "+celltype.size()+" rows and "+
((IntList)celltype.get(row)).size()+" cols!!");
}
CellValueRecordInterface retval = null;
int type = ((IntList)celltype.get(row)).get(col);
switch (type) {
case HSSFCell.CELL_TYPE_NUMERIC:
NumberRecord nrecord = new NumberRecord();
nrecord.setColumn((short)col);
nrecord.setRow(row);
nrecord.setValue(((DoubleList)numericcells.get(row)).get(col));
nrecord.setXFIndex((short)((IntList)xfs.get(row)).get(col));
retval = nrecord;
break;
case HSSFCell.CELL_TYPE_STRING:
LabelSSTRecord srecord = new LabelSSTRecord();
srecord.setColumn((short)col);
srecord.setRow(row);
srecord.setSSTIndex((int)((DoubleList)numericcells.get(row)).get(col));
srecord.setXFIndex((short)((IntList)xfs.get(row)).get(col));
retval=srecord;
break;
case HSSFCell.CELL_TYPE_BLANK:
BlankRecord brecord = new BlankRecord();
brecord.setColumn((short)col);
brecord.setRow(row);
brecord.setXFIndex((short)((IntList)xfs.get(row)).get(col));
retval=brecord;
break;
case HSSFCell.CELL_TYPE_FORMULA:
FormulaRecord fr = new FormulaRecord();
fr.setColumn((short)col);
fr.setOptions((short)2);
fr.setRow(row);
fr.setXFIndex((short)((IntList)xfs.get(row)).get(col));
StringRecord st = null;
String strval = (String)((List)stringvals.get(row)).get(col);
List expressionlist = (List)((List)formulaptgs.get(row)).get(col);
fr.setParsedExpression(expressionlist);
fr.setExpressionLength(calculatePtgSize(expressionlist));
if (strval != null) {
st = new StringRecord();
st.setString(strval);
}
FormulaRecordAggregate frarecord = new FormulaRecordAggregate(fr,st);
retval= frarecord;
break;
default:
throw new RuntimeException("UnImplemented Celltype "+type);
}
return retval;
}
private short calculatePtgSize(List expressionlist) {
short retval = 0;
Iterator iter = expressionlist.iterator();
while (iter.hasNext()) {
retval += (short)((Ptg)iter.next()).getSize();
}
return retval;
}
private void insertCell(CellValueRecordInterface cell, int type) {
int rownum = cell.getRow();
int colnum = cell.getColumn();
DoubleList nmRow = (DoubleList)numericcells.get(rownum);
switch (type) {
case HSSFCell.CELL_TYPE_NUMERIC:
NumberRecord nrecord = (NumberRecord)cell;
adjustDoubleList(nmRow, colnum+1);
nmRow.set(colnum,nrecord.getValue());
physCells++;
break;
case HSSFCell.CELL_TYPE_STRING:
LabelSSTRecord srecord = (LabelSSTRecord)cell;
adjustDoubleList(nmRow, colnum+1);
nmRow.set(colnum,srecord.getSSTIndex());
physCells++;
break;
case HSSFCell.CELL_TYPE_FORMULA:
List ptRow = (List)formulaptgs.get(rownum);
List stRow = (List)stringvals.get(rownum);
FormulaRecordAggregate frarecord = (FormulaRecordAggregate)cell;
adjustDoubleList(nmRow, colnum+1);
adjustObjectList(ptRow, colnum+1);
adjustStringList(stRow, colnum+1);
nmRow.set(colnum,frarecord.getFormulaRecord().getValue());
ptRow.set(colnum,frarecord.getFormulaRecord().getParsedExpression());
StringRecord str = frarecord.getStringRecord();
if (str != null) {
stRow.set(colnum,str.getString());
} else {
stRow.set(colnum,null);
}
physCells++;
break;
case HSSFCell.CELL_TYPE_BLANK:
//BlankRecord brecord = (BlankRecord)cell;
physCells++;
break;
default:
throw new RuntimeException("UnImplemented Celltype "+cell.toString());
}
}
private int determineType(CellValueRecordInterface cval)
{ {
Iterator itr = records.values().iterator(); Record record = ( Record ) cval;
int pos = offset; int sid = record.getSid();
int retval = 0;
while (itr.hasNext()) switch (sid)
{ {
pos += (( Record ) itr.next()).serialize(pos, data);
case NumberRecord.sid :
retval = HSSFCell.CELL_TYPE_NUMERIC;
break;
case BlankRecord.sid :
retval = HSSFCell.CELL_TYPE_BLANK;
break;
case LabelSSTRecord.sid :
retval = HSSFCell.CELL_TYPE_STRING;
break;
case FormulaRecordAggregate.sid :
retval = HSSFCell.CELL_TYPE_FORMULA;
break;
case BoolErrRecord.sid :
BoolErrRecord boolErrRecord = ( BoolErrRecord ) record;
retval = (boolErrRecord.isBoolean())
? HSSFCell.CELL_TYPE_BOOLEAN
: HSSFCell.CELL_TYPE_ERROR;
break;
} }
return pos - offset; return retval;
}
/**
* called by the constructor, should set class level fields. Should throw
* runtime exception for bad/icomplete data.
*
* @param data raw data
* @param size size of data
* @param offset of the record's data (provided a big array of the file)
*/
protected void fillFields(byte [] data, short size, int offset)
{
} }
/** private void ensureRows(int rownum) {
* called by constructor, should throw runtime exception in the event of a adjustRows(celltype, rownum+1, IntList.class);
* record passed with a differing ID. adjustRows(xfs, rownum+1, IntList.class);
* adjustRows(numericcells, rownum+1, DoubleList.class);
* @param id alleged id for this record adjustRows(formulaptgs, rownum+1, ArrayList.class);
*/ adjustRows(stringvals, rownum+1, ArrayList.class);
protected void validateSid(short id)
{
} }
/** private void adjustRows(List list, int size, Class theclass) {
* return the non static version of the id for this record. while (list.size() < size) {
*/ try {
list.add(theclass.newInstance());
public short getSid() } catch (Exception e) {
{ throw new RuntimeException("Could Not Instantiate Row in adjustRows");
return sid; }
}
public int getRecordSize() {
int size = 0;
Iterator irecs = records.values().iterator();
while (irecs.hasNext()) {
size += (( Record ) irecs.next()).getRecordSize();
} }
return size;
// return size;
} }
public Iterator getIterator() private void adjustIntList(IntList list, int size) {
{ while (list.size() < size) {
return records.values().iterator(); list.add(-1);
}
} }
/** Performs a deep clone of the record*/ private void adjustDoubleList(DoubleList list, int size) {
public Object clone() { while (list.size() < size) {
ValueRecordsAggregate rec = new ValueRecordsAggregate(); list.add(-1);
for (Iterator valIter = getIterator(); valIter.hasNext();) { }
CellValueRecordInterface val = (CellValueRecordInterface)((CellValueRecordInterface)valIter.next()).clone();
rec.insertCell(val);
}
return rec;
} }
private void adjustObjectList(List list, int size) {
while (list.size() < size) {
list.add(new ArrayList());
}
}
private void adjustStringList(List list, int size) {
while (list.size() < size) {
list.add(new String());
}
}
protected int findNextPopulatedCell(int row, int col) {
IntList ctRow = (IntList) celltype.get(row);
int retval = -1;
if (ctRow.size() > col+1) {
for (int k = col+1; k < ctRow.size() +1; k++) {
if (k != ctRow.size()) {
int val = ctRow.get(k);
if (val != -1) {
retval = k;
break;
} // end if (val !=...
} //end if (k !=..
} //end for
} //end if (ctRow.size()...
return retval;
}
public short getSid() {
return sid;
}
public void fillFields(byte[] data, short size, int offset) {
}
protected void validateSid(short sid) {
}
} }
/* class VRAIterator implements Iterator {
* class XYLocator implements Comparable { private boolean hasNext;
* private int row = 0; private ValueRecordsAggregate vra;
* private int col = 0; int popindex;
* public XYLocator(int row, int col) { int row;
* this.row = row; int rowlimit;
* this.col = col; int col;
* } CellValueRecordInterface current = null;
* CellValueRecordInterface next = null;
* public int getRow() {
* return row; public VRAIterator(ValueRecordsAggregate vra) {
* } this.vra = vra;
* this.rowlimit = -1;
* public int getCol() { popindex = 0;
* return col; if (vra.getPhysicalNumberOfCells() > 0) {
* } hasNext = true;
* next = findNextCell(null);
* public int compareTo(Object obj) { }
* XYLocator loc = (XYLocator)obj; }
*
* if (this.getRow() == loc.getRow() && public VRAIterator(ValueRecordsAggregate vra, int row) {
* this.getCol() == loc.getCol() ) this(vra);
* return 0; rowlimit = row;
* this.row = row;
* if (this.getRow() < loc.getRow()) this.popindex = vra.populatedRows.indexOf(row);
* return -1; }
*
* if (this.getRow() > loc.getRow()) public boolean hasNext() {
* return 1; return hasNext;
* }
* if (this.getCol() < loc.getCol())
* return -1; public Object next() {
* current = next;
* if (this.getCol() > loc.getCol()) next = findNextCell(current);
* return 1; if (next == null) {
* hasNext = false;
* return -1; }
* return current;
* } }
*
* public boolean equals(Object obj) { public void remove() {
* if (!(obj instanceof XYLocator)) return false; vra.removeCell(current);
* }
* XYLocator loc = (XYLocator)obj;
* if (this.getRow() == loc.getRow() private CellValueRecordInterface findNextCell(CellValueRecordInterface current) {
* && IntList ctRow = null;
* this.getCol() == loc.getCol() int rowNum = -1;
* ) return true; int colNum = -1;
* return false; int newCol = -1;
* } boolean wasntFirst = false;
*
* if (current != null) {
* } wasntFirst = true;
*/ rowNum = current.getRow();
colNum = current.getColumn();
ctRow = ((IntList)vra.celltype.get(rowNum));
}
//if popindex = row iwth no cells, fast forward till we get to one with size > 0
while ((ctRow == null || ctRow.size() == 0) && vra.populatedRows.size() > popindex) {
if (wasntFirst == true) {
throw new RuntimeException("CANT HAPPEN WASNTFIRST BUT WE'RE FASTFORWARDING!");
}
rowNum = vra.populatedRows.get(popindex);
ctRow = (IntList)vra.celltype.get(rowNum);
if (ctRow.size() == 0) {
if (rowlimit == -1) {
popindex++;
} else {
this.hasNext = false;
}
}
}
if (rowNum == -1) {
return null;
}
while (newCol == -1) {
newCol = findNextPopulatedCell(rowNum,colNum);
colNum = newCol;
if (colNum == -1) { //end of row, forward one row
popindex++;
if (popindex < vra.populatedRows.size() && rowlimit == -1) {
rowNum = vra.populatedRows.get(popindex);
} else {
return null;
}
}
}
return vra.constructRecord(rowNum,colNum);
}
private int findNextPopulatedCell(int row, int col) {
/*IntList ctRow = (IntList) vra.celltype.get(row);
int retval = -1;
if (ctRow.size() > col+1) {
for (int k = col+1; k < ctRow.size() +1; k++) {
if (k != ctRow.size()) {
int val = ctRow.get(k);
if (val != -1) {
retval = k;
break;
} // end if (val !=...
} //end if (k !=..
} //end for
} //end if (ctRow.size()...
return retval;*/
return vra.findNextPopulatedCell(row, col);
}
}

View File

@ -163,7 +163,7 @@ public class HSSFCell
private Sheet sheet; private Sheet sheet;
//private short row; //private short row;
private int row; private int row;
private CellValueRecordInterface record; // private CellValueRecordInterface record;
/** /**
* Creates new Cell - Should only be called by HSSFRow. This creates a cell * Creates new Cell - Should only be called by HSSFRow. This creates a cell
@ -196,13 +196,25 @@ public class HSSFCell
this.book = book; this.book = book;
this.sheet = sheet; this.sheet = sheet;
BlankRecord rec = new BlankRecord();
rec.setRow(row);
rec.setColumn(cellNum);
rec.setXFIndex((short)0xf);
cellType = HSSFCell.CELL_TYPE_BLANK;
sheet.addValueRecord(row,(CellValueRecordInterface)rec);
// Relying on the fact that by default the cellType is set to 0 which // Relying on the fact that by default the cellType is set to 0 which
// is different to CELL_TYPE_BLANK hence the following method call correctly // is different to CELL_TYPE_BLANK hence the following method call correctly
// creates a new blank cell. // creates a new blank cell.
setCellType(CELL_TYPE_BLANK, false); //setCellType(CELL_TYPE_BLANK, false);
ExtendedFormatRecord xf = book.getExFormatAt(0xf);
//ExtendedFormatRecord xf = book.getExFormatAt(0xf);
//setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
} }
/** /**
@ -236,7 +248,7 @@ public class HSSFCell
errorValue = ( byte ) 0; errorValue = ( byte ) 0;
this.book = book; this.book = book;
this.sheet = sheet; this.sheet = sheet;
switch (type) /* switch (type)
{ {
case CELL_TYPE_NUMERIC : case CELL_TYPE_NUMERIC :
@ -285,7 +297,7 @@ public class HSSFCell
} }
ExtendedFormatRecord xf = book.getExFormatAt(0xf); ExtendedFormatRecord xf = book.getExFormatAt(0xf);
setCellStyle(new HSSFCellStyle(( short ) 0xf, xf)); setCellStyle(new HSSFCellStyle(( short ) 0xf, xf)); */
} }
/** /**
@ -302,7 +314,7 @@ public class HSSFCell
CellValueRecordInterface cval) CellValueRecordInterface cval)
{ {
cellNum = cval.getColumn(); cellNum = cval.getColumn();
record = cval; //record = cval;
this.row = row; this.row = row;
cellType = determineType(cval); cellType = determineType(cval);
cellStyle = null; cellStyle = null;
@ -394,8 +406,14 @@ public class HSSFCell
public void setCellNum(short num) public void setCellNum(short num)
{ {
CellValueRecordInterface cval = sheet.getValueRecord(row, cellNum);
if (cval != null) {
sheet.removeValueRecord(this.row, cval);
}
cellNum = num; cellNum = num;
record.setColumn(num); sheet.addValueRecord(row, cval);
//record.setColumn(num);
} }
/** /**
@ -457,16 +475,16 @@ public class HSSFCell
} }
else else
{ {
frec = ( FormulaRecordAggregate ) record; frec = (FormulaRecordAggregate)sheet.getValueRecord(row, cellNum);
} }
frec.setColumn(getCellNum()); frec.setColumn(getCellNum());
if (setValue) if (setValue)
{ {
frec.getFormulaRecord().setValue(getNumericCellValue()); frec.getFormulaRecord().setValue(getNumericCellValue());
} }
frec.setXFIndex(( short ) cellStyle.getIndex()); // frec.setXFIndex(( short ) cellStyle.getIndex());
frec.setRow(row); frec.setRow(row);
record = frec; sheet.replaceValueRecord(frec);
break; break;
case CELL_TYPE_NUMERIC : case CELL_TYPE_NUMERIC :
@ -478,16 +496,16 @@ public class HSSFCell
} }
else else
{ {
nrec = ( NumberRecord ) record; nrec = ( NumberRecord ) sheet.getValueRecord(row, cellNum);
} }
nrec.setColumn(getCellNum()); nrec.setColumn(getCellNum());
if (setValue) if (setValue)
{ {
nrec.setValue(getNumericCellValue()); nrec.setValue(getNumericCellValue());
} }
nrec.setXFIndex(( short ) cellStyle.getIndex()); nrec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex());
nrec.setRow(row); nrec.setRow(row);
record = nrec; sheet.replaceValueRecord(nrec);
break; break;
case CELL_TYPE_STRING : case CELL_TYPE_STRING :
@ -499,11 +517,11 @@ public class HSSFCell
} }
else else
{ {
lrec = ( LabelSSTRecord ) record; lrec = ( LabelSSTRecord ) sheet.getValueRecord(row, cellNum);
} }
lrec.setColumn(getCellNum()); lrec.setColumn(getCellNum());
lrec.setRow(row); lrec.setRow(row);
lrec.setXFIndex(( short ) cellStyle.getIndex()); lrec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex());
if (setValue) if (setValue)
{ {
if ((getStringCellValue() != null) if ((getStringCellValue() != null)
@ -523,7 +541,7 @@ public class HSSFCell
lrec.setSSTIndex(sst); lrec.setSSTIndex(sst);
} }
} }
record = lrec; sheet.replaceValueRecord(lrec);
break; break;
case CELL_TYPE_BLANK : case CELL_TYPE_BLANK :
@ -535,21 +553,21 @@ public class HSSFCell
} }
else else
{ {
brec = ( BlankRecord ) record; brec = ( BlankRecord ) sheet.getValueRecord(row, cellNum);
} }
brec.setColumn(getCellNum()); brec.setColumn(getCellNum());
// During construction the cellStyle may be null for a Blank cell. // During construction the cellStyle may be null for a Blank cell.
if (cellStyle != null) if (cellStyle != null)
{ {
brec.setXFIndex(( short ) cellStyle.getIndex()); brec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex());
} }
else else
{ {
brec.setXFIndex(( short ) 0); brec.setXFIndex(( short ) 0);
} }
brec.setRow(row); brec.setRow(row);
record = brec; sheet.replaceValueRecord(brec);
break; break;
case CELL_TYPE_BOOLEAN : case CELL_TYPE_BOOLEAN :
@ -561,7 +579,7 @@ public class HSSFCell
} }
else else
{ {
boolRec = ( BoolErrRecord ) record; boolRec = ( BoolErrRecord ) sheet.getValueRecord(row, cellNum);
} }
boolRec.setColumn(getCellNum()); boolRec.setColumn(getCellNum());
if (setValue) if (setValue)
@ -570,7 +588,7 @@ public class HSSFCell
} }
boolRec.setXFIndex(( short ) cellStyle.getIndex()); boolRec.setXFIndex(( short ) cellStyle.getIndex());
boolRec.setRow(row); boolRec.setRow(row);
record = boolRec; sheet.replaceValueRecord(boolRec);
break; break;
case CELL_TYPE_ERROR : case CELL_TYPE_ERROR :
@ -582,7 +600,7 @@ public class HSSFCell
} }
else else
{ {
errRec = ( BoolErrRecord ) record; errRec = ( BoolErrRecord ) sheet.getValueRecord(row, cellNum);
} }
errRec.setColumn(getCellNum()); errRec.setColumn(getCellNum());
if (setValue) if (setValue)
@ -591,16 +609,17 @@ public class HSSFCell
} }
errRec.setXFIndex(( short ) cellStyle.getIndex()); errRec.setXFIndex(( short ) cellStyle.getIndex());
errRec.setRow(row); errRec.setRow(row);
record = errRec; sheet.replaceValueRecord(errRec);
break; break;
} }
if (cellType != this.cellType) if (cellType != this.cellType)
{ {
int loc = sheet.getLoc(); int loc = sheet.getLoc();
sheet.replaceValueRecord(record); //sheet.replaceValueRecord(record);
sheet.setLoc(loc); sheet.setLoc(loc);
} }
//sheet.setCellType(this.row, this.cellNum);
this.cellType = cellType; this.cellType = cellType;
} }
@ -631,7 +650,7 @@ public class HSSFCell
{ {
setCellType(CELL_TYPE_NUMERIC, false); setCellType(CELL_TYPE_NUMERIC, false);
} }
(( NumberRecord ) record).setValue(value); sheet.setCellValue(row, cellNum, value);
cellValue = value; cellValue = value;
} }
@ -693,7 +712,7 @@ public class HSSFCell
{ {
index = book.addSSTString(value, true); index = book.addSSTString(value, true);
} }
(( LabelSSTRecord ) record).setSSTIndex(index); sheet.setCellValue(row, cellNum, index);
stringValue = value; stringValue = value;
} }
} }
@ -704,12 +723,12 @@ public class HSSFCell
setCellType(CELL_TYPE_BLANK,false); setCellType(CELL_TYPE_BLANK,false);
} else { } else {
setCellType(CELL_TYPE_FORMULA,false); setCellType(CELL_TYPE_FORMULA,false);
FormulaRecordAggregate rec = (FormulaRecordAggregate) record; FormulaRecordAggregate rec = new FormulaRecordAggregate(new FormulaRecord(), null);
rec.getFormulaRecord().setOptions(( short ) 2); rec.getFormulaRecord().setOptions(( short ) 2);
rec.getFormulaRecord().setValue(0); rec.getFormulaRecord().setValue(0);
rec.setRow(row);
//only set to default if there is no extended format index already set rec.setColumn(cellNum);
if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f); rec.setXFIndex(( short ) 0x0f);
FormulaParser fp = new FormulaParser(formula+";",book); FormulaParser fp = new FormulaParser(formula+";",book);
fp.parse(); fp.parse();
Ptg[] ptg = fp.getRPNPtg(); Ptg[] ptg = fp.getRPNPtg();
@ -720,6 +739,9 @@ public class HSSFCell
rec.getFormulaRecord().pushExpressionToken(ptg[ k ]); rec.getFormulaRecord().pushExpressionToken(ptg[ k ]);
} }
rec.getFormulaRecord().setExpressionLength(( short ) size); rec.getFormulaRecord().setExpressionLength(( short ) size);
sheet.replaceValueRecord(rec);
//sheet.setCellFormula(row, cellNum, options, value
//Workbook.currentBook = null; //Workbook.currentBook = null;
} }
} }
@ -727,7 +749,8 @@ public class HSSFCell
public String getCellFormula() { public String getCellFormula() {
//Workbook.currentBook=book; //Workbook.currentBook=book;
SheetReferences refs = book.getSheetReferences(); SheetReferences refs = book.getSheetReferences();
String retval = FormulaParser.toFormulaString(refs, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression()); String retval = FormulaParser.toFormulaString(refs,
((FormulaRecordAggregate)sheet.getValueRecord(row,cellNum)).getFormulaRecord().getParsedExpression());
//Workbook.currentBook=null; //Workbook.currentBook=null;
return retval; return retval;
} }
@ -834,12 +857,12 @@ public class HSSFCell
public void setCellValue(boolean value) public void setCellValue(boolean value)
{ {
if ((cellType != CELL_TYPE_BOOLEAN ) && ( cellType != CELL_TYPE_FORMULA)) /*if ((cellType != CELL_TYPE_BOOLEAN ) && ( cellType != CELL_TYPE_FORMULA))
{ {
setCellType(CELL_TYPE_BOOLEAN, false); setCellType(CELL_TYPE_BOOLEAN, false);
} }
(( BoolErrRecord ) record).setValue(value); (( BoolErrRecord ) record).setValue(value);
booleanValue = value; booleanValue = value; */
} }
/** /**
@ -853,11 +876,11 @@ public class HSSFCell
public void setCellErrorValue(byte value) public void setCellErrorValue(byte value)
{ {
if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA)) /*if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA))
{ {
setCellType(CELL_TYPE_ERROR, false); setCellType(CELL_TYPE_ERROR, false);
} }
(( BoolErrRecord ) record).setValue(value); (( BoolErrRecord ) record).setValue(value);*/
errorValue = value; errorValue = value;
} }
@ -911,7 +934,8 @@ public class HSSFCell
public void setCellStyle(HSSFCellStyle style) public void setCellStyle(HSSFCellStyle style)
{ {
cellStyle = style; cellStyle = style;
record.setXFIndex(style.getIndex());
sheet.setCellStyle(row, cellNum, style.getIndex());
} }
/** /**
@ -961,7 +985,7 @@ public class HSSFCell
protected CellValueRecordInterface getCellValueRecord() protected CellValueRecordInterface getCellValueRecord()
{ {
return record; return sheet.getValueRecord(row, cellNum);
} }
/** /**
@ -976,6 +1000,7 @@ public class HSSFCell
throw new RuntimeException("You cannot reference columns with an index of less then 0."); throw new RuntimeException("You cannot reference columns with an index of less then 0.");
} }
} }
/** /**
* Sets this cell as the active cell for the worksheet * Sets this cell as the active cell for the worksheet
@ -985,4 +1010,5 @@ public class HSSFCell
this.sheet.setActiveCellRow(this.row); this.sheet.setActiveCellRow(this.row);
this.sheet.setActiveCellCol(this.cellNum); this.sheet.setActiveCellCol(this.cellNum);
} }
} }

View File

@ -63,6 +63,7 @@ import org.apache.poi.hssf.model.Sheet;
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.RowRecord; import org.apache.poi.hssf.record.RowRecord;
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -84,7 +85,7 @@ public class HSSFRow
public final static int INITIAL_CAPACITY = 5; public final static int INITIAL_CAPACITY = 5;
//private short rowNum; //private short rowNum;
private int rowNum; private int rowNum;
private HashMap cells; //private ValueRecordsAggregate cells;
// private short firstcell = -1; // private short firstcell = -1;
// private short lastcell = -1; // private short lastcell = -1;
@ -92,7 +93,7 @@ public class HSSFRow
* reference to low level representation * reference to low level representation
*/ */
private RowRecord row; //private RowRecord row;
/** /**
* reference to containing low level Workbook * reference to containing low level Workbook
@ -123,16 +124,16 @@ public class HSSFRow
protected HSSFRow(Workbook book, Sheet sheet, int rowNum) protected HSSFRow(Workbook book, Sheet sheet, int rowNum)
{ {
this.rowNum = rowNum; this.rowNum = rowNum;
cells = new HashMap(10); // new ArrayList(INITIAL_CAPACITY); //cells = new HashMap(10); // new ArrayList(INITIAL_CAPACITY);
this.book = book; this.book = book;
this.sheet = sheet; this.sheet = sheet;
row = new RowRecord(); //row = new RowRecord();
row.setHeight((short) 0xff); //row.setHeight((short) 0xff);
row.setLastCol((short) -1); //row.setLastCol((short) -1);
row.setFirstCol((short) -1); //row.setFirstCol((short) -1);
// row.setRowNumber(rowNum); // row.setRowNumber(rowNum);
setRowNum(rowNum); //setRowNum(rowNum);
} }
/** /**
@ -148,10 +149,10 @@ public class HSSFRow
protected HSSFRow(Workbook book, Sheet sheet, RowRecord record) protected HSSFRow(Workbook book, Sheet sheet, RowRecord record)
{ {
//this.rowNum = rowNum; //this.rowNum = rowNum;
cells = new HashMap(); // ArrayList(INITIAL_CAPACITY); //cells = new HashMap(); // ArrayList(INITIAL_CAPACITY);
this.book = book; this.book = book;
this.sheet = sheet; this.sheet = sheet;
row = record; //row = record;
// row.setHeight(record.getHeight()); // row.setHeight(record.getHeight());
// row.setRowNumber(rowNum); // row.setRowNumber(rowNum);
@ -175,8 +176,8 @@ public class HSSFRow
{ {
HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), column); HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), column);
addCell(cell); //addCell(cell);
sheet.addValueRecord(getRowNum(), cell.getCellValueRecord()); //sheet.addValueRecord(getRowNum(), cell.getCellValueRecord());
return cell; return cell;
} }
@ -211,15 +212,15 @@ public class HSSFRow
CellValueRecordInterface cval = cell.getCellValueRecord(); CellValueRecordInterface cval = cell.getCellValueRecord();
sheet.removeValueRecord(getRowNum(), cval); sheet.removeValueRecord(getRowNum(), cval);
cells.remove(new Integer(cell.getCellNum())); //cells.remove(new Integer(cell.getCellNum()));
if (cell.getCellNum() == row.getLastCol()) if (cell.getCellNum() == getLastCol(rowNum))
{ {
row.setLastCol(findLastCell(row.getLastCol())); sheet.getRow(rowNum).setLastCol(findLastCell(sheet.getRow(rowNum).getLastCol()));
} }
if (cell.getCellNum() == row.getFirstCol()) if (cell.getCellNum() == getFirstCol(rowNum))
{ {
row.setFirstCol(findFirstCell(row.getFirstCol())); setFirstCol(findFirstCell(getFirstCol(rowNum)));
} }
} }
@ -236,7 +237,7 @@ public class HSSFRow
addCell(hcell); addCell(hcell);
// sheet.addValueRecord(getRowNum(),cell.getCellValueRecord()); sheet.addValueRecord(getRowNum(),cell);
return hcell; return hcell;
} }
@ -249,10 +250,10 @@ public class HSSFRow
public void setRowNum(int rowNum) public void setRowNum(int rowNum)
{ {
this.rowNum = rowNum; this.rowNum = rowNum;
if (row != null) //if (row != null)
{ //{
row.setRowNumber(rowNum); // used only for KEY comparison (HSSFRow) // row.setRowNumber(rowNum); // used only for KEY comparison (HSSFRow)
} //}
} }
/** /**
@ -272,26 +273,44 @@ public class HSSFRow
private void addCell(HSSFCell cell) private void addCell(HSSFCell cell)
{ {
if (row.getFirstCol() == -1) if (getFirstCol(rowNum) == -1)
{ {
row.setFirstCol(cell.getCellNum()); setFirstCol(cell.getCellNum());
} }
if (row.getLastCol() == -1) if (getLastCol(rowNum) == -1)
{ {
row.setLastCol(cell.getCellNum()); setLastCol(cell.getCellNum());
} }
cells.put(new Integer(cell.getCellNum()), cell); //cells.put(new Integer(cell.getCellNum()), cell);
sheet.addValueRecord(this.rowNum, cell.getCellValueRecord());
if (cell.getCellNum() < row.getFirstCol()) if (cell.getCellNum() < getFirstCol(rowNum))
{ {
row.setFirstCol(cell.getCellNum()); setFirstCol(cell.getCellNum());
} }
if (cell.getCellNum() > row.getLastCol()) if (cell.getCellNum() > getLastCol(rowNum))
{ {
row.setLastCol(cell.getCellNum()); setLastCol(cell.getCellNum());
} }
} }
private void setLastCol(short cell) {
sheet.setLastColForRow(rowNum, cell);
}
private void setFirstCol(short cell) {
sheet.setFirstColForRow(rowNum, cell);
}
private short getLastCol(int row) {
return sheet.getLastColForRow(row);
}
private short getFirstCol(int row) {
return sheet.getFirstColForRow(row);
}
/** /**
* get the hssfcell representing a given column (logical cell) 0-based. If you * get the hssfcell representing a given column (logical cell) 0-based. If you
* ask for a cell that is not defined....you get a null. * ask for a cell that is not defined....you get a null.
@ -302,6 +321,11 @@ public class HSSFRow
public HSSFCell getCell(short cellnum) public HSSFCell getCell(short cellnum)
{ {
HSSFCell retval = null;
CellValueRecordInterface cval = sheet.getValueRecord(rowNum, cellnum);
if (cval != null) {
retval = new HSSFCell(book, sheet, rowNum, cval);
}
/* for (int k = 0; k < cells.size(); k++) /* for (int k = 0; k < cells.size(); k++)
{ {
@ -312,7 +336,7 @@ public class HSSFRow
return cell; return cell;
} }
}*/ }*/
return (HSSFCell) cells.get(new Integer(cellnum)); return retval;
} }
/** /**
@ -325,7 +349,7 @@ public class HSSFRow
if (getPhysicalNumberOfCells() == 0) if (getPhysicalNumberOfCells() == 0)
return -1; return -1;
else else
return row.getFirstCol(); return getFirstCol(rowNum);
} }
/** /**
@ -338,7 +362,7 @@ public class HSSFRow
if (getPhysicalNumberOfCells() == 0) if (getPhysicalNumberOfCells() == 0)
return -1; return -1;
else else
return row.getLastCol(); return getLastCol(rowNum);
} }
@ -350,11 +374,13 @@ public class HSSFRow
public int getPhysicalNumberOfCells() public int getPhysicalNumberOfCells()
{ {
if (cells == null) // sheet.get
{ // if (cells == null)
return 0; // shouldn't be possible but it is due to missing API support for BLANK/MULBLANK // {
} // return 0; // shouldn't be possible but it is due to missing API support for BLANK/MULBLANK
return cells.size(); // }
// return cells.size();
return sheet.getPhysicalNumberOfRows();
} }
/** /**
@ -367,8 +393,8 @@ public class HSSFRow
{ {
// row.setOptionFlags( // row.setOptionFlags(
row.setBadFontHeight(true); sheet.getRow(rowNum).setBadFontHeight(true);
row.setHeight(height); sheet.getRow(rowNum).setHeight(height);
} }
/** /**
@ -380,8 +406,8 @@ public class HSSFRow
{ {
// row.setOptionFlags( // row.setOptionFlags(
row.setBadFontHeight(true); sheet.getRow(rowNum).setBadFontHeight(true);
row.setHeight((short) (height * 20)); sheet.getRow(rowNum).setHeight((short) (height * 20));
} }
/** /**
@ -391,7 +417,7 @@ public class HSSFRow
public short getHeight() public short getHeight()
{ {
return row.getHeight(); return sheet.getRow(rowNum).getHeight();
} }
/** /**
@ -401,7 +427,7 @@ public class HSSFRow
public float getHeightInPoints() public float getHeightInPoints()
{ {
return (row.getHeight() / 20); return (sheet.getRow(rowNum).getHeight() / 20);
} }
/** /**
@ -413,7 +439,7 @@ public class HSSFRow
protected RowRecord getRowRecord() protected RowRecord getRowRecord()
{ {
return row; return sheet.getRow(rowNum);
} }
/** /**
@ -457,7 +483,7 @@ public class HSSFRow
public Iterator cellIterator() public Iterator cellIterator()
{ {
return cells.values().iterator(); return new RowCellIterator(this.book, this.sheet, this.rowNum);
} }
public int compareTo(Object obj) public int compareTo(Object obj)
@ -494,3 +520,36 @@ public class HSSFRow
return false; return false;
} }
} }
class RowCellIterator implements Iterator {
Iterator cells;
Workbook book;
Sheet sheet;
int row;
public RowCellIterator(Workbook book, Sheet sheet, int row) {
this.sheet = sheet;
this.book = book;
this.row = row;
cells = this.sheet.rowCellIterator(row);
}
public boolean hasNext() {
return cells.hasNext();
}
public Object next() {
HSSFCell retval = null;
if (cells.hasNext()) {
retval = new HSSFCell(book, sheet, row, ((CellValueRecordInterface)cells.next()));
}
return retval;
}
public void remove() {
cells.remove();
}
}

View File

@ -62,13 +62,11 @@ package org.apache.poi.hssf.usermodel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.TreeMap;
import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Sheet;
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.HCenterRecord; import org.apache.poi.hssf.record.HCenterRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RowRecord; import org.apache.poi.hssf.record.RowRecord;
import org.apache.poi.hssf.record.SCLRecord; import org.apache.poi.hssf.record.SCLRecord;
import org.apache.poi.hssf.record.VCenterRecord; import org.apache.poi.hssf.record.VCenterRecord;
@ -115,7 +113,9 @@ public class HSSFSheet
*/ */
private Sheet sheet; private Sheet sheet;
private TreeMap rows; // private TreeMap rows;
// private RowRecordsAggregate rows;
// private ValueRecordsAggregate vra;
private Workbook book; private Workbook book;
private int firstrow; private int firstrow;
private int lastrow; private int lastrow;
@ -132,7 +132,7 @@ public class HSSFSheet
protected HSSFSheet(Workbook book) protected HSSFSheet(Workbook book)
{ {
sheet = Sheet.createSheet(); sheet = Sheet.createSheet();
rows = new TreeMap(); // new ArrayList(INITIAL_CAPACITY); //rows = new TreeMap(); // new ArrayList(INITIAL_CAPACITY);
this.book = book; this.book = book;
} }
@ -148,7 +148,7 @@ public class HSSFSheet
protected HSSFSheet(Workbook book, Sheet sheet) protected HSSFSheet(Workbook book, Sheet sheet)
{ {
this.sheet = sheet; this.sheet = sheet;
rows = new TreeMap(); //rows = new TreeMap();
this.book = book; this.book = book;
setPropertiesFromSheet(sheet); setPropertiesFromSheet(sheet);
} }
@ -164,7 +164,7 @@ public class HSSFSheet
private void setPropertiesFromSheet(Sheet sheet) private void setPropertiesFromSheet(Sheet sheet)
{ {
int sloc = sheet.getLoc(); /* int sloc = sheet.getLoc();
RowRecord row = sheet.getNextRow(); RowRecord row = sheet.getNextRow();
while (row != null) while (row != null)
@ -173,7 +173,9 @@ public class HSSFSheet
row = sheet.getNextRow(); row = sheet.getNextRow();
} }
sheet.setLoc(sloc); sheet.setLoc(sloc);*/
/*
CellValueRecordInterface cval = sheet.getNextValueRecord(); CellValueRecordInterface cval = sheet.getNextValueRecord();
long timestart = System.currentTimeMillis(); long timestart = System.currentTimeMillis();
@ -204,8 +206,9 @@ public class HSSFSheet
cval = null; cval = null;
} }
} }
log.log(DEBUG, "total sheet cell creation took ", */
new Long(System.currentTimeMillis() - timestart)); // log.log(DEBUG, "total sheet cell creation took ",
// new Long(System.currentTimeMillis() - timestart));
} }
/** /**
@ -233,13 +236,13 @@ public class HSSFSheet
* @return HSSFRow high level representation * @return HSSFRow high level representation
*/ */
private HSSFRow createRowFromRecord(RowRecord row) /* private HSSFRow createRowFromRecord(RowRecord row)
{ {
HSSFRow hrow = new HSSFRow(book, sheet, row); HSSFRow hrow = new HSSFRow(book, sheet, row);
addRow(hrow, false); addRow(hrow, false);
return hrow; return hrow;
} }*/
/** /**
* Remove a row from this sheet. All cells contained in the row are removed as well * Remove a row from this sheet. All cells contained in the row are removed as well
@ -250,35 +253,35 @@ public class HSSFSheet
public void removeRow(HSSFRow row) public void removeRow(HSSFRow row)
{ {
sheet.setLoc(sheet.getDimsLoc()); sheet.setLoc(sheet.getDimsLoc());
if (rows.size() > 0) // if (rows.size() > 0)
{ // {
rows.remove(row); // rows.remove(row);
if (row.getRowNum() == getLastRowNum()) // if (row.getRowNum() == getLastRowNum())
{ // {
lastrow = findLastRow(lastrow); // lastrow = findLastRow(lastrow);
} // }
if (row.getRowNum() == getFirstRowNum()) // if (row.getRowNum() == getFirstRowNum())
{ // {
firstrow = findFirstRow(firstrow); // firstrow = findFirstRow(firstrow);
} // }
Iterator iter = row.cellIterator(); //Iterator iter = row.cellIterator();
while (iter.hasNext()) /* while (iter.hasNext())
{ {
HSSFCell cell = (HSSFCell) iter.next(); HSSFCell cell = (HSSFCell) iter.next();
sheet.removeValueRecord(row.getRowNum(), sheet.removeValueRecord(row.getRowNum(),
cell.getCellValueRecord()); cell.getCellValueRecord());
} }*/
sheet.removeRow(row.getRowRecord()); sheet.removeRow(row.getRowRecord());
} //}
} }
/** /**
* used internally to refresh the "last row" when the last row is removed. * used internally to refresh the "last row" when the last row is removed.
*/ */
private int findLastRow(int lastrow) /* private int findLastRow(int lastrow)
{ {
int rownum = lastrow - 1; int rownum = lastrow - 1;
HSSFRow r = getRow(rownum); HSSFRow r = getRow(rownum);
@ -288,13 +291,13 @@ public class HSSFSheet
r = getRow(--rownum); r = getRow(--rownum);
} }
return rownum; return rownum;
} }*/
/** /**
* used internally to refresh the "first row" when the first row is removed. * used internally to refresh the "first row" when the first row is removed.
*/ */
private int findFirstRow(int firstrow) /*private int findFirstRow(int firstrow)
{ {
int rownum = firstrow + 1; int rownum = firstrow + 1;
HSSFRow r = getRow(rownum); HSSFRow r = getRow(rownum);
@ -308,7 +311,7 @@ public class HSSFSheet
return -1; return -1;
return rownum; return rownum;
} } */
/** /**
* add a row to the sheet * add a row to the sheet
@ -318,19 +321,22 @@ public class HSSFSheet
private void addRow(HSSFRow row, boolean addLow) private void addRow(HSSFRow row, boolean addLow)
{ {
rows.put(row, row); //rows.put(row, row);
if (addLow) if (addLow) {
{ RowRecord rec = sheet.getRow(row.getRowNum());
sheet.addRow(row.getRowRecord()); if (rec == null) {
rec = new RowRecord();
sheet.addRow(sheet.createRow(row.getRowNum()));
}
} }
if (row.getRowNum() > getLastRowNum()) /* if (row.getRowNum() > getLastRowNum())
{ {
lastrow = row.getRowNum(); lastrow = row.getRowNum();
} }
if (row.getRowNum() < getFirstRowNum()) if (row.getRowNum() < getFirstRowNum())
{ {
firstrow = row.getRowNum(); firstrow = row.getRowNum();
} }*/
} }
/** /**
@ -342,11 +348,9 @@ public class HSSFSheet
public HSSFRow getRow(int rownum) public HSSFRow getRow(int rownum)
{ {
HSSFRow row = new HSSFRow(); HSSFRow retval = new HSSFRow(book, sheet, this.sheet.getRow(rownum));
//row.setRowNum((short) rownum); return retval;
row.setRowNum( rownum);
return (HSSFRow) rows.get(row);
} }
/** /**
@ -355,7 +359,7 @@ public class HSSFSheet
public int getPhysicalNumberOfRows() public int getPhysicalNumberOfRows()
{ {
return rows.size(); return sheet.getPhysicalNumberOfRows();
} }
/** /**
@ -365,7 +369,7 @@ public class HSSFSheet
public int getFirstRowNum() public int getFirstRowNum()
{ {
return firstrow; return sheet.getFirstRow();
} }
/** /**
@ -375,7 +379,7 @@ public class HSSFSheet
public int getLastRowNum() public int getLastRowNum()
{ {
return lastrow; return sheet.getLastRow();
} }
/** /**
@ -592,7 +596,7 @@ public class HSSFSheet
public Iterator rowIterator() public Iterator rowIterator()
{ {
return rows.values().iterator(); return new SheetRowIterator(this, this.book);
} }
/** /**
@ -813,66 +817,60 @@ public class HSSFSheet
* @param newPrintGridlines boolean to turn on or off the printing of * @param newPrintGridlines boolean to turn on or off the printing of
* gridlines * gridlines
*/ */
public void setPrintGridlines( boolean newPrintGridlines ) public void setPrintGridlines(boolean newPrintGridlines) {
{ getSheet().getPrintGridlines().setPrintGridlines(newPrintGridlines);
getSheet().getPrintGridlines().setPrintGridlines( newPrintGridlines );
} }
/** /**
* Gets the print setup object. * Gets the print setup object.
* @return The user model for the print setup object. * @return The user model for the print setup object.
*/ */
public HSSFPrintSetup getPrintSetup() public HSSFPrintSetup getPrintSetup() {
{ return new HSSFPrintSetup(getSheet().getPrintSetup());
return new HSSFPrintSetup( getSheet().getPrintSetup() );
} }
/** /**
* Gets the user model for the document header. * Gets the user model for the document header.
* @return The Document header. * @return The Document header.
*/ */
public HSSFHeader getHeader() public HSSFHeader getHeader() {
{ return new HSSFHeader(getSheet().getHeader());
return new HSSFHeader( getSheet().getHeader() );
} }
/** /**
* Gets the user model for the document footer. * Gets the user model for the document footer.
* @return The Document footer. * @return The Document footer.
*/ */
public HSSFFooter getFooter() public HSSFFooter getFooter() {
{ return new HSSFFooter(getSheet().getFooter());
return new HSSFFooter( getSheet().getFooter() ); }
}
/** /**
* Sets whether sheet is selected. * Sets whether sheet is selected.
* @param sel Whether to select the sheet or deselect the sheet. * @param sel Whether to select the sheet or deselect the sheet.
*/ */
public void setSelected( boolean sel ) public void setSelected(boolean sel) {
{ getSheet().setSelected(sel);
getSheet().setSelected( sel ); }
}
/** /**
* Gets the size of the margin in inches. * Gets the size of the margin in inches.
* @param margin which margin to get * @param margin which margin to get
* @return the size of the margin * @return the size of the margin
*/ */
public double getMargin( short margin ) public double getMargin(short margin) {
{ return getSheet().getMargin(margin);
return getSheet().getMargin( margin ); }
}
/**
* Sets the size of the margin in inches.
* @param margin which margin to get
* @param size the size of the margin
*/
public void setMargin(short margin, double size) {
getSheet().setMargin(margin, size);
}
/**
* Sets the size of the margin in inches.
* @param margin which margin to get
* @param size the size of the margin
*/
public void setMargin( short margin, double size )
{
getSheet().setMargin( margin, size );
}
/** /**
* Sets the zoom magnication for the sheet. The zoom is expressed as a * Sets the zoom magnication for the sheet. The zoom is expressed as a
@ -903,7 +901,7 @@ public class HSSFSheet
* @param endRow * @param endRow
* @param n * @param n
* @param isRow * @param isRow
*/ */
protected void shiftMerged(int startRow, int endRow, int n, boolean isRow) { protected void shiftMerged(int startRow, int endRow, int n, boolean isRow) {
List shiftedRegions = new ArrayList(); List shiftedRegions = new ArrayList();
//move merged regions completely if they fall within the new region boundaries when they are shifted //move merged regions completely if they fall within the new region boundaries when they are shifted
@ -1087,3 +1085,33 @@ public class HSSFSheet
} }
class SheetRowIterator implements Iterator {
Iterator rows;
Workbook book;
Sheet sheet;
public SheetRowIterator(HSSFSheet sheet, Workbook book) {
this.sheet = sheet.getSheet();
this.book = book;
rows = this.sheet.rowRecordIterator();
}
public boolean hasNext() {
return rows.hasNext();
}
public Object next() {
HSSFRow retval = null;
if (rows.hasNext()) {
retval = new HSSFRow(book, sheet, (RowRecord)rows.next());
}
return retval;
}
public void remove() {
rows.remove();
}
}

View File

@ -59,26 +59,11 @@
*/ */
package org.apache.poi.hssf.usermodel; package org.apache.poi.hssf.usermodel;
import java.io.ByteArrayInputStream; import org.apache.poi.util.POILogFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import org.apache.poi.hssf.eventmodel.EventRecordFactory; import org.apache.poi.hssf.eventmodel.EventRecordFactory;
import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.BackupRecord; import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.ExtendedFormatRecord;
import org.apache.poi.hssf.record.FontRecord;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.RecordFactory;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.UnknownRecord;
import org.apache.poi.hssf.record.WindowTwoRecord;
import org.apache.poi.hssf.record.formula.Area3DPtg; import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.record.formula.MemFuncPtg; import org.apache.poi.hssf.record.formula.MemFuncPtg;
import org.apache.poi.hssf.record.formula.UnionPtg; import org.apache.poi.hssf.record.formula.UnionPtg;
@ -88,9 +73,17 @@ import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream; import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.Entry; import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
/** /**
* High level representation of a workbook. This is the first object most users * High level representation of a workbook. This is the first object most users
* will construct whether they are reading or writing a workbook. It is also the * will construct whether they are reading or writing a workbook. It is also the