diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index 3f8aa68d7..2be7cb4ec 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,6 +37,7 @@ + 41187 - fixed HSSFSheet to properly read xls files without ROW records 44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals 42570 - fixed LabelRecord to use empty string instead of null when the length is zero. 42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues. diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 75e8a30de..3212850d3 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 41187 - fixed HSSFSheet to properly read xls files without ROW records 44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals 42570 - fixed LabelRecord to use empty string instead of null when the length is zero. 42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues. diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java index 2af25e748..2dac8b1d0 100644 --- a/src/java/org/apache/poi/hssf/model/Sheet.java +++ b/src/java/org/apache/poi/hssf/model/Sheet.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -16,7 +15,6 @@ limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.model; import org.apache.poi.hssf.record.*; @@ -57,9 +55,7 @@ import java.util.List; // normally I don't do this, buy we literally mean ALL * @see org.apache.poi.hssf.usermodel.HSSFSheet * @version 1.0-pre */ - -public class Sheet implements Model -{ +public final class Sheet implements Model { public static final short LeftMargin = 0; public static final short RightMargin = 1; public static final short TopMargin = 2; @@ -97,9 +93,9 @@ public class Sheet implements Model protected ObjectProtectRecord objprotect = null; protected ScenarioProtectRecord scenprotect = null; protected PasswordRecord password = null; - protected List condFormatting = new ArrayList();; + protected List condFormatting = new ArrayList(); - /** Add an UncalcedRecord if not true indicating formulas have not been calculated */ + /** Add an UncalcedRecord if not true indicating formulas have not been calculated */ protected boolean uncalced = false; public static final byte PANE_LOWER_RIGHT = (byte)0; @@ -108,7 +104,7 @@ public class Sheet implements Model public static final byte PANE_UPPER_LEFT = (byte)3; /** - * Creates new Sheet with no intialization --useless at this point + * Creates new Sheet with no initialization --useless at this point * @see #createSheet(List,int,int) */ public Sheet() @@ -166,7 +162,7 @@ public class Sheet implements Model } } else if (rec.getSid() == UncalcedRecord.sid) { - retval.uncalced = true; + retval.uncalced = true; } else if (rec.getSid() == DimensionsRecord.sid) { @@ -188,14 +184,14 @@ public class Sheet implements Model } else if ( rec.getSid() == CFHeaderRecord.sid ) { - CFRecordsAggregate cfAgg = CFRecordsAggregate.createCFAggregate(recs, k); - retval.condFormatting.add(cfAgg); - rec = cfAgg; + CFRecordsAggregate cfAgg = CFRecordsAggregate.createCFAggregate(recs, k); + retval.condFormatting.add(cfAgg); + rec = cfAgg; } else if ( rec.getSid() == CFRuleRecord.sid ) { - // Skip it since it is processed by CFRecordsAggregate - rec = null; + // Skip it since it is processed by CFRecordsAggregate + rec = null; } else if (rec.getSid() == ColumnInfoRecord.sid) { @@ -244,7 +240,7 @@ public class Sheet implements Model if ( isfirstrow ) { retval.rows = new RowRecordsAggregate(); - rec = retval.rows; + rec = retval.rows; isfirstrow = false; } retval.rows.insertRow(row); @@ -256,7 +252,7 @@ public class Sheet implements Model else if ( rec.getSid() == GridsetRecord.sid ) { retval.gridset = (GridsetRecord) rec; - } + } else if ( rec.getSid() == HeaderRecord.sid && bofEofNestingLevel == 1) { retval.header = (HeaderRecord) rec; @@ -301,32 +297,32 @@ public class Sheet implements Model { rec = null; } - - else if ( rec.getSid() == ProtectRecord.sid ) - { - retval.protect = (ProtectRecord) rec; - } - else if ( rec.getSid() == ObjectProtectRecord.sid ) - { - retval.objprotect = (ObjectProtectRecord) rec; - } - else if ( rec.getSid() == ScenarioProtectRecord.sid ) - { - retval.scenprotect = (ScenarioProtectRecord) rec; - } - else if ( rec.getSid() == PasswordRecord.sid ) - { - retval.password = (PasswordRecord) rec; - } - else if (rec.getSid() == PageBreakRecord.HORIZONTAL_SID) - { - retval.rowBreaks = (PageBreakRecord)rec; - } - else if (rec.getSid() == PageBreakRecord.VERTICAL_SID) - { - retval.colBreaks = (PageBreakRecord)rec; - } - + + else if ( rec.getSid() == ProtectRecord.sid ) + { + retval.protect = (ProtectRecord) rec; + } + else if ( rec.getSid() == ObjectProtectRecord.sid ) + { + retval.objprotect = (ObjectProtectRecord) rec; + } + else if ( rec.getSid() == ScenarioProtectRecord.sid ) + { + retval.scenprotect = (ScenarioProtectRecord) rec; + } + else if ( rec.getSid() == PasswordRecord.sid ) + { + retval.password = (PasswordRecord) rec; + } + else if (rec.getSid() == PageBreakRecord.HORIZONTAL_SID) + { + retval.rowBreaks = (PageBreakRecord)rec; + } + else if (rec.getSid() == PageBreakRecord.VERTICAL_SID) + { + retval.colBreaks = (PageBreakRecord)rec; + } + if (rec != null) { records.add(rec); @@ -351,9 +347,9 @@ public class Sheet implements Model /** * Clones the low level records of this sheet and returns the new sheet instance. * This method is implemented by adding methods for deep cloning to all records that - * can be added to a sheet. The Record object does not implement cloneable. + * can be added to a sheet. The Record object does not implement cloneable. * When adding a new record, implement a public clone method if and only if the record - * belongs to a sheet. + * belongs to a sheet. */ public Sheet cloneSheet() { @@ -374,7 +370,7 @@ public class Sheet implements Model ValueRecordsAggregate vrAgg = (ValueRecordsAggregate)rec; for (Iterator cellIter = vrAgg.getIterator();cellIter.hasNext();) { Record valRec = (Record)cellIter.next(); - + if (valRec instanceof FormulaRecordAggregate) { FormulaRecordAggregate fmAgg = (FormulaRecordAggregate)valRec; Record fmAggRec = fmAgg.getFormulaRecord(); @@ -459,9 +455,9 @@ public class Sheet implements Model records.add(retval.rowBreaks); retval.colBreaks = new PageBreakRecord(PageBreakRecord.VERTICAL_SID); records.add(retval.colBreaks); - + retval.header = (HeaderRecord) retval.createHeader(); - records.add( retval.header ); + records.add( retval.header ); retval.footer = (FooterRecord) retval.createFooter(); records.add( retval.footer ); records.add( retval.createHCenter() ); @@ -479,11 +475,11 @@ public class Sheet implements Model retval.dimsloc = records.size()-1; records.add(retval.windowTwo = retval.createWindowTwo()); retval.setLoc(records.size() - 1); - retval.selection = + retval.selection = (SelectionRecord) retval.createSelection(); records.add(retval.selection); - retval.protect = (ProtectRecord) retval.createProtect(); - records.add(retval.protect); + retval.protect = (ProtectRecord) retval.createProtect(); + records.add(retval.protect); records.add(retval.createEOF()); @@ -511,26 +507,25 @@ public class Sheet implements Model } } - //public int addMergedRegion(short rowFrom, short colFrom, short rowTo, - public int addMergedRegion(int rowFrom, short colFrom, int rowTo, - short colTo) - { - // Validate input - if(rowTo < rowFrom) { - throw new IllegalArgumentException("The row to ("+rowTo+") must be >= the row from ("+rowFrom+")"); - } - if(colTo < colFrom) { - throw new IllegalArgumentException("The col to ("+colTo+") must be >= the col from ("+colFrom+")"); - } - + public int addMergedRegion(int rowFrom, short colFrom, int rowTo, short colTo) { + // Validate input + if (rowTo < rowFrom) { + throw new IllegalArgumentException("The 'to' row (" + rowTo + + ") must not be less than the 'from' row (" + rowFrom + ")"); + } + if (colTo < colFrom) { + throw new IllegalArgumentException("The 'to' col (" + colTo + + ") must not be less than the 'from' col (" + colFrom + ")"); + } + if (merged == null || merged.getNumAreas() == 1027) { merged = ( MergeCellsRecord ) createMergedCells(); - mergedRecords.add(merged); + mergedRecords.add(merged); records.add(records.size() - 1, merged); } merged.addArea(rowFrom, colFrom, rowTo, colTo); - return numMergedRegions++; + return numMergedRegions++; } public void removeMergedRegion(int index) @@ -538,59 +533,10 @@ public class Sheet implements Model //safety checks if (index >= numMergedRegions || mergedRecords.size() == 0) return; - + int pos = 0; int startNumRegions = 0; - - //optimisation for current record - if (numMergedRegions - index < merged.getNumAreas()) - { - pos = mergedRecords.size() - 1; - startNumRegions = numMergedRegions - merged.getNumAreas(); - } - else - { - for (int n = 0; n < mergedRecords.size(); n++) - { - MergeCellsRecord record = (MergeCellsRecord) mergedRecords.get(n); - if (startNumRegions + record.getNumAreas() > index) - { - pos = n; - break; - } - startNumRegions += record.getNumAreas(); - } - } - MergeCellsRecord rec = (MergeCellsRecord) mergedRecords.get(pos); - rec.removeAreaAt(index - startNumRegions); - numMergedRegions--; - if (rec.getNumAreas() == 0) - { - mergedRecords.remove(pos); - //get rid of the record from the sheet - records.remove(merged); - if (merged == rec) { - //pull up the LAST record for operations when we finally - //support continue records for mergedRegions - if (mergedRecords.size() > 0) { - merged = (MergeCellsRecord) mergedRecords.get(mergedRecords.size() - 1); - } else { - merged = null; - } - } - } - } - - public MergeCellsRecord.MergedRegion getMergedRegionAt(int index) - { - //safety checks - if (index >= numMergedRegions || mergedRecords.size() == 0) - return null; - - int pos = 0; - int startNumRegions = 0; - //optimisation for current record if (numMergedRegions - index < merged.getNumAreas()) { @@ -607,7 +553,56 @@ public class Sheet implements Model pos = n; break; } - startNumRegions += record.getNumAreas(); + startNumRegions += record.getNumAreas(); + } + } + + MergeCellsRecord rec = (MergeCellsRecord) mergedRecords.get(pos); + rec.removeAreaAt(index - startNumRegions); + numMergedRegions--; + if (rec.getNumAreas() == 0) + { + mergedRecords.remove(pos); + //get rid of the record from the sheet + records.remove(merged); + if (merged == rec) { + //pull up the LAST record for operations when we finally + //support continue records for mergedRegions + if (mergedRecords.size() > 0) { + merged = (MergeCellsRecord) mergedRecords.get(mergedRecords.size() - 1); + } else { + merged = null; + } + } + } + } + + public MergeCellsRecord.MergedRegion getMergedRegionAt(int index) + { + //safety checks + if (index >= numMergedRegions || mergedRecords.size() == 0) + return null; + + int pos = 0; + int startNumRegions = 0; + + //optimisation for current record + if (numMergedRegions - index < merged.getNumAreas()) + { + pos = mergedRecords.size() - 1; + startNumRegions = numMergedRegions - merged.getNumAreas(); + } + else + { + for (int n = 0; n < mergedRecords.size(); n++) + { + MergeCellsRecord record = (MergeCellsRecord) mergedRecords.get(n); + if (startNumRegions + record.getNumAreas() > index) + { + pos = n; + break; + } + startNumRegions += record.getNumAreas(); } } return ((MergeCellsRecord) mergedRecords.get(pos)).getAreaAt(index - startNumRegions); @@ -620,62 +615,62 @@ public class Sheet implements Model // Find correct position to add new CF record private int findConditionalFormattingPosition() { - // This is default. - // If the algorithm does not find the right position, - // this one will be used (this is a position before EOF record) - int index = records.size()-2; - - for( int i=index; i>=0; i-- ) - { - Record rec = (Record)records.get(i); - short sid = rec.getSid(); - - // CFRecordsAggregate records already exist, just add to the end - if (rec instanceof CFRecordsAggregate) { return i+1; } - - if( sid == (short)0x00ef ) { return i+1; }// PHONETICPR - if( sid == (short)0x015f ) { return i+1; }// LABELRANGES - if( sid == MergeCellsRecord.sid ) { return i+1; } - if( sid == (short)0x0099 ) { return i+1; }// STANDARDWIDTH - if( sid == SelectionRecord.sid ) { return i+1; } - if( sid == PaneRecord.sid ) { return i+1; } - if( sid == SCLRecord.sid ) { return i+1; } - if( sid == WindowTwoRecord.sid ) { return i+1; } - } - - return index; + // This is default. + // If the algorithm does not find the right position, + // this one will be used (this is a position before EOF record) + int index = records.size()-2; + + for( int i=index; i>=0; i-- ) + { + Record rec = (Record)records.get(i); + short sid = rec.getSid(); + + // CFRecordsAggregate records already exist, just add to the end + if (rec instanceof CFRecordsAggregate) { return i+1; } + + if( sid == (short)0x00ef ) { return i+1; }// PHONETICPR + if( sid == (short)0x015f ) { return i+1; }// LABELRANGES + if( sid == MergeCellsRecord.sid ) { return i+1; } + if( sid == (short)0x0099 ) { return i+1; }// STANDARDWIDTH + if( sid == SelectionRecord.sid ) { return i+1; } + if( sid == PaneRecord.sid ) { return i+1; } + if( sid == SCLRecord.sid ) { return i+1; } + if( sid == WindowTwoRecord.sid ) { return i+1; } + } + + return index; } public int addConditionalFormatting(CFRecordsAggregate cfAggregate) { - int index = findConditionalFormattingPosition(); - records.add(index, cfAggregate); - condFormatting.add(cfAggregate); - return condFormatting.size()-1; + int index = findConditionalFormattingPosition(); + records.add(index, cfAggregate); + condFormatting.add(cfAggregate); + return condFormatting.size()-1; } public void removeConditionalFormatting(int index) { if (index >= 0 && index <= condFormatting.size()-1 ) { - CFRecordsAggregate cfAggregate = getCFRecordsAggregateAt(index); - records.remove(cfAggregate); - condFormatting.remove(index); + CFRecordsAggregate cfAggregate = getCFRecordsAggregateAt(index); + records.remove(cfAggregate); + condFormatting.remove(index); } } - + public CFRecordsAggregate getCFRecordsAggregateAt(int index) { if (index >= 0 && index <= condFormatting.size()-1 ) { - return (CFRecordsAggregate) condFormatting.get(index); + return (CFRecordsAggregate) condFormatting.get(index); } return null; } - + public int getNumConditionalFormattings() { - return condFormatting.size(); + return condFormatting.size(); } /** @@ -711,8 +706,6 @@ public class Sheet implements Model * * @see org.apache.poi.hssf.record.DimensionsRecord */ - - //public void setDimensions(short firstrow, short firstcol, short lastrow, public void setDimensions(int firstrow, short firstcol, int lastrow, short lastcol) { @@ -735,7 +728,7 @@ public class Sheet implements Model /** * set the locator for where we should look for the next value record. The - * algorythm will actually start here and find the correct location so you + * algorithm will actually start here and find the correct location so you * can set this to 0 and watch performance go down the tubes but it will work. * After a value is set this is automatically advanced. Its also set by the * create method. So you probably shouldn't mess with this unless you have @@ -813,13 +806,13 @@ public class Sheet implements Model for (int k = 0; k < records.size(); k++) { Record record = (( Record ) records.get(k)); - + // Don't write out UncalcedRecord entries, as // we handle those specially just below if (record instanceof UncalcedRecord) { - continue; + continue; } - + // Once the rows have been found in the list of records, start // writing out the blocked row information. This includes the DBCell references if (record instanceof RowRecordsAggregate) { @@ -829,13 +822,13 @@ public class Sheet implements Model } else { pos += record.serialize(pos, data ); // rec.length; } - + // If the BOF record was just serialized then add the IndexRecord if (record.getSid() == BOFRecord.sid) { // Add an optional UncalcedRecord if (uncalced) { - UncalcedRecord rec = new UncalcedRecord(); - pos += rec.serialize(pos, data); + UncalcedRecord rec = new UncalcedRecord(); + pos += rec.serialize(pos, data); } //Can there be more than one BOF for a sheet? If not then we can //remove this guard. So be safe it is left here. @@ -871,7 +864,7 @@ public class Sheet implements Model log.log(POILogger.DEBUG, "Sheet.serialize returning "); return pos-offset; } - + private int serializeIndexRecord(final int BOFRecordIndex, final int offset, byte[] data) { IndexRecord index = new IndexRecord(); index.setFirstRow(rows.getFirstRowNum()); @@ -906,7 +899,7 @@ public class Sheet implements Model } return index.serialize(offset, data); } - + /** * Create a row record. (does not add it to the records contained in this sheet) @@ -930,8 +923,6 @@ public class Sheet implements Model * @return LabelSSTRecord newly created containing your SST Index, row,col. * @see org.apache.poi.hssf.record.SSTRecord */ - - //public LabelSSTRecord createLabelSST(short row, short col, int index) public LabelSSTRecord createLabelSST(int row, short col, int index) { log.logFormatted(POILogger.DEBUG, "create labelsst row,col,index %,%,%", @@ -957,8 +948,6 @@ public class Sheet implements Model * * @return NumberRecord for that row, col containing that value as added to the sheet */ - - //public NumberRecord createNumber(short row, short col, double value) public NumberRecord createNumber(int row, short col, double value) { log.logFormatted(POILogger.DEBUG, "create number row,col,value %,%,%", @@ -968,7 +957,6 @@ public class Sheet implements Model }); NumberRecord rec = new NumberRecord(); - //rec.setRow(( short ) row); rec.setRow(row); rec.setColumn(col); rec.setValue(value); @@ -982,18 +970,14 @@ public class Sheet implements Model * @param row - the row the BlankRecord is a member of * @param col - the column the BlankRecord is a member of */ - - //public BlankRecord createBlank(short row, short col) public BlankRecord createBlank(int row, short col) { - //log.logFormatted(POILogger.DEBUG, "create blank row,col %,%", new short[] log.logFormatted(POILogger.DEBUG, "create blank row,col %,%", new int[] { row, col }); BlankRecord rec = new BlankRecord(); - //rec.setRow(( short ) row); rec.setRow(row); rec.setColumn(col); rec.setXFIndex(( short ) 0x0f); @@ -1009,12 +993,9 @@ public class Sheet implements Model * @param formula - a String representing the formula. To be parsed to PTGs * @return bogus/useless formula record */ - - //public FormulaRecord createFormula(short row, short col, String formula) public FormulaRecord createFormula(int row, short col, String formula) { log.logFormatted(POILogger.DEBUG, "create formula row,col,formula %,%,%", - //new short[] new int[] { row, col @@ -1052,8 +1033,6 @@ public class Sheet implements Model * @param row the row to add the cell value to * @param col the cell value record itself. */ - - //public void addValueRecord(short row, CellValueRecordInterface col) public void addValueRecord(int row, CellValueRecordInterface col) { checkCells(); @@ -1075,29 +1054,6 @@ public class Sheet implements Model d.setFirstCol(col.getColumn()); } cells.insertCell(col); - - /* - * for (int k = loc; k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * if (rec.getSid() == RowRecord.sid) - * { - * RowRecord rowrec = ( RowRecord ) rec; - * - * if (rowrec.getRowNumber() == col.getRow()) - * { - * records.add(k + 1, col); - * loc = k; - * if (rowrec.getLastCol() <= col.getColumn()) - * { - * rowrec.setLastCol((( short ) (col.getColumn() + 1))); - * } - * break; - * } - * } - * } - */ } /** @@ -1109,8 +1065,6 @@ public class Sheet implements Model * @param col - a record supporting the CellValueRecordInterface. * @see org.apache.poi.hssf.record.CellValueRecordInterface */ - - //public void removeValueRecord(short row, CellValueRecordInterface col) public void removeValueRecord(int row, CellValueRecordInterface col) { checkCells(); @@ -1118,27 +1072,6 @@ public class Sheet implements Model new int[]{row, dimsloc} ); loc = dimsloc; cells.removeCell(col); - - /* - * for (int k = loc; k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * // checkDimsLoc(rec,k); - * if (rec.isValue()) - * { - * CellValueRecordInterface cell = - * ( CellValueRecordInterface ) rec; - * - * if ((cell.getRow() == col.getRow()) - * && (cell.getColumn() == col.getColumn())) - * { - * records.remove(k); - * break; - * } - * } - * } - */ } /** @@ -1160,26 +1093,10 @@ public class Sheet implements Model //The ValueRecordsAggregate use a tree map underneath. //The tree Map uses the CellValueRecordInterface as both the //key and the value, if we dont do a remove, then - //the previous instance of the key is retained, effectively using + //the previous instance of the key is retained, effectively using //double the memory cells.removeCell(newval); cells.insertCell(newval); - - /* - * CellValueRecordInterface oldval = getNextValueRecord(); - * - * while (oldval != null) - * { - * if (oldval.isEqual(newval)) - * { - * records.set(( short ) (getLoc() - 1), newval); - * return; - * } - * oldval = getNextValueRecord(); - * } - * addValueRecord(newval.getRow(), newval); - * setLoc(dimsloc); - */ } /** @@ -1218,41 +1135,6 @@ public class Sheet implements Model rows.insertRow(row); - /* - * for (int k = loc; k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * if (rec.getSid() == IndexRecord.sid) - * { - * index = ( IndexRecord ) rec; - * } - * if (rec.getSid() == RowRecord.sid) - * { - * RowRecord rowrec = ( RowRecord ) rec; - * - * if (rowrec.getRowNumber() > row.getRowNumber()) - * { - * records.add(k, row); - * loc = k; - * break; - * } - * } - * if (rec.getSid() == WindowTwoRecord.sid) - * { - * records.add(k, row); - * loc = k; - * break; - * } - * } - * if (index != null) - * { - * if (index.getLastRowAdd1() <= row.getRowNumber()) - * { - * index.setLastRowAdd1(row.getRowNumber() + 1); - * } - * } - */ if (log.check( POILogger.DEBUG )) log.log(POILogger.DEBUG, "exit addRow"); } @@ -1268,33 +1150,9 @@ public class Sheet implements Model public void removeRow(RowRecord row) { checkRows(); - // IndexRecord index = null; setLoc(getDimsLoc()); rows.removeRow(row); - - /* - * for (int k = loc; k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * // checkDimsLoc(rec,k); - * if (rec.getSid() == RowRecord.sid) - * { - * RowRecord rowrec = ( RowRecord ) rec; - * - * if (rowrec.getRowNumber() == row.getRowNumber()) - * { - * records.remove(k); - * break; - * } - * } - * if (rec.getSid() == WindowTwoRecord.sid) - * { - * break; - * } - * } - */ } /** @@ -1325,66 +1183,8 @@ public class Sheet implements Model return null; } return ( CellValueRecordInterface ) valueRecIterator.next(); - - /* - * if (this.getLoc() < records.size()) - * { - * for (int k = getLoc(); k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * this.setLoc(k + 1); - * if (rec instanceof CellValueRecordInterface) - * { - * return ( CellValueRecordInterface ) rec; - * } - * } - * } - * return null; - */ } - /** - * get the NEXT RowRecord or CellValueRecord(from LOC). The first record that - * is a Row record or CellValueRecord(starting at LOC) will be returned. - *

- * This method is "loc" sensitive. Meaning you need to set LOC to where you - * want it to start searching. If you don't know do this: setLoc(getDimsLoc). - * When adding several rows you can just start at the last one by leaving loc - * at what this sets it to. For this method, set loc to dimsloc to start with. - * subsequent calls will return rows in (physical) sequence or NULL when you get to the end. - * - * @return RowRecord representing the next row record or CellValueRecordInterface - * representing the next cellvalue or NULL if there are no more - * @see #setLoc(int) - * - */ - -/* public Record getNextRowOrValue() - { - POILogger.DEBUG((new StringBuffer("getNextRow loc= ")).append(loc) - .toString()); - if (this.getLoc() < records.size()) - { - for (int k = this.getLoc(); k < records.size(); k++) - { - Record rec = ( Record ) records.get(k); - - this.setLoc(k + 1); - if (rec.getSid() == RowRecord.sid) - { - return rec; - } - else if (rec.isValue()) - { - return rec; - } - } - } - return null; - } - */ - /** * get the NEXT RowRecord (from LOC). The first record that is a Row record * (starting at LOC) will be returned. @@ -1413,20 +1213,6 @@ public class Sheet implements Model return null; } return ( RowRecord ) rowRecIterator.next(); - -/* if (this.getLoc() < records.size()) - { - for (int k = this.getLoc(); k < records.size(); k++) - { - Record rec = ( Record ) records.get(k); - - this.setLoc(k + 1); - if (rec.getSid() == RowRecord.sid) - { - return ( RowRecord ) rec; - } - } - }*/ } /** @@ -1445,34 +1231,10 @@ public class Sheet implements Model * @see #setLoc(int) * */ - - //public RowRecord getRow(short rownum) - public RowRecord getRow(int rownum) - { + public RowRecord getRow(int rownum) { if (log.check( POILogger.DEBUG )) log.log(POILogger.DEBUG, "getNextRow loc= " + loc); return rows.getRow(rownum); - - /* - * if (this.getLoc() < records.size()) - * { - * for (int k = this.getLoc(); k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * this.setLoc(k + 1); - * if (rec.getSid() == RowRecord.sid) - * { - * if ((( RowRecord ) rec).getRowNumber() == rownum) - * { - * return ( RowRecord ) rec; - * } - * } - * } - * } - */ - - // return null; } /** @@ -1489,7 +1251,6 @@ public class Sheet implements Model retval.setVersion(( short ) 0x600); retval.setType(( short ) 0x010); - // retval.setBuild((short)0x10d3); retval.setBuild(( short ) 0x0dbb); retval.setBuildYear(( short ) 1996); retval.setHistoryBitMask(0xc1); @@ -1807,7 +1568,7 @@ public class Sheet implements Model * @see org.apache.poi.hssf.record.ColumnInfoRecord * @return record containing a ColumnInfoRecord */ - + // TODO change return type to ColumnInfoRecord protected Record createColInfo() { return ColumnInfoRecordsAggregate.createColInfo(); @@ -1830,12 +1591,12 @@ public class Sheet implements Model public boolean isGridsPrinted() { - if (gridset == null) { - gridset = (GridsetRecord)createGridset(); - //Insert the newlycreated Gridset record at the end of the record (just before the EOF) - int loc = findFirstRecordLocBySid(EOFRecord.sid); - records.add(loc, gridset); - } + if (gridset == null) { + gridset = (GridsetRecord)createGridset(); + //Insert the newlycreated Gridset record at the end of the record (just before the EOF) + int loc = findFirstRecordLocBySid(EOFRecord.sid); + records.add(loc, gridset); + } return !gridset.getGridset(); } @@ -1918,16 +1679,16 @@ public class Sheet implements Model } return retval; } - + /** - * get the index to the ExtendedFormatRecord "associated" with - * the column at specified 0-based index. (In this case, an - * ExtendedFormatRecord index is actually associated with a + * get the index to the ExtendedFormatRecord "associated" with + * the column at specified 0-based index. (In this case, an + * ExtendedFormatRecord index is actually associated with a * ColumnInfoRecord which spans 1 or more columns) *
* Returns the index to the default ExtendedFormatRecord (0xF) * if no ColumnInfoRecord exists that includes the column - * index specified. + * index specified. * @param column * @return index of ExtendedFormatRecord associated with * ColumnInfoRecord that includes the column index or the @@ -2116,38 +1877,38 @@ public class Sheet implements Model retval.setNumRefs(( short ) 0x0); return retval; } - - public short getTopRow() + + public short getTopRow() { - return (windowTwo==null) ? (short) 0 : windowTwo.getTopRow(); + return (windowTwo==null) ? (short) 0 : windowTwo.getTopRow(); } - - public void setTopRow(short topRow) + + public void setTopRow(short topRow) { - if (windowTwo!=null) - { - windowTwo.setTopRow(topRow); - } + if (windowTwo!=null) + { + windowTwo.setTopRow(topRow); + } } - + /** * Sets the left column to show in desktop window pane. * @param leftCol the left column to show in desktop window pane */ public void setLeftCol(short leftCol){ - if (windowTwo!=null) - { - windowTwo.setLeftCol(leftCol); - } + if (windowTwo!=null) + { + windowTwo.setLeftCol(leftCol); + } } - - public short getLeftCol() + + public short getLeftCol() { - return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol(); + return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol(); } - - - + + + /** * Returns the active row * @@ -2162,7 +1923,7 @@ public class Sheet implements Model } return selection.getActiveCellRow(); } - + /** * Sets the active row * @@ -2177,7 +1938,7 @@ public class Sheet implements Model selection.setActiveCellRow(row); } } - + /** * Returns the active column * @@ -2192,7 +1953,7 @@ public class Sheet implements Model } return selection.getActiveCellCol(); } - + /** * Sets the active column * @@ -2278,9 +2039,9 @@ public class Sheet implements Model } // Add space for UncalcedRecord if (uncalced) { - retval += UncalcedRecord.getStaticRecordSize(); + retval += UncalcedRecord.getStaticRecordSize(); } - + return retval; } @@ -2367,7 +2128,7 @@ public class Sheet implements Model */ public HeaderRecord getHeader () { - return header; + return header; } /** @@ -2376,7 +2137,7 @@ public class Sheet implements Model */ public void setHeader (HeaderRecord newHeader) { - header = newHeader; + header = newHeader; } /** @@ -2385,7 +2146,7 @@ public class Sheet implements Model */ public FooterRecord getFooter () { - return footer; + return footer; } /** @@ -2394,7 +2155,7 @@ public class Sheet implements Model */ public void setFooter (FooterRecord newFooter) { - footer = newFooter; + footer = newFooter; } /** @@ -2403,7 +2164,7 @@ public class Sheet implements Model */ public PrintSetupRecord getPrintSetup () { - return printSetup; + return printSetup; } /** @@ -2412,7 +2173,7 @@ public class Sheet implements Model */ public void setPrintSetup (PrintSetupRecord newPrintSetup) { - printSetup = newPrintSetup; + printSetup = newPrintSetup; } /** @@ -2421,7 +2182,7 @@ public class Sheet implements Model */ public PrintGridlinesRecord getPrintGridlines () { - return printGridlines; + return printGridlines; } /** @@ -2430,7 +2191,7 @@ public class Sheet implements Model */ public void setPrintGridlines (PrintGridlinesRecord newPrintGridlines) { - printGridlines = newPrintGridlines; + printGridlines = newPrintGridlines; } /** @@ -2447,23 +2208,23 @@ public class Sheet implements Model * @return the size of the margin */ public double getMargin(short margin) { - if (getMargins()[margin] != null) - return margins[margin].getMargin(); - else { - switch ( margin ) - { - case LeftMargin: - return .75; - case RightMargin: - return .75; - case TopMargin: - return 1.0; - case BottomMargin: - return 1.0; - default : - throw new RuntimeException( "Unknown margin constant: " + margin ); - } - } + if (getMargins()[margin] != null) + return margins[margin].getMargin(); + else { + switch ( margin ) + { + case LeftMargin: + return .75; + case RightMargin: + return .75; + case TopMargin: + return 1.0; + case BottomMargin: + return 1.0; + default : + throw new RuntimeException( "Unknown margin constant: " + margin ); + } + } } /** @@ -2472,32 +2233,32 @@ public class Sheet implements Model * @param size the size of the margin */ public void setMargin(short margin, double size) { - Margin m = getMargins()[margin]; - if (m == null) { - switch ( margin ) - { - case LeftMargin: - m = new LeftMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - case RightMargin: - m = new RightMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - case TopMargin: - m = new TopMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - case BottomMargin: - m = new BottomMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - default : - throw new RuntimeException( "Unknown margin constant: " + margin ); - } - margins[margin] = m; - } - m.setMargin( size ); + Margin m = getMargins()[margin]; + if (m == null) { + switch ( margin ) + { + case LeftMargin: + m = new LeftMarginRecord(); + records.add( getDimsLoc() + 1, m ); + break; + case RightMargin: + m = new RightMarginRecord(); + records.add( getDimsLoc() + 1, m ); + break; + case TopMargin: + m = new TopMarginRecord(); + records.add( getDimsLoc() + 1, m ); + break; + case BottomMargin: + m = new BottomMarginRecord(); + records.add( getDimsLoc() + 1, m ); + break; + default : + throw new RuntimeException( "Unknown margin constant: " + margin ); + } + margins[margin] = m; + } + m.setMargin( size ); } public int getEofLoc() @@ -2514,10 +2275,10 @@ public class Sheet implements Model */ public void createFreezePane(int colSplit, int rowSplit, int topRow, int leftmostColumn ) { - int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); - if (paneLoc != -1) - records.remove(paneLoc); - + int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); + if (paneLoc != -1) + records.remove(paneLoc); + int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); PaneRecord pane = new PaneRecord(); pane.setX((short)colSplit); @@ -2563,10 +2324,10 @@ public class Sheet implements Model */ public void createSplitPane(int xSplitPos, int ySplitPos, int topRow, int leftmostColumn, int activePane ) { - int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); - if (paneLoc != -1) - records.remove(paneLoc); - + int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); + if (paneLoc != -1) + records.remove(paneLoc); + int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); PaneRecord r = new PaneRecord(); r.setX((short)xSplitPos); @@ -2583,7 +2344,7 @@ public class Sheet implements Model sel.setPane(PANE_LOWER_RIGHT); } - + /** * Returns the information regarding the currently configured pane (split or freeze). * @return null if no pane configured, or the pane information. @@ -2592,9 +2353,9 @@ public class Sheet implements Model PaneRecord rec = (PaneRecord)findFirstRecordBySid(PaneRecord.sid); if (rec == null) return null; - + return new PaneInformation(rec.getX(), rec.getY(), rec.getTopRow(), - rec.getLeftColumn(), (byte)rec.getActivePane(), windowTwo.getFreezePanes()); + rec.getLeftColumn(), (byte)rec.getActivePane(), windowTwo.getFreezePanes()); } public SelectionRecord getSelection() @@ -2660,12 +2421,12 @@ public class Sheet implements Model */ public ProtectRecord getProtect() { - if (protect == null) { - protect = (ProtectRecord)createProtect(); - //Insert the newlycreated protect record at the end of the record (just before the EOF) - int loc = findFirstRecordLocBySid(EOFRecord.sid); - records.add(loc, protect); - } + if (protect == null) { + protect = (ProtectRecord)createProtect(); + //Insert the newlycreated protect record at the end of the record (just before the EOF) + int loc = findFirstRecordLocBySid(EOFRecord.sid); + records.add(loc, protect); + } return protect; } @@ -2674,12 +2435,12 @@ public class Sheet implements Model */ public PasswordRecord getPassword() { - if (password == null) { - password = createPassword(); - //Insert the newly created password record at the end of the record (just before the EOF) - int loc = findFirstRecordLocBySid(EOFRecord.sid); - records.add(loc, password); - } + if (password == null) { + password = createPassword(); + //Insert the newly created password record at the end of the record (just before the EOF) + int loc = findFirstRecordLocBySid(EOFRecord.sid); + records.add(loc, password); + } return password; } @@ -2714,7 +2475,7 @@ public class Sheet implements Model * @return whether gridlines are displayed */ public boolean isDisplayGridlines() { - return windowTwo.getDisplayGridlines(); + return windowTwo.getDisplayGridlines(); } /** @@ -2730,7 +2491,7 @@ public class Sheet implements Model * @return whether formulas are displayed */ public boolean isDisplayFormulas() { - return windowTwo.getDisplayFormulas(); + return windowTwo.getDisplayFormulas(); } /** @@ -2746,24 +2507,24 @@ public class Sheet implements Model * @return whether RowColHeadings are displayed */ public boolean isDisplayRowColHeadings() { - return windowTwo.getDisplayRowColHeadings(); + return windowTwo.getDisplayRowColHeadings(); } - + /** - * @return whether an uncalced record must be inserted or not at generation - */ - public boolean getUncalced() { - return uncalced; - } - /** - * @param uncalced whether an uncalced record must be inserted or not at generation - */ - public void setUncalced(boolean uncalced) { - this.uncalced = uncalced; - } + * @return whether an uncalced record must be inserted or not at generation + */ + public boolean getUncalced() { + return uncalced; + } + /** + * @param uncalced whether an uncalced record must be inserted or not at generation + */ + public void setUncalced(boolean uncalced) { + this.uncalced = uncalced; + } - /** + /** * Returns the array of margins. If not created, will create. * * @return the array of marings. @@ -2771,7 +2532,7 @@ public class Sheet implements Model protected Margin[] getMargins() { if (margins == null) margins = new Margin[4]; - return margins; + return margins; } /** @@ -2789,11 +2550,11 @@ public class Sheet implements Model boolean noDrawingRecordsFound = (loc == -1); if (noDrawingRecordsFound) { - if(!createIfMissing) { - // None found, and not allowed to add in - return -1; - } - + if(!createIfMissing) { + // None found, and not allowed to add in + return -1; + } + EscherAggregate aggregate = new EscherAggregate( drawingManager ); loc = findFirstRecordLocBySid(EscherAggregate.sid); if (loc == -1) @@ -2847,43 +2608,43 @@ public class Sheet implements Model * @param breaks The page record to be shifted * @param start Starting "main" value to shift breaks * @param stop Ending "main" value to shift breaks - * @param count number of units (rows/columns) to shift by + * @param count number of units (rows/columns) to shift by */ public void shiftBreaks(PageBreakRecord breaks, short start, short stop, int count) { - - if(rowBreaks == null) - return; - Iterator iterator = breaks.getBreaksIterator(); - List shiftedBreak = new ArrayList(); - while(iterator.hasNext()) - { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - short breakLocation = breakItem.main; - boolean inStart = (breakLocation >= start); - boolean inEnd = (breakLocation <= stop); - if(inStart && inEnd) - shiftedBreak.add(breakItem); - } - - iterator = shiftedBreak.iterator(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - breaks.removeBreak(breakItem.main); - breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo); - } + + if(rowBreaks == null) + return; + Iterator iterator = breaks.getBreaksIterator(); + List shiftedBreak = new ArrayList(); + while(iterator.hasNext()) + { + PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); + short breakLocation = breakItem.main; + boolean inStart = (breakLocation >= start); + boolean inEnd = (breakLocation <= stop); + if(inStart && inEnd) + shiftedBreak.add(breakItem); + } + + iterator = shiftedBreak.iterator(); + while (iterator.hasNext()) { + PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); + breaks.removeBreak(breakItem.main); + breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo); + } } - + /** * Sets a page break at the indicated row * @param row */ - public void setRowBreak(int row, short fromCol, short toCol) { - if (rowBreaks == null) { + public void setRowBreak(int row, short fromCol, short toCol) { + if (rowBreaks == null) { int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); rowBreaks = new PageBreakRecord(PageBreakRecord.HORIZONTAL_SID); records.add(loc, rowBreaks); - } - rowBreaks.addBreak((short)row, fromCol, toCol); + } + rowBreaks.addBreak((short)row, fromCol, toCol); } /** @@ -2891,9 +2652,9 @@ public class Sheet implements Model * @param row */ public void removeRowBreak(int row) { - if (rowBreaks == null) - throw new IllegalArgumentException("Sheet does not define any row breaks"); - rowBreaks.removeBreak((short)row); + if (rowBreaks == null) + throw new IllegalArgumentException("Sheet does not define any row breaks"); + rowBreaks.removeBreak((short)row); } /** @@ -2902,7 +2663,7 @@ public class Sheet implements Model * @return true if the specified row has a page break */ public boolean isRowBroken(int row) { - return (rowBreaks == null) ? false : rowBreaks.getBreak((short)row) != null; + return (rowBreaks == null) ? false : rowBreaks.getBreak((short)row) != null; } /** @@ -2910,12 +2671,12 @@ public class Sheet implements Model * */ public void setColumnBreak(short column, short fromRow, short toRow) { - if (colBreaks == null) { + if (colBreaks == null) { int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); colBreaks = new PageBreakRecord(PageBreakRecord.VERTICAL_SID); records.add(loc, colBreaks); - } - colBreaks.addBreak(column, fromRow, toRow); + } + colBreaks.addBreak(column, fromRow, toRow); } /** @@ -2923,10 +2684,10 @@ public class Sheet implements Model * */ public void removeColumnBreak(short column) { - if (colBreaks == null) - throw new IllegalArgumentException("Sheet does not define any column breaks"); - - colBreaks.removeBreak(column); + if (colBreaks == null) + throw new IllegalArgumentException("Sheet does not define any column breaks"); + + colBreaks.removeBreak(column); } /** @@ -2935,9 +2696,9 @@ public class Sheet implements Model * @return true if the specified column has a page break */ public boolean isColumnBroken(short column) { - return (colBreaks == null) ? false : colBreaks.getBreak(column) != null; + return (colBreaks == null) ? false : colBreaks.getBreak(column) != null; } - + /** * Shifts the horizontal page breaks for the indicated count * @param startingRow @@ -2945,7 +2706,7 @@ public class Sheet implements Model * @param count */ public void shiftRowBreaks(int startingRow, int endingRow, int count) { - shiftBreaks(rowBreaks, (short)startingRow, (short)endingRow, (short)count); + shiftBreaks(rowBreaks, (short)startingRow, (short)endingRow, (short)count); } /** @@ -2955,39 +2716,39 @@ public class Sheet implements Model * @param count */ public void shiftColumnBreaks(short startingCol, short endingCol, short count) { - shiftBreaks(colBreaks, startingCol, endingCol, count); + shiftBreaks(colBreaks, startingCol, endingCol, count); } - + /** * Returns all the row page breaks * @return all the row page breaks */ public Iterator getRowBreaks() { - return rowBreaks.getBreaksIterator(); + return rowBreaks.getBreaksIterator(); } - + /** * Returns the number of row page breaks * @return the number of row page breaks */ public int getNumRowBreaks(){ - return (rowBreaks == null) ? 0 : (int)rowBreaks.getNumBreaks(); + return (rowBreaks == null) ? 0 : (int)rowBreaks.getNumBreaks(); } - + /** * Returns all the column page breaks * @return all the column page breaks */ public Iterator getColumnBreaks(){ - return colBreaks.getBreaksIterator(); + return colBreaks.getBreaksIterator(); } - + /** * Returns the number of column page breaks * @return the number of column page breaks */ public int getNumColumnBreaks(){ - return (colBreaks == null) ? 0 : (int)colBreaks.getNumBreaks(); + return (colBreaks == null) ? 0 : (int)colBreaks.getNumBreaks(); } public void setColumnGroupCollapsed( short columnNumber, boolean collapsed ) @@ -3030,213 +2791,40 @@ public class Sheet implements Model records.add(protIdx+2,srec); scenprotect = srec; } - } + } /** - * unprotect objects in the sheet (will not protect them, but any set to false are + * unprotect objects in the sheet (will not protect them, but any set to false are * unprotected. * @param sheet is unprotected (false = unprotect) * @param objects are unprotected (false = unprotect) * @param scenarios are unprotected (false = unprotect) */ public void unprotectSheet( boolean sheet, boolean objects, boolean scenarios ) { - int protIdx = -1; + if (!sheet) { ProtectRecord prec = getProtect(); prec.setProtect(sheet); PasswordRecord pass = getPassword(); pass.setPassword((short)00); - } + } if(objprotect != null && !objects) { objprotect.setProtect(false); } if(scenprotect != null && !scenarios) { scenprotect.setProtect(false); } - } + } /** * @return {sheet is protected, objects are proteced, scenarios are protected} */ public boolean[] isProtected() { - return new boolean[] { (protect != null && protect.getProtect()), + return new boolean[] { (protect != null && protect.getProtect()), (objprotect != null && objprotect.getProtect()), (scenprotect != null && scenprotect.getProtect())}; } - -// private void collapseColumn( short columnNumber ) -// { -// int idx = findColumnIdx( columnNumber, 0 ); -// if (idx == -1) -// return; -// -// // Find the start of the group. -// ColumnInfoRecord columnInfo = (ColumnInfoRecord) columnSizes.get( findStartOfColumnOutlineGroup( idx ) ); -// -// // Hide all the columns until the end of the group -// columnInfo = writeHidden( columnInfo, idx, true ); -// -// // Write collapse field -// setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, Boolean.TRUE); -// } -// private void expandColumn( short columnNumber ) -// { -// int idx = findColumnIdx( columnNumber, 0 ); -// if (idx == -1) -// return; -// -// // If it is already exapanded do nothing. -// if (!isColumnGroupCollapsed(idx)) -// return; -// -// // Find the start of the group. -// int startIdx = findStartOfColumnOutlineGroup( idx ); -// ColumnInfoRecord columnInfo = getColInfo( startIdx ); -// -// // Find the end of the group. -// int endIdx = findEndOfColumnOutlineGroup( idx ); -// ColumnInfoRecord endColumnInfo = getColInfo( endIdx ); -// -// // expand: -// // colapsed bit must be unset -// // hidden bit gets unset _if_ surrounding groups are expanded you can determine -// // this by looking at the hidden bit of the enclosing group. You will have -// // to look at the start and the end of the current group to determine which -// // is the enclosing group -// // hidden bit only is altered for this outline level. ie. don't uncollapse contained groups -// if (!isColumnGroupHiddenByParent( idx )) -// { -// for (int i = startIdx; i <= endIdx; i++) -// { -// if (columnInfo.getOutlineLevel() == getColInfo(i).getOutlineLevel()) -// getColInfo(i).setHidden( false ); -// } -// } -// -// // Write collapse field -// setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, Boolean.FALSE); -// } - -// private boolean isColumnGroupCollapsed( int idx ) -// { -// int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx ); -// if (endOfOutlineGroupIdx >= columnSizes.size()) -// return false; -// if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn()) -// return false; -// else -// return getColInfo(endOfOutlineGroupIdx+1).getCollapsed(); -// } - -// private boolean isColumnGroupHiddenByParent( int idx ) -// { -// // Look out outline details of end -// int endLevel; -// boolean endHidden; -// int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx ); -// if (endOfOutlineGroupIdx >= columnSizes.size()) -// { -// endLevel = 0; -// endHidden = false; -// } -// else if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn()) -// { -// endLevel = 0; -// endHidden = false; -// } -// else -// { -// endLevel = getColInfo( endOfOutlineGroupIdx + 1).getOutlineLevel(); -// endHidden = getColInfo( endOfOutlineGroupIdx + 1).getHidden(); -// } -// -// // Look out outline details of start -// int startLevel; -// boolean startHidden; -// int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx ); -// if (startOfOutlineGroupIdx <= 0) -// { -// startLevel = 0; -// startHidden = false; -// } -// else if (getColInfo(startOfOutlineGroupIdx).getFirstColumn() - 1 != getColInfo(startOfOutlineGroupIdx - 1).getLastColumn()) -// { -// startLevel = 0; -// startHidden = false; -// } -// else -// { -// startLevel = getColInfo( startOfOutlineGroupIdx - 1).getOutlineLevel(); -// startHidden = getColInfo( startOfOutlineGroupIdx - 1 ).getHidden(); -// } -// -// if (endLevel > startLevel) -// { -// return endHidden; -// } -// else -// { -// return startHidden; -// } -// } - -// private ColumnInfoRecord getColInfo(int idx) -// { -// return columns.getColInfo( idx ); -// } - -// private int findStartOfColumnOutlineGroup(int idx) -// { -// // Find the start of the group. -// ColumnInfoRecord columnInfo = (ColumnInfoRecord) columnSizes.get( idx ); -// int level = columnInfo.getOutlineLevel(); -// while (idx != 0) -// { -// ColumnInfoRecord prevColumnInfo = (ColumnInfoRecord) columnSizes.get( idx - 1 ); -// if (columnInfo.getFirstColumn() - 1 == prevColumnInfo.getLastColumn()) -// { -// if (prevColumnInfo.getOutlineLevel() < level) -// { -// break; -// } -// idx--; -// columnInfo = prevColumnInfo; -// } -// else -// { -// break; -// } -// } -// -// return idx; -// } - -// private int findEndOfColumnOutlineGroup(int idx) -// { -// // Find the end of the group. -// ColumnInfoRecord columnInfo = (ColumnInfoRecord) columnSizes.get( idx ); -// int level = columnInfo.getOutlineLevel(); -// while (idx < columnSizes.size() - 1) -// { -// ColumnInfoRecord nextColumnInfo = (ColumnInfoRecord) columnSizes.get( idx + 1 ); -// if (columnInfo.getLastColumn() + 1 == nextColumnInfo.getFirstColumn()) -// { -// if (nextColumnInfo.getOutlineLevel() < level) -// { -// break; -// } -// idx++; -// columnInfo = nextColumnInfo; -// } -// else -// { -// break; -// } -// } -// -// return idx; -// } public void groupRowRange(int fromRow, int toRow, boolean indent) { @@ -3272,8 +2860,8 @@ public class Sheet implements Model // Grab the guts record, adding if needed GutsRecord guts = (GutsRecord) findFirstRecordBySid( GutsRecord.sid ); if(guts == null) { - guts = new GutsRecord(); - records.add(guts); + guts = new GutsRecord(); + records.add(guts); } // Set the levels onto it guts.setRowLevelMax( (short) ( maxLevel + 1 ) ); @@ -3291,126 +2879,4 @@ public class Sheet implements Model rows.expandRow( row ); } } - - -// private void collapseRow( int rowNumber ) -// { -// -// // Find the start of the group. -// int startRow = rows.findStartOfRowOutlineGroup( rowNumber ); -// RowRecord rowRecord = (RowRecord) rows.getRow( startRow ); -// -// // Hide all the columns until the end of the group -// int lastRow = rows.writeHidden( rowRecord, startRow, true ); -// -// // Write collapse field -// if (getRow(lastRow + 1) != null) -// { -// getRow(lastRow + 1).setColapsed( true ); -// } -// else -// { -// RowRecord row = createRow( lastRow + 1); -// row.setColapsed( true ); -// rows.insertRow( row ); -// } -// } - -// private int findStartOfRowOutlineGroup(int row) -// { -// // Find the start of the group. -// RowRecord rowRecord = rows.getRow( row ); -// int level = rowRecord.getOutlineLevel(); -// int currentRow = row; -// while (rows.getRow( currentRow ) != null) -// { -// rowRecord = rows.getRow( currentRow ); -// if (rowRecord.getOutlineLevel() < level) -// return currentRow + 1; -// currentRow--; -// } -// -// return currentRow + 1; -// } - -// private int writeHidden( RowRecord rowRecord, int row, boolean hidden ) -// { -// int level = rowRecord.getOutlineLevel(); -// while (rowRecord != null && rows.getRow(row).getOutlineLevel() >= level) -// { -// rowRecord.setZeroHeight( hidden ); -// row++; -// rowRecord = rows.getRow( row ); -// } -// return row - 1; -// } - -// private int findEndOfRowOutlineGroup( int row ) -// { -// int level = getRow( row ).getOutlineLevel(); -// int currentRow; -// for (currentRow = row; currentRow < rows.getLastRowNum(); currentRow++) -// { -// if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level) -// { -// break; -// } -// } -// -// return currentRow-1; -// } - -// private boolean isRowGroupCollapsed( int row ) -// { -// int collapseRow = rows.findEndOfRowOutlineGroup( row ) + 1; -// -// if (getRow(collapseRow) == null) -// return false; -// else -// return getRow( collapseRow ).getColapsed(); -// } - - -// private boolean isRowGroupHiddenByParent( int row ) -// { -// // Look out outline details of end -// int endLevel; -// boolean endHidden; -// int endOfOutlineGroupIdx = rows.findEndOfRowOutlineGroup( row ); -// if (getRow( endOfOutlineGroupIdx + 1 ) == null) -// { -// endLevel = 0; -// endHidden = false; -// } -// else -// { -// endLevel = getRow( endOfOutlineGroupIdx + 1).getOutlineLevel(); -// endHidden = getRow( endOfOutlineGroupIdx + 1).getZeroHeight(); -// } -// -// // Look out outline details of start -// int startLevel; -// boolean startHidden; -// int startOfOutlineGroupIdx = rows.findStartOfRowOutlineGroup( row ); -// if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null) -// { -// startLevel = 0; -// startHidden = false; -// } -// else -// { -// startLevel = getRow( startOfOutlineGroupIdx - 1).getOutlineLevel(); -// startHidden = getRow( startOfOutlineGroupIdx - 1 ).getZeroHeight(); -// } -// -// if (endLevel > startLevel) -// { -// return endHidden; -// } -// else -// { -// return startHidden; -// } -// } - } diff --git a/src/java/org/apache/poi/hssf/record/RowRecord.java b/src/java/org/apache/poi/hssf/record/RowRecord.java index a2815d287..cbfc0ec59 100644 --- a/src/java/org/apache/poi/hssf/record/RowRecord.java +++ b/src/java/org/apache/poi/hssf/record/RowRecord.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -15,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.record; @@ -31,20 +29,18 @@ import org.apache.poi.util.LittleEndian; * @author Jason Height (jheight at chariot dot net dot au) * @version 2.0-pre */ - -public class RowRecord - extends Record - implements Comparable -{ - public final static short sid = 0x208; +public final class RowRecord extends Record implements Comparable { + public final static short sid = 0x208; - /** The maximum row number that excel can handle (zero bazed) ie 65536 rows is + private static final int OPTION_BITS_ALWAYS_SET = 0x0100; + private static final int DEFAULT_HEIGHT_BIT = 0x8000; + + /** The maximum row number that excel can handle (zero based) ie 65536 rows is * max number of rows. */ public final static int MAX_ROW_NUMBER = 65535; - //private short field_1_row_number; - private int field_1_row_number; + private int field_1_row_number; private short field_2_first_col; private short field_3_last_col; // plus 1 private short field_4_height; @@ -52,7 +48,8 @@ public class RowRecord // for generated sheets. private short field_6_reserved; - private short field_7_option_flags; + /** 16 bit options flags */ + private int field_7_option_flags; private static final BitField outlineLevel = BitFieldFactory.getInstance(0x07); // bit 3 reserved @@ -62,8 +59,17 @@ public class RowRecord private static final BitField formatted = BitFieldFactory.getInstance(0x80); private short field_8_xf_index; // only if isFormatted - public RowRecord() - { + public RowRecord(int rowNumber) { + field_1_row_number = rowNumber; + field_2_first_col = -1; + field_3_last_col = -1; + field_4_height = (short)DEFAULT_HEIGHT_BIT; + field_4_height = (short)DEFAULT_HEIGHT_BIT; + field_5_optimize = ( short ) 0; + field_6_reserved = ( short ) 0; + field_7_option_flags = OPTION_BITS_ALWAYS_SET; // seems necessary for outlining + + field_8_xf_index = ( short ) 0xf; } /** @@ -86,7 +92,6 @@ public class RowRecord protected void fillFields(RecordInputStream in) { - //field_1_row_number = LittleEndian.getShort(data, 0 + offset); field_1_row_number = in.readUShort(); field_2_first_col = in.readShort(); field_3_last_col = in.readShort(); @@ -156,7 +161,7 @@ public class RowRecord public void setOptionFlags(short options) { - field_7_option_flags = options; + field_7_option_flags = options | OPTION_BITS_ALWAYS_SET; } // option bitfields @@ -169,20 +174,18 @@ public class RowRecord public void setOutlineLevel(short ol) { - field_7_option_flags = - outlineLevel.setShortValue(field_7_option_flags, ol); + field_7_option_flags = outlineLevel.setValue(field_7_option_flags, ol); } /** - * set whether or not to colapse this row - * @param c - colapse or not + * set whether or not to collapse this row + * @param c - collapse or not * @see #setOptionFlags(short) */ public void setColapsed(boolean c) { - field_7_option_flags = colapsed.setShortBoolean(field_7_option_flags, - c); + field_7_option_flags = colapsed.setBoolean(field_7_option_flags, c); } /** @@ -193,8 +196,7 @@ public class RowRecord public void setZeroHeight(boolean z) { - field_7_option_flags = - zeroHeight.setShortBoolean(field_7_option_flags, z); + field_7_option_flags = zeroHeight.setBoolean(field_7_option_flags, z); } /** @@ -205,8 +207,7 @@ public class RowRecord public void setBadFontHeight(boolean f) { - field_7_option_flags = - badFontHeight.setShortBoolean(field_7_option_flags, f); + field_7_option_flags = badFontHeight.setBoolean(field_7_option_flags, f); } /** @@ -217,8 +218,7 @@ public class RowRecord public void setFormatted(boolean f) { - field_7_option_flags = formatted.setShortBoolean(field_7_option_flags, - f); + field_7_option_flags = formatted.setBoolean(field_7_option_flags, f); } // end bitfields @@ -293,7 +293,7 @@ public class RowRecord public short getOptionFlags() { - return field_7_option_flags; + return (short)field_7_option_flags; } // option bitfields @@ -306,7 +306,7 @@ public class RowRecord public short getOutlineLevel() { - return outlineLevel.getShortValue(field_7_option_flags); + return (short)outlineLevel.getValue(field_7_option_flags); } /** @@ -410,7 +410,6 @@ public class RowRecord { LittleEndian.putShort(data, 0 + offset, sid); LittleEndian.putShort(data, 2 + offset, ( short ) 16); - //LittleEndian.putShort(data, 4 + offset, getRowNumber()); LittleEndian.putShort(data, 4 + offset, ( short ) getRowNumber()); LittleEndian.putShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol()); LittleEndian.putShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol()); @@ -419,7 +418,6 @@ public class RowRecord LittleEndian.putShort(data, 14 + offset, field_6_reserved); LittleEndian.putShort(data, 16 + offset, getOptionFlags()); -// LittleEndian.putShort(data,18,getOutlineLevel()); LittleEndian.putShort(data, 18 + offset, getXFIndex()); return getRecordSize(); } @@ -469,8 +467,7 @@ public class RowRecord } public Object clone() { - RowRecord rec = new RowRecord(); - rec.field_1_row_number = field_1_row_number; + RowRecord rec = new RowRecord(field_1_row_number); rec.field_2_first_col = field_2_first_col; rec.field_3_last_col = field_3_last_col; rec.field_4_height = field_4_height; 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 bed1f0748..65af632d3 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java @@ -35,19 +35,17 @@ import java.util.TreeMap; * @author Jason Height (jheight at chariot dot net dot au) */ -public class RowRecordsAggregate - extends Record -{ - int firstrow = -1; - int lastrow = -1; - Map records = null; - int size = 0; +public final class RowRecordsAggregate extends Record { + private int firstrow = -1; + private int lastrow = -1; + private Map records = null; // TODO - use a proper key in this map + private int size = 0; /** Creates a new instance of ValueRecordsAggregate */ public RowRecordsAggregate() { - records = new TreeMap(); + records = new TreeMap(); } public void insertRow(RowRecord row) @@ -74,15 +72,13 @@ public class RowRecordsAggregate records.remove(row); } - public RowRecord getRow(int rownum) - { - // Row must be between 0 and 65535 - if(rownum < 0 || rownum > 65535) { - throw new IllegalArgumentException("The row number must be between 0 and 65535"); - } + public RowRecord getRow(int rownum) { + // Row must be between 0 and 65535 + if(rownum < 0 || rownum > 65535) { + throw new IllegalArgumentException("The row number must be between 0 and 65535"); + } - RowRecord row = new RowRecord(); - row.setRowNumber(rownum); + RowRecord row = new RowRecord(rownum); return ( RowRecord ) records.get(row); } @@ -333,7 +329,7 @@ public class RowRecordsAggregate // Find the start of the group. int startRow = findStartOfRowOutlineGroup( rowNumber ); - RowRecord rowRecord = (RowRecord) getRow( startRow ); + RowRecord rowRecord = getRow( startRow ); // Hide all the columns until the end of the group int lastRow = writeHidden( rowRecord, startRow, true ); @@ -358,17 +354,8 @@ public class RowRecordsAggregate * @return RowRecord created for the passed in row number * @see org.apache.poi.hssf.record.RowRecord */ - public static RowRecord createRow(int row) - { - RowRecord rowrec = new RowRecord(); - - //rowrec.setRowNumber(( short ) row); - rowrec.setRowNumber(row); - rowrec.setHeight(( short ) 0xff); - rowrec.setOptimize(( short ) 0x0); - rowrec.setOptionFlags(( short ) 0x100); // seems necessary for outlining - rowrec.setXFIndex(( short ) 0xf); - return rowrec; + public static RowRecord createRow(int rowNumber) { + return new RowRecord(rowNumber); } public boolean isRowGroupCollapsed( int row ) @@ -399,12 +386,12 @@ public class RowRecordsAggregate int endIdx = findEndOfRowOutlineGroup( idx ); // expand: - // colapsed bit must be unset + // collapsed bit must be unset // hidden bit gets unset _if_ surrounding groups are expanded you can determine // this by looking at the hidden bit of the enclosing group. You will have // to look at the start and the end of the current group to determine which // is the enclosing group - // hidden bit only is altered for this outline level. ie. don't uncollapse contained groups + // hidden bit only is altered for this outline level. ie. don't un-collapse contained groups if ( !isRowGroupHiddenByParent( idx ) ) { for ( int i = startIdx; i <= endIdx; i++ ) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java index 1b83bced9..def79f6d3 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java @@ -21,7 +21,6 @@ import java.util.Iterator; import java.util.NoSuchElementException; 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; @@ -37,11 +36,9 @@ public final class HSSFRow implements Comparable { // used for collections public final static int INITIAL_CAPACITY = 5; - //private short rowNum; + private int rowNum; private HSSFCell[] cells=new HSSFCell[INITIAL_CAPACITY]; -// private short firstcell = -1; -// private short lastcell = -1; /** * reference to low level representation @@ -61,7 +58,8 @@ public final class HSSFRow implements Comparable { private Sheet sheet; - protected HSSFRow() + // TODO - ditch this constructor + HSSFRow() { } @@ -73,18 +71,12 @@ public final class HSSFRow implements Comparable { * @param rowNum the row number of this row (0 based) * @see org.apache.poi.hssf.usermodel.HSSFSheet#createRow(int) */ - - //protected HSSFRow(Workbook book, Sheet sheet, short rowNum) - protected HSSFRow(HSSFWorkbook book, Sheet sheet, int rowNum) + HSSFRow(HSSFWorkbook book, Sheet sheet, int rowNum) { this.rowNum = rowNum; this.book = book; this.sheet = sheet; - row = new RowRecord(); - row.setOptionFlags( (short)0x100 ); // seems necessary for outlining to work. - row.setHeight((short) 0xff); - row.setLastCol((short) -1); - row.setFirstCol((short) -1); + row = new RowRecord(rowNum); setRowNum(rowNum); } @@ -98,8 +90,7 @@ public final class HSSFRow implements Comparable { * @param record the low level api object this row should represent * @see org.apache.poi.hssf.usermodel.HSSFSheet#createRow(int) */ - - protected HSSFRow(HSSFWorkbook book, Sheet sheet, RowRecord record) + HSSFRow(HSSFWorkbook book, Sheet sheet, RowRecord record) { this.book = book; this.sheet = sheet; @@ -200,12 +191,11 @@ public final class HSSFRow implements Comparable { * @param rowNum the row number (0-based) * @throws IndexOutOfBoundsException if the row number is not within the range 0-65535. */ - - //public void setRowNum(short rowNum) - public void setRowNum(int rowNum) - { - if ((rowNum < 0) || (rowNum > RowRecord.MAX_ROW_NUMBER)) - throw new IndexOutOfBoundsException("Row number must be between 0 and "+RowRecord.MAX_ROW_NUMBER+", was <"+rowNum+">"); + public void setRowNum(int rowNum) { + if ((rowNum < 0) || (rowNum > RowRecord.MAX_ROW_NUMBER)) { + throw new IllegalArgumentException("Invalid row number (" + rowNum + + ") outside allowable range (0.." + RowRecord.MAX_ROW_NUMBER + ")"); + } this.rowNum = rowNum; if (row != null) { @@ -217,8 +207,6 @@ public final class HSSFRow implements Comparable { * get row number this row represents * @return the row number (0 based) */ - - //public short getRowNum() public int getRowNum() { return rowNum; diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index 6d817a1ed..e8855e65e 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -136,6 +136,7 @@ public final class HSSFSheet { { int sloc = sheet.getLoc(); RowRecord row = sheet.getNextRow(); + boolean rowRecordsAlreadyPresent = row!=null; while (row != null) { @@ -160,6 +161,18 @@ public final class HSSFSheet { if ( ( lastrow == null ) || ( lastrow.getRowNum() != cval.getRow() ) ) { hrow = getRow( cval.getRow() ); + if (hrow == null) { + // Some tools (like Perl module Spreadsheet::WriteExcel - bug 41187) skip the RowRecords + // Excel, OpenOffice.org and GoogleDocs are all OK with this, so POI should be too. + if (rowRecordsAlreadyPresent) { + // if at least one row record is present, all should be present. + throw new RuntimeException("Unexpected missing row when some rows already present"); + } + // create the row record on the fly now. + RowRecord rowRec = new RowRecord(cval.getRow()); + sheet.addRow(rowRec); + hrow = createRowFromRecord(rowRec); + } } if ( hrow != null ) { diff --git a/src/testcases/org/apache/poi/hssf/HSSFTests.java b/src/testcases/org/apache/poi/hssf/HSSFTests.java index 5b597a67c..0a4fa66af 100644 --- a/src/testcases/org/apache/poi/hssf/HSSFTests.java +++ b/src/testcases/org/apache/poi/hssf/HSSFTests.java @@ -22,9 +22,7 @@ import junit.framework.TestSuite; import org.apache.poi.hssf.eventmodel.TestEventRecordFactory; import org.apache.poi.hssf.eventmodel.TestModelFactory; -import org.apache.poi.hssf.model.TestDrawingManager; -import org.apache.poi.hssf.model.TestFormulaParser; -import org.apache.poi.hssf.model.TestSheet; +import org.apache.poi.hssf.model.AllModelTests; import org.apache.poi.hssf.record.AllRecordTests; import org.apache.poi.hssf.usermodel.AllUserModelTests; import org.apache.poi.hssf.util.TestAreaReference; @@ -50,10 +48,10 @@ public final class HSSFTests { TestSuite suite = new TestSuite("Tests for org.apache.poi.hssf"); // $JUnit-BEGIN$ + suite.addTest(AllModelTests.suite()); suite.addTest(AllUserModelTests.suite()); suite.addTest(AllRecordTests.suite()); - suite.addTest(new TestSuite(TestFormulaParser.class)); suite.addTest(new TestSuite(TestAreaReference.class)); suite.addTest(new TestSuite(TestCellReference.class)); suite.addTest(new TestSuite(TestRangeAddress.class)); @@ -61,8 +59,6 @@ public final class HSSFTests { suite.addTest(new TestSuite(TestSheetReferences.class)); suite.addTest(new TestSuite(TestEventRecordFactory.class)); suite.addTest(new TestSuite(TestModelFactory.class)); - suite.addTest(new TestSuite(TestDrawingManager.class)); - suite.addTest(new TestSuite(TestSheet.class)); // $JUnit-END$ return suite; } diff --git a/src/testcases/org/apache/poi/hssf/data/ex41187-19267.xls b/src/testcases/org/apache/poi/hssf/data/ex41187-19267.xls new file mode 100644 index 000000000..c07bfca59 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/ex41187-19267.xls differ diff --git a/src/testcases/org/apache/poi/hssf/model/AllModelTests.java b/src/testcases/org/apache/poi/hssf/model/AllModelTests.java new file mode 100755 index 000000000..19ef43706 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/model/AllModelTests.java @@ -0,0 +1,40 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.model; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Collects all tests for org.apache.poi.hssf.model. + * + * @author Josh Micich + */ +public final class AllModelTests { + + public static Test suite() { + TestSuite result = new TestSuite(AllModelTests.class.getName()); + result.addTestSuite(TestDrawingManager.class); + result.addTestSuite(TestDrawingManager2.class); + result.addTestSuite(TestFormulaParser.class); + result.addTestSuite(TestFormulaParserEval.class); + result.addTestSuite(TestSheet.class); + result.addTestSuite(TestSheetAdditional.class); + return result; + } +} diff --git a/src/testcases/org/apache/poi/hssf/model/TestSheet.java b/src/testcases/org/apache/poi/hssf/model/TestSheet.java index 964caedc2..9281eb80d 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestSheet.java +++ b/src/testcases/org/apache/poi/hssf/model/TestSheet.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -15,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.model; @@ -34,8 +32,7 @@ import java.util.List; * * @author Glen Stampoultzis (glens at apache.org) */ -public class TestSheet extends TestCase -{ +public final class TestSheet extends TestCase { public void testCreateSheet() throws Exception { // Check we're adding row and cell aggregates @@ -76,6 +73,21 @@ public class TestSheet extends TestCase if ((regionsToAdd % 1027) != 0) recordsExpected++; assertTrue("The " + regionsToAdd + " merged regions should have been spread out over " + recordsExpected + " records, not " + recordsAdded, recordsAdded == recordsExpected); + // Check we can't add one with invalid date + try { + sheet.addMergedRegion(10, (short)10, 9, (short)12); + fail("Expected an exception to occur"); + } catch(IllegalArgumentException e) { + // occurs during successful test + assertEquals("The 'to' row (9) must not be less than the 'from' row (10)", e.getMessage()); + } + try { + sheet.addMergedRegion(10, (short)10, 12, (short)9); + fail("Expected an exception to occur"); + } catch(IllegalArgumentException e) { + // occurs during successful test + assertEquals("The 'to' col (9) must not be less than the 'from' col (10)", e.getMessage()); + } } public void testRemoveMergedRegion() @@ -113,9 +125,9 @@ public class TestSheet extends TestCase MergeCellsRecord merged = new MergeCellsRecord(); merged.addArea(0, (short)0, 1, (short)2); - records.add(new RowRecord()); - records.add(new RowRecord()); - records.add(new RowRecord()); + records.add(new RowRecord(0)); + records.add(new RowRecord(1)); + records.add(new RowRecord(2)); records.add(merged); Sheet sheet = Sheet.createSheet(records, 0); @@ -142,20 +154,11 @@ public class TestSheet extends TestCase */ public void testRowAggregation() { List records = new ArrayList(); - RowRecord row = new RowRecord(); - row.setRowNumber(0); - records.add(row); - - row = new RowRecord(); - row.setRowNumber(1); - records.add(row); + records.add(new RowRecord(0)); + records.add(new RowRecord(1)); records.add(new StringRecord()); - - row = new RowRecord(); - row.setRowNumber(2); - records.add(row); - + records.add(new RowRecord(2)); Sheet sheet = Sheet.createSheet(records, 0); assertNotNull("Row [2] was skipped", sheet.getRow(2)); @@ -197,9 +200,9 @@ public class TestSheet extends TestCase Iterator iterator = sheet.getRowBreaks(); while (iterator.hasNext()) { PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; + int main = breakItem.main; if (main != 0 && main != 10 && main != 11) fail("Invalid page break"); - if (main == 0) is0 = true; + if (main == 0) is0 = true; if (main == 10) is10= true; if (main == 11) is11 = true; } @@ -216,8 +219,6 @@ public class TestSheet extends TestCase assertFalse("row should be removed", sheet.isRowBroken(10)); assertEquals("no more breaks", 0, sheet.getNumRowBreaks()); - - } /** @@ -256,10 +257,10 @@ public class TestSheet extends TestCase Iterator iterator = sheet.getColumnBreaks(); while (iterator.hasNext()) { PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; + int main = breakItem.main; if (main != 0 && main != 1 && main != 10 && main != 15) fail("Invalid page break"); - if (main == 0) is0 = true; - if (main == 1) is1 = true; + if (main == 0) is0 = true; + if (main == 1) is1 = true; if (main == 10) is10= true; if (main == 15) is15 = true; } @@ -286,72 +287,69 @@ public class TestSheet extends TestCase * works as designed. */ public void testXFIndexForColumn() { - try{ - final short TEST_IDX = 10; - final short DEFAULT_IDX = 0xF; // 15 - short xfindex = Short.MIN_VALUE; - Sheet sheet = Sheet.createSheet(); - - // without ColumnInfoRecord - xfindex = sheet.getXFIndexForColAt((short) 0); - assertEquals(DEFAULT_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 1); - assertEquals(DEFAULT_IDX, xfindex); - - ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo(); - sheet.columns.insertColumn(nci); - - // single column ColumnInfoRecord - nci.setFirstColumn((short) 2); - nci.setLastColumn((short) 2); - nci.setXFIndex(TEST_IDX); - xfindex = sheet.getXFIndexForColAt((short) 0); - assertEquals(DEFAULT_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 1); - assertEquals(DEFAULT_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 2); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 3); - assertEquals(DEFAULT_IDX, xfindex); + final short TEST_IDX = 10; + final short DEFAULT_IDX = 0xF; // 15 + short xfindex = Short.MIN_VALUE; + Sheet sheet = Sheet.createSheet(); + + // without ColumnInfoRecord + xfindex = sheet.getXFIndexForColAt((short) 0); + assertEquals(DEFAULT_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 1); + assertEquals(DEFAULT_IDX, xfindex); + + ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo(); + sheet.columns.insertColumn(nci); + + // single column ColumnInfoRecord + nci.setFirstColumn((short) 2); + nci.setLastColumn((short) 2); + nci.setXFIndex(TEST_IDX); + xfindex = sheet.getXFIndexForColAt((short) 0); + assertEquals(DEFAULT_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 1); + assertEquals(DEFAULT_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 2); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 3); + assertEquals(DEFAULT_IDX, xfindex); - // ten column ColumnInfoRecord - nci.setFirstColumn((short) 2); - nci.setLastColumn((short) 11); - nci.setXFIndex(TEST_IDX); - xfindex = sheet.getXFIndexForColAt((short) 1); - assertEquals(DEFAULT_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 2); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 6); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 11); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 12); - assertEquals(DEFAULT_IDX, xfindex); + // ten column ColumnInfoRecord + nci.setFirstColumn((short) 2); + nci.setLastColumn((short) 11); + nci.setXFIndex(TEST_IDX); + xfindex = sheet.getXFIndexForColAt((short) 1); + assertEquals(DEFAULT_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 2); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 6); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 11); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 12); + assertEquals(DEFAULT_IDX, xfindex); - // single column ColumnInfoRecord starting at index 0 - nci.setFirstColumn((short) 0); - nci.setLastColumn((short) 0); - nci.setXFIndex(TEST_IDX); - xfindex = sheet.getXFIndexForColAt((short) 0); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 1); - assertEquals(DEFAULT_IDX, xfindex); + // single column ColumnInfoRecord starting at index 0 + nci.setFirstColumn((short) 0); + nci.setLastColumn((short) 0); + nci.setXFIndex(TEST_IDX); + xfindex = sheet.getXFIndexForColAt((short) 0); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 1); + assertEquals(DEFAULT_IDX, xfindex); - // ten column ColumnInfoRecord starting at index 0 - nci.setFirstColumn((short) 0); - nci.setLastColumn((short) 9); - nci.setXFIndex(TEST_IDX); - xfindex = sheet.getXFIndexForColAt((short) 0); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 7); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 9); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 10); - assertEquals(DEFAULT_IDX, xfindex); - } - catch(Exception e){e.printStackTrace();fail(e.getMessage());} + // ten column ColumnInfoRecord starting at index 0 + nci.setFirstColumn((short) 0); + nci.setLastColumn((short) 9); + nci.setXFIndex(TEST_IDX); + xfindex = sheet.getXFIndexForColAt((short) 0); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 7); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 9); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 10); + assertEquals(DEFAULT_IDX, xfindex); } - } + diff --git a/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java b/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java index 69ab3f298..f1c3b7c9c 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java +++ b/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java @@ -19,125 +19,18 @@ package org.apache.poi.hssf.model; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import junit.framework.TestCase; import org.apache.poi.hssf.record.ColumnInfoRecord; -import org.apache.poi.hssf.record.MergeCellsRecord; -import org.apache.poi.hssf.record.PageBreakRecord; -import org.apache.poi.hssf.record.RowRecord; -import org.apache.poi.hssf.record.StringRecord; /** * @author Tony Poppleton */ -public class TestSheetAdditional extends TestCase -{ - /** - * Constructor for SheetTest. - * @param arg0 - */ - public TestSheetAdditional(String arg0) - { - super(arg0); - } +public final class TestSheetAdditional extends TestCase { - public void testAddMergedRegion() - { - Sheet sheet = Sheet.createSheet(); - int regionsToAdd = 4096; - int startRecords = sheet.getRecords().size(); - - //simple test that adds a load of regions - for (int n = 0; n < regionsToAdd; n++) - { - int index = sheet.addMergedRegion(0, (short) 0, 1, (short) 1); - assertTrue("Merged region index expected to be " + n + " got " + index, index == n); - } - - //test all the regions were indeed added - assertTrue(sheet.getNumMergedRegions() == regionsToAdd); - - //test that the regions were spread out over the appropriate number of records - int recordsAdded = sheet.getRecords().size() - startRecords; - int recordsExpected = regionsToAdd/1027; - if ((regionsToAdd % 1027) != 0) - recordsExpected++; - assertTrue("The " + regionsToAdd + " merged regions should have been spread out over " + recordsExpected + " records, not " + recordsAdded, recordsAdded == recordsExpected); - - // Check we can't add one with invalud date - try { - sheet.addMergedRegion(10, (short)10, 9, (short)12); - fail(); - } catch(IllegalArgumentException e) {} - try { - sheet.addMergedRegion(10, (short)10, 12, (short)9); - fail(); - } catch(IllegalArgumentException e) {} - } - - public void testRemoveMergedRegion() - { - Sheet sheet = Sheet.createSheet(); - int regionsToAdd = 4096; - - for (int n = 0; n < regionsToAdd; n++) - sheet.addMergedRegion(0, (short) 0, 1, (short) 1); - - int records = sheet.getRecords().size(); - - //remove a third from the beginning - for (int n = 0; n < regionsToAdd/3; n++) - { - sheet.removeMergedRegion(0); - //assert they have been deleted - assertTrue("Num of regions should be " + (regionsToAdd - n - 1) + " not " + sheet.getNumMergedRegions(), sheet.getNumMergedRegions() == regionsToAdd - n - 1); - } - - //assert any record removing was done - int recordsRemoved = (regionsToAdd/3)/1027; //doesn't work for particular values of regionsToAdd - assertTrue("Expected " + recordsRemoved + " record to be removed from the starting " + records + ". Currently there are " + sheet.getRecords().size() + " records", records - sheet.getRecords().size() == recordsRemoved); - } - - /** - * Bug: 22922 (Reported by Xuemin Guan) - *

- * Remove mergedregion fails when a sheet loses records after an initial CreateSheet - * fills up the records. - * - */ - public void testMovingMergedRegion() { - List records = new ArrayList(); - - MergeCellsRecord merged = new MergeCellsRecord(); - merged.addArea(0, (short)0, 1, (short)2); - records.add(new RowRecord()); - records.add(new RowRecord()); - records.add(new RowRecord()); - records.add(merged); - - Sheet sheet = Sheet.createSheet(records, 0); - sheet.records.remove(0); - - //stub object to throw off list INDEX operations - sheet.removeMergedRegion(0); - assertEquals("Should be no more merged regions", 0, sheet.getNumMergedRegions()); - } - - public void testGetMergedRegionAt() - { - //TODO - } - - public void testGetNumMergedRegions() - { - //TODO - } - - public void DISBALEDtestGetCellWidth() throws Exception - { + public void testGetCellWidth() { Sheet sheet = Sheet.createSheet(); ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo(); @@ -146,14 +39,8 @@ public class TestSheetAdditional extends TestCase nci.setLastColumn((short)10); nci.setColumnWidth((short)100); - Field f = null; - f = Sheet.class.getDeclaredField("columnSizes"); - f.setAccessible(true); - List columnSizes = new ArrayList(); - f.set(sheet,columnSizes); - columnSizes.add(nci); - sheet.records.add(1 + sheet.dimsloc, nci); - sheet.dimsloc++; + + sheet.columns.insertColumn(nci); assertEquals((short)100,sheet.getColumnWidth((short)5)); assertEquals((short)100,sheet.getColumnWidth((short)6)); @@ -172,151 +59,6 @@ public class TestSheetAdditional extends TestCase assertEquals((short)100,sheet.getColumnWidth((short)10)); } - /** - * Makes sure all rows registered for this sheet are aggregated, they were being skipped - * - */ - public void testRowAggregation() { - List records = new ArrayList(); - RowRecord row = new RowRecord(); - row.setRowNumber(0); - records.add(row); - - row = new RowRecord(); - row.setRowNumber(1); - records.add(row); - - records.add(new StringRecord()); - - row = new RowRecord(); - row.setRowNumber(2); - records.add(row); - - - Sheet sheet = Sheet.createSheet(records, 0); - assertNotNull("Row [2] was skipped", sheet.getRow(2)); - - } - - /** - * Make sure page break functionality works (in memory) - * - */ - public void testRowPageBreaks(){ - short colFrom = 0; - short colTo = 255; - - Sheet sheet = Sheet.createSheet(); - sheet.setRowBreak(0, colFrom, colTo); - - assertTrue("no row break at 0", sheet.isRowBroken(0)); - assertEquals("1 row break available", 1, sheet.getNumRowBreaks()); - - sheet.setRowBreak(0, colFrom, colTo); - sheet.setRowBreak(0, colFrom, colTo); - - assertTrue("no row break at 0", sheet.isRowBroken(0)); - assertEquals("1 row break available", 1, sheet.getNumRowBreaks()); - - sheet.setRowBreak(10, colFrom, colTo); - sheet.setRowBreak(11, colFrom, colTo); - - assertTrue("no row break at 10", sheet.isRowBroken(10)); - assertTrue("no row break at 11", sheet.isRowBroken(11)); - assertEquals("3 row break available", 3, sheet.getNumRowBreaks()); - - - boolean is10 = false; - boolean is0 = false; - boolean is11 = false; - - Iterator iterator = sheet.getRowBreaks(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; - if (main != 0 && main != 10 && main != 11) fail("Invalid page break"); - if (main == 0) is0 = true; - if (main == 10) is10= true; - if (main == 11) is11 = true; - } - - assertTrue("one of the breaks didnt make it", is0 && is10 && is11); - - sheet.removeRowBreak(11); - assertFalse("row should be removed", sheet.isRowBroken(11)); - - sheet.removeRowBreak(0); - assertFalse("row should be removed", sheet.isRowBroken(0)); - - sheet.removeRowBreak(10); - assertFalse("row should be removed", sheet.isRowBroken(10)); - - assertEquals("no more breaks", 0, sheet.getNumRowBreaks()); - - - } - - /** - * Make sure column pag breaks works properly (in-memory) - * - */ - public void testColPageBreaks(){ - short rowFrom = 0; - short rowTo = (short)65535; - - Sheet sheet = Sheet.createSheet(); - sheet.setColumnBreak((short)0, rowFrom, rowTo); - - assertTrue("no col break at 0", sheet.isColumnBroken((short)0)); - assertEquals("1 col break available", 1, sheet.getNumColumnBreaks()); - - sheet.setColumnBreak((short)0, rowFrom, rowTo); - - assertTrue("no col break at 0", sheet.isColumnBroken((short)0)); - assertEquals("1 col break available", 1, sheet.getNumColumnBreaks()); - - sheet.setColumnBreak((short)1, rowFrom, rowTo); - sheet.setColumnBreak((short)10, rowFrom, rowTo); - sheet.setColumnBreak((short)15, rowFrom, rowTo); - - assertTrue("no col break at 1", sheet.isColumnBroken((short)1)); - assertTrue("no col break at 10", sheet.isColumnBroken((short)10)); - assertTrue("no col break at 15", sheet.isColumnBroken((short)15)); - assertEquals("4 col break available", 4, sheet.getNumColumnBreaks()); - - boolean is10 = false; - boolean is0 = false; - boolean is1 = false; - boolean is15 = false; - - Iterator iterator = sheet.getColumnBreaks(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; - if (main != 0 && main != 1 && main != 10 && main != 15) fail("Invalid page break"); - if (main == 0) is0 = true; - if (main == 1) is1 = true; - if (main == 10) is10= true; - if (main == 15) is15 = true; - } - - assertTrue("one of the breaks didnt make it", is0 && is1 && is10 && is15); - - sheet.removeColumnBreak((short)15); - assertFalse("column break should not be there", sheet.isColumnBroken((short)15)); - - sheet.removeColumnBreak((short)0); - assertFalse("column break should not be there", sheet.isColumnBroken((short)0)); - - sheet.removeColumnBreak((short)1); - assertFalse("column break should not be there", sheet.isColumnBroken((short)1)); - - sheet.removeColumnBreak((short)10); - assertFalse("column break should not be there", sheet.isColumnBroken((short)10)); - - assertEquals("no more breaks", 0, sheet.getNumColumnBreaks()); - } - } diff --git a/src/testcases/org/apache/poi/hssf/record/aggregates/TestRowRecordsAggregate.java b/src/testcases/org/apache/poi/hssf/record/aggregates/TestRowRecordsAggregate.java index 50f67129c..239fc2b88 100644 --- a/src/testcases/org/apache/poi/hssf/record/aggregates/TestRowRecordsAggregate.java +++ b/src/testcases/org/apache/poi/hssf/record/aggregates/TestRowRecordsAggregate.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -15,34 +14,28 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - + package org.apache.poi.hssf.record.aggregates; -import org.apache.poi.hssf.record.*; +import junit.framework.TestCase; -public class TestRowRecordsAggregate extends junit.framework.TestCase { - public TestRowRecordsAggregate(String name) { - super (name); - } +import org.apache.poi.hssf.record.RowRecord; + +/** + * + */ +public final class TestRowRecordsAggregate extends TestCase { public void testRowGet() { RowRecordsAggregate rra = new RowRecordsAggregate(); - RowRecord rr = new RowRecord(); - rr.setRowNumber(( short ) 4); + RowRecord rr = new RowRecord(4); rra.insertRow(rr); - RowRecord rr2 = new RowRecord(); rr2.setRowNumber((short) 1); - rra.insertRow(rr2); + rra.insertRow(new RowRecord(1)); RowRecord rr1 = rra.getRow(4); - assertTrue("Row Record should not be null", rr1!=null); - assertTrue("Row number is 1",rr1.getRowNumber() == 4); + assertNotNull(rr1); + assertEquals("Row number is 1", 4, rr1.getRowNumber()); assertTrue("Row record retrieved is identical ", rr1 == rr); } - - public static void main(String [] args) { - System.out - .println("Testing org.apache.poi.hssf.record.aggregates.RowRecordAggregate"); - junit.textui.TestRunner.run(TestRowRecordsAggregate.class); - } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java index b6f22022c..f0c4139d2 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java @@ -143,8 +143,9 @@ public final class TestHSSFRow extends TestCase { try { sheet.createRow(-1); fail("IndexOutOfBoundsException should have been thrown"); - } catch (IndexOutOfBoundsException ex) { + } catch (IllegalArgumentException e) { // expected during successful test + assertEquals("Invalid row number (-1) outside allowable range (0..65535)", e.getMessage()); } //Test high row bound @@ -153,8 +154,9 @@ public final class TestHSSFRow extends TestCase { try { sheet.createRow(65536); fail("IndexOutOfBoundsException should have been thrown"); - } catch (IndexOutOfBoundsException ex) { + } catch (IllegalArgumentException e) { // expected during successful test + assertEquals("Invalid row number (65536) outside allowable range (0..65535)", e.getMessage()); } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java index 246d6b517..71c8a3a4c 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java @@ -23,6 +23,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; @@ -193,17 +194,29 @@ public final class TestHSSFSheet extends TestCase { public void testCloneSheet() { HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet("Test Clone"); - HSSFRow row = sheet.createRow((short) 0); + HSSFRow row = sheet.createRow(0); HSSFCell cell = row.createCell((short) 0); - cell.setCellValue("clone_test"); - HSSFSheet cloned = workbook.cloneSheet(0); - + HSSFCell cell2 = row.createCell((short) 1); + cell.setCellValue(new HSSFRichTextString("clone_test")); + cell2.setCellFormula("sin(1)"); + + HSSFSheet clonedSheet = workbook.cloneSheet(0); + HSSFRow clonedRow = clonedSheet.getRow(0); + //Check for a good clone - assertEquals(cloned.getRow((short)0).getCell((short)0).getStringCellValue(), "clone_test"); + assertEquals(clonedRow.getCell(0).getRichStringCellValue().getString(), "clone_test"); //Check that the cells are not somehow linked - cell.setCellValue("Difference Check"); - assertEquals(cloned.getRow((short)0).getCell((short)0).getStringCellValue(), "clone_test"); + cell.setCellValue(new HSSFRichTextString("Difference Check")); + cell2.setCellFormula("cos(2)"); + if ("Difference Check".equals(clonedRow.getCell(0).getRichStringCellValue().getString())) { + fail("string cell not properly cloned"); + } + if ("COS(2)".equals(clonedRow.getCell(1).getCellFormula())) { + fail("formula cell not properly cloned"); + } + assertEquals(clonedRow.getCell(0).getRichStringCellValue().getString(), "clone_test"); + assertEquals(clonedRow.getCell(1).getCellFormula(), "SIN(1)"); } /** tests that the sheet name for multiple clones of the same sheet is unique @@ -214,7 +227,7 @@ public final class TestHSSFSheet extends TestCase { HSSFSheet sheet = workbook.createSheet("Test Clone"); HSSFRow row = sheet.createRow((short) 0); HSSFCell cell = row.createCell((short) 0); - cell.setCellValue("clone_test"); + cell.setCellValue(new HSSFRichTextString("clone_test")); //Clone the sheet multiple times workbook.cloneSheet(0); workbook.cloneSheet(0); @@ -517,11 +530,11 @@ public final class TestHSSFSheet extends TestCase { HSSFSheet sheet = wb.createSheet(); HSSFRow row = sheet.createRow(0); HSSFCell cell = row.createCell((short)0); - cell.setCellValue("first row, first cell"); + cell.setCellValue(new HSSFRichTextString("first row, first cell")); row = sheet.createRow(1); cell = row.createCell((short)1); - cell.setCellValue("second row, second cell"); + cell.setCellValue(new HSSFRichTextString("second row, second cell")); Region region = new Region(1, (short)0, 1, (short)1); sheet.addMergedRegion(region); @@ -643,28 +656,28 @@ public final class TestHSSFSheet extends TestCase { /** cell with formula becomes null on cloning a sheet*/ public void test35084() { - - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet s =wb.createSheet("Sheet1"); - HSSFRow r = s.createRow(0); - r.createCell((short)0).setCellValue(1); - r.createCell((short)1).setCellFormula("A1*2"); - HSSFSheet s1 = wb.cloneSheet(0); - r=s1.getRow(0); - assertEquals("double" ,r.getCell((short)0).getNumericCellValue(),(double)1,0); //sanity check - assertNotNull(r.getCell((short)1)); - assertEquals("formula", r.getCell((short)1).getCellFormula(), "A1*2"); - } + + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet s = wb.createSheet("Sheet1"); + HSSFRow r = s.createRow(0); + r.createCell((short) 0).setCellValue(1); + r.createCell((short) 1).setCellFormula("A1*2"); + HSSFSheet s1 = wb.cloneSheet(0); + r = s1.getRow(0); + assertEquals("double", r.getCell((short) 0).getNumericCellValue(), 1, 0); // sanity check + assertNotNull(r.getCell((short) 1)); + assertEquals("formula", r.getCell((short) 1).getCellFormula(), "A1*2"); + } /** test that new default column styles get applied */ public void testDefaultColumnStyle() { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFCellStyle style = wb.createCellStyle(); - HSSFSheet s = wb.createSheet(); - s.setDefaultColumnStyle((short)0, style); - HSSFRow r = s.createRow(0); - HSSFCell c = r.createCell((short)0); - assertEquals("style should match", style.getIndex(), c.getCellStyle().getIndex()); + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFCellStyle style = wb.createCellStyle(); + HSSFSheet s = wb.createSheet(); + s.setDefaultColumnStyle((short) 0, style); + HSSFRow r = s.createRow(0); + HSSFCell c = r.createCell((short) 0); + assertEquals("style should match", style.getIndex(), c.getCellStyle().getIndex()); } @@ -814,11 +827,6 @@ public final class TestHSSFSheet extends TestCase { assertTrue(wb3.getSheetAt(3).getForceFormulaRecalculation()); } - - public static void main(java.lang.String[] args) { - junit.textui.TestRunner.run(TestHSSFSheet.class); - } - public void testColumnWidth() throws Exception { //check we can correctly read column widths from a reference workbook HSSFWorkbook wb = openSample("colwidth.xls"); @@ -870,11 +878,33 @@ public final class TestHSSFSheet extends TestCase { assertEquals(256*10, sh.getColumnWidth((short)0)); assertEquals(256*10, sh.getColumnWidth((short)1)); assertEquals(256*10, sh.getColumnWidth((short)2)); - //columns D-F have custom wodth + //columns D-F have custom width for (char i = 'D'; i <= 'F'; i++) { short w = (short)(256*12); assertEquals(w, sh.getColumnWidth((short)i)); } + } + + /** + * Some utilities write Excel files without the ROW records. + * Excel, ooo, and google docs are OK with this. + * Now POI is too. + */ + public void testMissingRowRecords_bug41187() { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("ex41187-19267.xls"); + HSSFSheet sheet = wb.getSheetAt(0); + HSSFRow row = sheet.getRow(0); + if(row == null) { + throw new AssertionFailedError("Identified bug 41187 a"); + } + if (row.getHeight() == 0) { + throw new AssertionFailedError("Identified bug 41187 b"); + } + assertEquals("Hi Excel!", row.getCell(0).getRichStringCellValue().getString()); + // check row height for 'default' flag + assertEquals((short)0x8000, row.getHeight()); + + HSSFTestDataSamples.writeOutAndReadBack(wb); } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java index 4c156e7b6..75ac6923a 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java @@ -147,9 +147,10 @@ public final class TestHSSFWorkbook extends TestCase { // Single chart, two sheets b = openSample("44010-SingleChart.xls"); assertEquals(2, b.getNumberOfSheets()); + assertEquals("Graph2", b.getSheetName(1)); s = b.getSheetAt(1); assertEquals(0, s.getFirstRowNum()); - assertEquals(0, s.getLastRowNum()); + assertEquals(8, s.getLastRowNum()); // Has chart on 1st sheet?? // FIXME @@ -166,7 +167,7 @@ public final class TestHSSFWorkbook extends TestCase { assertEquals(2, b.getNumberOfSheets()); s = b.getSheetAt(1); assertEquals(0, s.getFirstRowNum()); - assertEquals(0, s.getLastRowNum()); + assertEquals(8, s.getLastRowNum()); // Two charts, three sheets @@ -175,10 +176,10 @@ public final class TestHSSFWorkbook extends TestCase { s = b.getSheetAt(1); assertEquals(0, s.getFirstRowNum()); - assertEquals(0, s.getLastRowNum()); + assertEquals(8, s.getLastRowNum()); s = b.getSheetAt(2); assertEquals(0, s.getFirstRowNum()); - assertEquals(0, s.getLastRowNum()); + assertEquals(8, s.getLastRowNum()); // Has chart on 1st sheet?? // FIXME @@ -197,13 +198,13 @@ public final class TestHSSFWorkbook extends TestCase { s = b.getSheetAt(1); assertEquals(0, s.getFirstRowNum()); - assertEquals(0, s.getLastRowNum()); + assertEquals(8, s.getLastRowNum()); s = b.getSheetAt(2); assertEquals(0, s.getFirstRowNum()); - assertEquals(0, s.getLastRowNum()); + assertEquals(8, s.getLastRowNum()); } private static HSSFWorkbook writeRead(HSSFWorkbook b) { - return HSSFTestDataSamples.writeOutAndReadBack(b); + return HSSFTestDataSamples.writeOutAndReadBack(b); } } \ No newline at end of file