From bdea32fe4240e4b62ff37407ec39d43866ff0991 Mon Sep 17 00:00:00 2001 From: "Andrew C. Oliver" Date: Sat, 19 Jul 2003 02:48:17 +0000 Subject: [PATCH] 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 --- .classpath | 12 +- src/java/org/apache/poi/hssf/model/Sheet.java | 79 ++- .../apache/poi/hssf/record/FormulaRecord.java | 8 + .../aggregates/RowRecordsAggregate.java | 61 +- .../aggregates/ValueRecordsAggregate.java | 660 +++++++++++++----- .../apache/poi/hssf/usermodel/HSSFCell.java | 102 ++- .../apache/poi/hssf/usermodel/HSSFRow.java | 153 ++-- .../apache/poi/hssf/usermodel/HSSFSheet.java | 196 +++--- .../poi/hssf/usermodel/HSSFWorkbook.java | 29 +- 9 files changed, 920 insertions(+), 380 deletions(-) diff --git a/.classpath b/.classpath index 75589e24b..dff3caf30 100644 --- a/.classpath +++ b/.classpath @@ -2,9 +2,13 @@ - - - - + + + + + + + + diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java index b99989cc9..80010ac3a 100644 --- a/src/java/org/apache/poi/hssf/model/Sheet.java +++ b/src/java/org/apache/poi/hssf/model/Sheet.java @@ -234,16 +234,18 @@ public class Sheet implements Model } else if ( rec.getSid() == RowRecord.sid ) { - RowRecord row = (RowRecord)rec; - if (!isfirstrow) rec = null; //only add the aggregate once - if ( isfirstrow ) { retval.rows = new RowRecordsAggregate(); - rec = retval.rows; + rec = retval.rows; + retval.rows.construct( k, recs ); isfirstrow = false; } - retval.rows.insertRow(row); + else + { + rec = null; + } + } else if ( rec.getSid() == PrintGridlinesRecord.sid ) { @@ -261,10 +263,6 @@ public class Sheet implements Model { retval.printSetup = (PrintSetupRecord) rec; } - else if ( rec.getSid() == SelectionRecord.sid ) - { - retval.selection = (SelectionRecord) rec; - } if (rec != null) { @@ -527,6 +525,11 @@ public class Sheet implements Model 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 * 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()); rows.removeRow(row); + cells.removeRow(row.getRowNumber()); /* * for (int k = loc; k < records.size(); k++) @@ -1310,6 +1314,9 @@ public class Sheet implements Model public RowRecord getRow(int rownum) { log.log(log.DEBUG, "getNextRow loc= " + loc); + if (rows == null) { + return null; + } return rows.getRow(rownum); /* @@ -1334,6 +1341,15 @@ public class Sheet implements Model // 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 * @@ -1412,6 +1428,15 @@ public class Sheet implements Model } } + public int getFirstRow() { + return rows.getFirstRowNum(); + } + + public int getLastRow() { + return rows.getLastRowNum(); + } + + /** not currently used */ private DBCellRecord createDBCell(int offset, IntList rowoffsets, @@ -1868,7 +1893,7 @@ public class Sheet implements Model for (k = 0; k < columnSizes.size(); k++) { ci = ( ColumnInfoRecord ) columnSizes.get(k); - if ((ci.getFirstColumn() <= column) + if ((ci.getFirstColumn() >= column) && (column <= ci.getLastColumn())) { break; @@ -1907,7 +1932,7 @@ public class Sheet implements Model for (k = 0; k < columnSizes.size(); k++) { ci = ( ColumnInfoRecord ) columnSizes.get(k); - if ((ci.getFirstColumn() <= column) + if ((ci.getFirstColumn() >= column) && (column <= ci.getLastColumn())) { break; @@ -2136,6 +2161,32 @@ public class Sheet implements Model 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) * @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(); } + return retval; } @@ -2203,6 +2255,11 @@ public class Sheet implements Model return null; } + public int getPhysicalNumberOfRows() { + return rows.getPhysicalNumberOfRows(); + } + + /** * Sets the SCL record or creates it in the correct place if it does not * already exist. diff --git a/src/java/org/apache/poi/hssf/record/FormulaRecord.java b/src/java/org/apache/poi/hssf/record/FormulaRecord.java index c1ed74a9d..228aa6592 100644 --- a/src/java/org/apache/poi/hssf/record/FormulaRecord.java +++ b/src/java/org/apache/poi/hssf/record/FormulaRecord.java @@ -342,6 +342,14 @@ public class FormulaRecord 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 * record passed with a differing ID. diff --git a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java index 2fe2ef631..09587af81 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java @@ -2,7 +2,7 @@ /* ==================================================================== * 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. * * Redistribution and use in source and binary forms, with or without @@ -75,10 +75,12 @@ public class RowRecordsAggregate { int firstrow = -1; int lastrow = -1; + boolean firstdirty = false; + boolean lastdirty = false; Map records = null; int size = 0; - /** Creates a new instance of ValueRecordsAggregate */ + /** Creates a new instance of RowRecordsAggregate */ public RowRecordsAggregate() { @@ -107,6 +109,12 @@ public class RowRecordsAggregate size -= row.getRecordSize(); // Integer integer = new Integer(row.getRowNumber()); + if (lastrow == row.getRowNumber()) { + lastdirty = true; + } + if (firstrow == row.getRowNumber()) { + firstdirty = true; + } records.remove(row); } @@ -127,17 +135,20 @@ public class RowRecordsAggregate public int getFirstRowNum() { + if (firstdirty) { + firstrow = findFirstRow(); + } return firstrow; } public int getLastRowNum() { + if (lastdirty) { + lastrow = findLastRow(); + } return lastrow; } - /* - * No need to go through all the records as we're just collecting RowRecords - public int construct(int offset, List records) { int k = 0; @@ -157,7 +168,7 @@ public class RowRecordsAggregate } return k; } - */ + /** * called by the class that is responsible for writing this sucker. * Subclasses should implement this so that their data is passed back in a @@ -222,7 +233,43 @@ public class RowRecordsAggregate { 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*/ public Object clone() { RowRecordsAggregate rec = new RowRecordsAggregate(); diff --git a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java index d985ac84f..3afdbfec5 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java @@ -2,7 +2,7 @@ /* ==================================================================== * 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. * * Redistribution and use in source and binary forms, with or without @@ -55,17 +55,22 @@ 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.formula.Ptg; +import org.apache.poi.util.DoubleList; +import org.apache.poi.util.IntList; import java.util.Iterator; import java.util.List; -import java.util.TreeMap; +import java.util.ArrayList; /** * * 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 Jason Height (jheight at chariot dot net dot au) */ @@ -76,63 +81,72 @@ public class ValueRecordsAggregate public final static short sid = -1000; int firstcell = -1; int lastcell = -1; - TreeMap records = null; -// int size = 0; + //TreeMap records = null; - /** 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) - { -/* if (records.get(cell) == null) - { - size += (( Record ) cell).getRecordSize(); + public int getRecordSize() { + //throw new RuntimeException("Not Implemented getRecordSize"); + + int size = 0; + 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() - - (( Record ) records.get(cell)).getRecordSize(); + pos += (( Record ) itr.next()).serialize(pos, data); }*/ - - // 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(); - } + return pos - offset; } - public void removeCell(CellValueRecordInterface cell) - { - // size -= (( Record ) cell).getRecordSize(); - - // XYLocator xy = new XYLocator(cell.getRow(), cell.getColumn()); - records.remove(cell); + public ValueRecordsAggregate() { + celltype = new ArrayList(DEFAULT_ROWS); + xfs = new ArrayList(DEFAULT_ROWS); + numericcells = new ArrayList(DEFAULT_ROWS); + formulaptgs = new ArrayList(DEFAULT_ROWS); + stringvals = new ArrayList(DEFAULT_ROWS); + populatedRows = new IntList(DEFAULT_ROWS); + physCells = 0; } - public int getPhysicalNumberOfCells() - { - return records.size(); + public Iterator getIterator() { + return new VRAIterator(this); } - public int getFirstCellNum() - { - return firstcell; - } - - public int getLastCellNum() - { - return lastcell; - } public int construct(int offset, List records) { @@ -157,11 +171,6 @@ public class ValueRecordsAggregate { 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()) { insertCell(( CellValueRecordInterface ) rec); @@ -170,140 +179,449 @@ public class ValueRecordsAggregate return k; } - /** - * 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 getPhysicalNumberOfCells() { + return physCells; + } - 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(); - int pos = offset; + Record record = ( Record ) cval; + 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; - } - /** - * 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) - { + return retval; } - /** - * 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 - */ + private void ensureRows(int rownum) { + adjustRows(celltype, rownum+1, IntList.class); + adjustRows(xfs, rownum+1, IntList.class); + adjustRows(numericcells, rownum+1, DoubleList.class); + adjustRows(formulaptgs, rownum+1, ArrayList.class); + adjustRows(stringvals, rownum+1, ArrayList.class); - protected void validateSid(short id) - { } - /** - * return the non static version of the id for this record. - */ - - public short getSid() - { - return sid; - } - - public int getRecordSize() { - - int size = 0; - Iterator irecs = records.values().iterator(); - - while (irecs.hasNext()) { - size += (( Record ) irecs.next()).getRecordSize(); + private void adjustRows(List list, int size, Class theclass) { + while (list.size() < size) { + try { + list.add(theclass.newInstance()); + } catch (Exception e) { + throw new RuntimeException("Could Not Instantiate Row in adjustRows"); + } } - - return size; -// return size; } - public Iterator getIterator() - { - return records.values().iterator(); + private void adjustIntList(IntList list, int size) { + while (list.size() < size) { + list.add(-1); + } } - /** Performs a deep clone of the record*/ - public Object clone() { - ValueRecordsAggregate rec = new ValueRecordsAggregate(); - for (Iterator valIter = getIterator(); valIter.hasNext();) { - CellValueRecordInterface val = (CellValueRecordInterface)((CellValueRecordInterface)valIter.next()).clone(); - rec.insertCell(val); - } - return rec; + private void adjustDoubleList(DoubleList list, int size) { + while (list.size() < size) { + list.add(-1); + } } + + 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 XYLocator implements Comparable { - * private int row = 0; - * private int col = 0; - * public XYLocator(int row, int col) { - * this.row = row; - * this.col = col; - * } - * - * public int getRow() { - * return row; - * } - * - * public int getCol() { - * return col; - * } - * - * public int compareTo(Object obj) { - * XYLocator loc = (XYLocator)obj; - * - * if (this.getRow() == loc.getRow() && - * this.getCol() == loc.getCol() ) - * return 0; - * - * if (this.getRow() < loc.getRow()) - * return -1; - * - * if (this.getRow() > loc.getRow()) - * return 1; - * - * if (this.getCol() < loc.getCol()) - * return -1; - * - * if (this.getCol() > loc.getCol()) - * return 1; - * - * return -1; - * - * } - * - * public boolean equals(Object obj) { - * if (!(obj instanceof XYLocator)) return false; - * - * XYLocator loc = (XYLocator)obj; - * if (this.getRow() == loc.getRow() - * && - * this.getCol() == loc.getCol() - * ) return true; - * return false; - * } - * - * - * } - */ +class VRAIterator implements Iterator { + private boolean hasNext; + private ValueRecordsAggregate vra; + int popindex; + int row; + int rowlimit; + int col; + CellValueRecordInterface current = null; + CellValueRecordInterface next = null; + + public VRAIterator(ValueRecordsAggregate vra) { + this.vra = vra; + this.rowlimit = -1; + popindex = 0; + if (vra.getPhysicalNumberOfCells() > 0) { + hasNext = true; + next = findNextCell(null); + } + } + + public VRAIterator(ValueRecordsAggregate vra, int row) { + this(vra); + rowlimit = row; + this.row = row; + this.popindex = vra.populatedRows.indexOf(row); + } + + public boolean hasNext() { + return hasNext; + } + + public Object next() { + current = next; + next = findNextCell(current); + if (next == null) { + hasNext = false; + } + return current; + } + + public void remove() { + vra.removeCell(current); + } + + private CellValueRecordInterface findNextCell(CellValueRecordInterface current) { + IntList ctRow = null; + int rowNum = -1; + int colNum = -1; + 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); + } + +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 5986b8463..c989753a6 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -163,7 +163,7 @@ public class HSSFCell private Sheet sheet; //private short row; private int row; - private CellValueRecordInterface record; +// private CellValueRecordInterface record; /** * Creates new Cell - Should only be called by HSSFRow. This creates a cell @@ -196,13 +196,25 @@ public class HSSFCell this.book = book; 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 // is different to CELL_TYPE_BLANK hence the following method call correctly // creates a new blank cell. - setCellType(CELL_TYPE_BLANK, false); - ExtendedFormatRecord xf = book.getExFormatAt(0xf); + //setCellType(CELL_TYPE_BLANK, false); + + //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; this.book = book; this.sheet = sheet; - switch (type) +/* switch (type) { case CELL_TYPE_NUMERIC : @@ -285,7 +297,7 @@ public class HSSFCell } 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) { cellNum = cval.getColumn(); - record = cval; + //record = cval; this.row = row; cellType = determineType(cval); cellStyle = null; @@ -394,8 +406,14 @@ public class HSSFCell public void setCellNum(short num) { + CellValueRecordInterface cval = sheet.getValueRecord(row, cellNum); + if (cval != null) { + sheet.removeValueRecord(this.row, cval); + } cellNum = num; - record.setColumn(num); + sheet.addValueRecord(row, cval); + //record.setColumn(num); + } /** @@ -457,16 +475,16 @@ public class HSSFCell } else { - frec = ( FormulaRecordAggregate ) record; + frec = (FormulaRecordAggregate)sheet.getValueRecord(row, cellNum); } frec.setColumn(getCellNum()); if (setValue) { frec.getFormulaRecord().setValue(getNumericCellValue()); } - frec.setXFIndex(( short ) cellStyle.getIndex()); +// frec.setXFIndex(( short ) cellStyle.getIndex()); frec.setRow(row); - record = frec; + sheet.replaceValueRecord(frec); break; case CELL_TYPE_NUMERIC : @@ -478,16 +496,16 @@ public class HSSFCell } else { - nrec = ( NumberRecord ) record; + nrec = ( NumberRecord ) sheet.getValueRecord(row, cellNum); } nrec.setColumn(getCellNum()); if (setValue) { nrec.setValue(getNumericCellValue()); } - nrec.setXFIndex(( short ) cellStyle.getIndex()); + nrec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex()); nrec.setRow(row); - record = nrec; + sheet.replaceValueRecord(nrec); break; case CELL_TYPE_STRING : @@ -499,11 +517,11 @@ public class HSSFCell } else { - lrec = ( LabelSSTRecord ) record; + lrec = ( LabelSSTRecord ) sheet.getValueRecord(row, cellNum); } lrec.setColumn(getCellNum()); lrec.setRow(row); - lrec.setXFIndex(( short ) cellStyle.getIndex()); + lrec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex()); if (setValue) { if ((getStringCellValue() != null) @@ -523,7 +541,7 @@ public class HSSFCell lrec.setSSTIndex(sst); } } - record = lrec; + sheet.replaceValueRecord(lrec); break; case CELL_TYPE_BLANK : @@ -535,21 +553,21 @@ public class HSSFCell } else { - brec = ( BlankRecord ) record; + brec = ( BlankRecord ) sheet.getValueRecord(row, cellNum); } brec.setColumn(getCellNum()); // During construction the cellStyle may be null for a Blank cell. if (cellStyle != null) { - brec.setXFIndex(( short ) cellStyle.getIndex()); + brec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex()); } else { brec.setXFIndex(( short ) 0); } brec.setRow(row); - record = brec; + sheet.replaceValueRecord(brec); break; case CELL_TYPE_BOOLEAN : @@ -561,7 +579,7 @@ public class HSSFCell } else { - boolRec = ( BoolErrRecord ) record; + boolRec = ( BoolErrRecord ) sheet.getValueRecord(row, cellNum); } boolRec.setColumn(getCellNum()); if (setValue) @@ -570,7 +588,7 @@ public class HSSFCell } boolRec.setXFIndex(( short ) cellStyle.getIndex()); boolRec.setRow(row); - record = boolRec; + sheet.replaceValueRecord(boolRec); break; case CELL_TYPE_ERROR : @@ -582,7 +600,7 @@ public class HSSFCell } else { - errRec = ( BoolErrRecord ) record; + errRec = ( BoolErrRecord ) sheet.getValueRecord(row, cellNum); } errRec.setColumn(getCellNum()); if (setValue) @@ -591,16 +609,17 @@ public class HSSFCell } errRec.setXFIndex(( short ) cellStyle.getIndex()); errRec.setRow(row); - record = errRec; + sheet.replaceValueRecord(errRec); break; } if (cellType != this.cellType) { int loc = sheet.getLoc(); - sheet.replaceValueRecord(record); + //sheet.replaceValueRecord(record); sheet.setLoc(loc); } + //sheet.setCellType(this.row, this.cellNum); this.cellType = cellType; } @@ -631,7 +650,7 @@ public class HSSFCell { setCellType(CELL_TYPE_NUMERIC, false); } - (( NumberRecord ) record).setValue(value); + sheet.setCellValue(row, cellNum, value); cellValue = value; } @@ -693,7 +712,7 @@ public class HSSFCell { index = book.addSSTString(value, true); } - (( LabelSSTRecord ) record).setSSTIndex(index); + sheet.setCellValue(row, cellNum, index); stringValue = value; } } @@ -704,12 +723,12 @@ public class HSSFCell setCellType(CELL_TYPE_BLANK,false); } else { setCellType(CELL_TYPE_FORMULA,false); - FormulaRecordAggregate rec = (FormulaRecordAggregate) record; + FormulaRecordAggregate rec = new FormulaRecordAggregate(new FormulaRecord(), null); rec.getFormulaRecord().setOptions(( short ) 2); rec.getFormulaRecord().setValue(0); - - //only set to default if there is no extended format index already set - if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f); + rec.setRow(row); + rec.setColumn(cellNum); + rec.setXFIndex(( short ) 0x0f); FormulaParser fp = new FormulaParser(formula+";",book); fp.parse(); Ptg[] ptg = fp.getRPNPtg(); @@ -720,6 +739,9 @@ public class HSSFCell rec.getFormulaRecord().pushExpressionToken(ptg[ k ]); } rec.getFormulaRecord().setExpressionLength(( short ) size); + + sheet.replaceValueRecord(rec); + //sheet.setCellFormula(row, cellNum, options, value //Workbook.currentBook = null; } } @@ -727,7 +749,8 @@ public class HSSFCell public String getCellFormula() { //Workbook.currentBook=book; 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; return retval; } @@ -834,12 +857,12 @@ public class HSSFCell 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); } (( BoolErrRecord ) record).setValue(value); - booleanValue = value; + booleanValue = value; */ } /** @@ -853,11 +876,11 @@ public class HSSFCell 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); } - (( BoolErrRecord ) record).setValue(value); + (( BoolErrRecord ) record).setValue(value);*/ errorValue = value; } @@ -911,7 +934,8 @@ public class HSSFCell public void setCellStyle(HSSFCellStyle style) { cellStyle = style; - record.setXFIndex(style.getIndex()); + + sheet.setCellStyle(row, cellNum, style.getIndex()); } /** @@ -961,7 +985,7 @@ public class HSSFCell 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."); } } + /** * Sets this cell as the active cell for the worksheet @@ -985,4 +1010,5 @@ public class HSSFCell this.sheet.setActiveCellRow(this.row); this.sheet.setActiveCellCol(this.cellNum); } + } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java index cf9b1c400..962a0e6e3 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java @@ -63,6 +63,7 @@ import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.CellValueRecordInterface; import org.apache.poi.hssf.record.RowRecord; +import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate; import java.util.HashMap; import java.util.Iterator; @@ -84,7 +85,7 @@ public class HSSFRow public final static int INITIAL_CAPACITY = 5; //private short rowNum; private int rowNum; - private HashMap cells; + //private ValueRecordsAggregate cells; // private short firstcell = -1; // private short lastcell = -1; @@ -92,7 +93,7 @@ public class HSSFRow * reference to low level representation */ - private RowRecord row; + //private RowRecord row; /** * reference to containing low level Workbook @@ -123,16 +124,16 @@ public class HSSFRow protected HSSFRow(Workbook book, Sheet sheet, int rowNum) { this.rowNum = rowNum; - cells = new HashMap(10); // new ArrayList(INITIAL_CAPACITY); + //cells = new HashMap(10); // new ArrayList(INITIAL_CAPACITY); this.book = book; this.sheet = sheet; - row = new RowRecord(); - row.setHeight((short) 0xff); - row.setLastCol((short) -1); - row.setFirstCol((short) -1); + //row = new RowRecord(); + //row.setHeight((short) 0xff); + //row.setLastCol((short) -1); + //row.setFirstCol((short) -1); // row.setRowNumber(rowNum); - setRowNum(rowNum); + //setRowNum(rowNum); } /** @@ -148,10 +149,10 @@ public class HSSFRow protected HSSFRow(Workbook book, Sheet sheet, RowRecord record) { //this.rowNum = rowNum; - cells = new HashMap(); // ArrayList(INITIAL_CAPACITY); + //cells = new HashMap(); // ArrayList(INITIAL_CAPACITY); this.book = book; this.sheet = sheet; - row = record; + //row = record; // row.setHeight(record.getHeight()); // row.setRowNumber(rowNum); @@ -175,8 +176,8 @@ public class HSSFRow { HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), column); - addCell(cell); - sheet.addValueRecord(getRowNum(), cell.getCellValueRecord()); + //addCell(cell); + //sheet.addValueRecord(getRowNum(), cell.getCellValueRecord()); return cell; } @@ -211,15 +212,15 @@ public class HSSFRow CellValueRecordInterface cval = cell.getCellValueRecord(); 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); - // sheet.addValueRecord(getRowNum(),cell.getCellValueRecord()); + sheet.addValueRecord(getRowNum(),cell); return hcell; } @@ -249,10 +250,10 @@ public class HSSFRow public void setRowNum(int rowNum) { this.rowNum = rowNum; - if (row != null) - { - row.setRowNumber(rowNum); // used only for KEY comparison (HSSFRow) - } + //if (row != null) + //{ + // row.setRowNumber(rowNum); // used only for KEY comparison (HSSFRow) + //} } /** @@ -272,26 +273,44 @@ public class HSSFRow 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 * ask for a cell that is not defined....you get a null. @@ -302,6 +321,11 @@ public class HSSFRow 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++) { @@ -312,7 +336,7 @@ public class HSSFRow return cell; } }*/ - return (HSSFCell) cells.get(new Integer(cellnum)); + return retval; } /** @@ -325,7 +349,7 @@ public class HSSFRow if (getPhysicalNumberOfCells() == 0) return -1; else - return row.getFirstCol(); + return getFirstCol(rowNum); } /** @@ -338,7 +362,7 @@ public class HSSFRow if (getPhysicalNumberOfCells() == 0) return -1; else - return row.getLastCol(); + return getLastCol(rowNum); } @@ -350,11 +374,13 @@ public class HSSFRow public int getPhysicalNumberOfCells() { - if (cells == null) - { - return 0; // shouldn't be possible but it is due to missing API support for BLANK/MULBLANK - } - return cells.size(); + // sheet.get +// if (cells == null) +// { +// return 0; // shouldn't be possible but it is due to missing API support for BLANK/MULBLANK +// } +// return cells.size(); + return sheet.getPhysicalNumberOfRows(); } /** @@ -367,8 +393,8 @@ public class HSSFRow { // row.setOptionFlags( - row.setBadFontHeight(true); - row.setHeight(height); + sheet.getRow(rowNum).setBadFontHeight(true); + sheet.getRow(rowNum).setHeight(height); } /** @@ -380,8 +406,8 @@ public class HSSFRow { // row.setOptionFlags( - row.setBadFontHeight(true); - row.setHeight((short) (height * 20)); + sheet.getRow(rowNum).setBadFontHeight(true); + sheet.getRow(rowNum).setHeight((short) (height * 20)); } /** @@ -391,7 +417,7 @@ public class HSSFRow public short getHeight() { - return row.getHeight(); + return sheet.getRow(rowNum).getHeight(); } /** @@ -401,7 +427,7 @@ public class HSSFRow public float getHeightInPoints() { - return (row.getHeight() / 20); + return (sheet.getRow(rowNum).getHeight() / 20); } /** @@ -413,7 +439,7 @@ public class HSSFRow protected RowRecord getRowRecord() { - return row; + return sheet.getRow(rowNum); } /** @@ -457,7 +483,7 @@ public class HSSFRow public Iterator cellIterator() { - return cells.values().iterator(); + return new RowCellIterator(this.book, this.sheet, this.rowNum); } public int compareTo(Object obj) @@ -494,3 +520,36 @@ public class HSSFRow 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(); + } + + +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index 2f6ec6f50..136fd0930 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -62,13 +62,11 @@ package org.apache.poi.hssf.usermodel; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.TreeMap; import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.CellValueRecordInterface; 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.SCLRecord; import org.apache.poi.hssf.record.VCenterRecord; @@ -115,7 +113,9 @@ public class HSSFSheet */ private Sheet sheet; - private TreeMap rows; + // private TreeMap rows; +// private RowRecordsAggregate rows; +// private ValueRecordsAggregate vra; private Workbook book; private int firstrow; private int lastrow; @@ -132,7 +132,7 @@ public class HSSFSheet protected HSSFSheet(Workbook book) { sheet = Sheet.createSheet(); - rows = new TreeMap(); // new ArrayList(INITIAL_CAPACITY); + //rows = new TreeMap(); // new ArrayList(INITIAL_CAPACITY); this.book = book; } @@ -148,7 +148,7 @@ public class HSSFSheet protected HSSFSheet(Workbook book, Sheet sheet) { this.sheet = sheet; - rows = new TreeMap(); + //rows = new TreeMap(); this.book = book; setPropertiesFromSheet(sheet); } @@ -164,7 +164,7 @@ public class HSSFSheet private void setPropertiesFromSheet(Sheet sheet) { - int sloc = sheet.getLoc(); +/* int sloc = sheet.getLoc(); RowRecord row = sheet.getNextRow(); while (row != null) @@ -173,7 +173,9 @@ public class HSSFSheet row = sheet.getNextRow(); } - sheet.setLoc(sloc); + sheet.setLoc(sloc);*/ + + /* CellValueRecordInterface cval = sheet.getNextValueRecord(); long timestart = System.currentTimeMillis(); @@ -204,8 +206,9 @@ public class HSSFSheet 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 */ - private HSSFRow createRowFromRecord(RowRecord row) +/* private HSSFRow createRowFromRecord(RowRecord row) { HSSFRow hrow = new HSSFRow(book, sheet, row); addRow(hrow, false); return hrow; - } + }*/ /** * 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) { sheet.setLoc(sheet.getDimsLoc()); - if (rows.size() > 0) - { - rows.remove(row); - if (row.getRowNum() == getLastRowNum()) - { - lastrow = findLastRow(lastrow); - } - if (row.getRowNum() == getFirstRowNum()) - { - firstrow = findFirstRow(firstrow); - } - Iterator iter = row.cellIterator(); +// if (rows.size() > 0) +// { +// rows.remove(row); + // if (row.getRowNum() == getLastRowNum()) + // { + // lastrow = findLastRow(lastrow); + // } + // if (row.getRowNum() == getFirstRowNum()) + // { + // firstrow = findFirstRow(firstrow); + // } + //Iterator iter = row.cellIterator(); - while (iter.hasNext()) +/* while (iter.hasNext()) { HSSFCell cell = (HSSFCell) iter.next(); sheet.removeValueRecord(row.getRowNum(), cell.getCellValueRecord()); - } + }*/ sheet.removeRow(row.getRowRecord()); - } + //} } /** * 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; HSSFRow r = getRow(rownum); @@ -288,13 +291,13 @@ public class HSSFSheet r = getRow(--rownum); } return rownum; - } + }*/ /** * 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; HSSFRow r = getRow(rownum); @@ -308,7 +311,7 @@ public class HSSFSheet return -1; return rownum; - } + } */ /** * add a row to the sheet @@ -318,19 +321,22 @@ public class HSSFSheet private void addRow(HSSFRow row, boolean addLow) { - rows.put(row, row); - if (addLow) - { - sheet.addRow(row.getRowRecord()); + //rows.put(row, row); + if (addLow) { + RowRecord rec = sheet.getRow(row.getRowNum()); + if (rec == null) { + rec = new RowRecord(); + sheet.addRow(sheet.createRow(row.getRowNum())); + } } - if (row.getRowNum() > getLastRowNum()) +/* if (row.getRowNum() > getLastRowNum()) { lastrow = row.getRowNum(); } if (row.getRowNum() < getFirstRowNum()) { firstrow = row.getRowNum(); - } + }*/ } /** @@ -342,11 +348,9 @@ public class HSSFSheet public HSSFRow getRow(int rownum) { - HSSFRow row = new HSSFRow(); + HSSFRow retval = new HSSFRow(book, sheet, this.sheet.getRow(rownum)); - //row.setRowNum((short) rownum); - row.setRowNum( rownum); - return (HSSFRow) rows.get(row); + return retval; } /** @@ -355,7 +359,7 @@ public class HSSFSheet public int getPhysicalNumberOfRows() { - return rows.size(); + return sheet.getPhysicalNumberOfRows(); } /** @@ -365,7 +369,7 @@ public class HSSFSheet public int getFirstRowNum() { - return firstrow; + return sheet.getFirstRow(); } /** @@ -375,7 +379,7 @@ public class HSSFSheet public int getLastRowNum() { - return lastrow; + return sheet.getLastRow(); } /** @@ -592,7 +596,7 @@ public class HSSFSheet 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 * gridlines */ - public void setPrintGridlines( boolean newPrintGridlines ) - { - getSheet().getPrintGridlines().setPrintGridlines( newPrintGridlines ); + public void setPrintGridlines(boolean newPrintGridlines) { + getSheet().getPrintGridlines().setPrintGridlines(newPrintGridlines); } /** * Gets the print setup object. * @return The user model for the print setup object. */ - public HSSFPrintSetup getPrintSetup() - { - return new HSSFPrintSetup( getSheet().getPrintSetup() ); + public HSSFPrintSetup getPrintSetup() { + return new HSSFPrintSetup(getSheet().getPrintSetup()); } /** * Gets the user model for the document header. * @return The Document header. */ - public HSSFHeader getHeader() - { - return new HSSFHeader( getSheet().getHeader() ); + public HSSFHeader getHeader() { + return new HSSFHeader(getSheet().getHeader()); } /** * Gets the user model for the document footer. * @return The Document footer. */ - public HSSFFooter getFooter() - { - return new HSSFFooter( getSheet().getFooter() ); - } + public HSSFFooter getFooter() { + return new HSSFFooter(getSheet().getFooter()); + } - /** - * Sets whether sheet is selected. - * @param sel Whether to select the sheet or deselect the sheet. - */ - public void setSelected( boolean sel ) - { - getSheet().setSelected( sel ); - } + /** + * Sets whether sheet is selected. + * @param sel Whether to select the sheet or deselect the sheet. + */ + public void setSelected(boolean sel) { + getSheet().setSelected(sel); + } - /** - * Gets the size of the margin in inches. - * @param margin which margin to get - * @return the size of the margin - */ - public double getMargin( short margin ) - { - return getSheet().getMargin( margin ); - } + /** + * Gets the size of the margin in inches. + * @param margin which margin to get + * @return the size of the margin + */ + public double getMargin(short 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 @@ -903,7 +901,7 @@ public class HSSFSheet * @param endRow * @param n * @param isRow - */ + */ protected void shiftMerged(int startRow, int endRow, int n, boolean isRow) { List shiftedRegions = new ArrayList(); //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(); + } + + +} diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 8420aa63b..04f80af5a 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -59,26 +59,11 @@ */ package org.apache.poi.hssf.usermodel; -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; - +import org.apache.poi.util.POILogFactory; import org.apache.poi.hssf.eventmodel.EventRecordFactory; import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Workbook; -import org.apache.poi.hssf.record.BackupRecord; -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.*; import org.apache.poi.hssf.record.formula.Area3DPtg; import org.apache.poi.hssf.record.formula.MemFuncPtg; 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.Entry; import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.POILogFactory; 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 * will construct whether they are reading or writing a workbook. It is also the