true
if the specified column has a page break
- */
- public boolean isColumnBroken(short column) {
- return getColumnBreaksRecord().getBreak(column) != null;
- }
-
- /**
- * Shifts the horizontal page breaks for the indicated count
- * @param startingRow
- * @param endingRow
- * @param count
- */
- public void shiftRowBreaks(int startingRow, int endingRow, int count) {
- shiftBreaks(getRowBreaksRecord(), startingRow, endingRow, count);
- }
-
- /**
- * Shifts the vertical page breaks for the indicated count
- * @param startingCol
- * @param endingCol
- * @param count
- */
- public void shiftColumnBreaks(short startingCol, short endingCol, short count) {
- shiftBreaks(getColumnBreaksRecord(), startingCol, endingCol, count);
- }
-
- /**
- * @return all the horizontal page breaks, never null
- */
- public int[] getRowBreaks() {
- return getRowBreaksRecord().getBreaks();
- }
-
- /**
- * @return the number of row page breaks
- */
- public int getNumRowBreaks(){
- return getRowBreaksRecord().getNumBreaks();
- }
-
- /**
- * @return all the column page breaks, never null
- */
- public int[] getColumnBreaks(){
- return getColumnBreaksRecord().getBreaks();
- }
-
- /**
- * @return the number of column page breaks
- */
- public int getNumColumnBreaks(){
- return getColumnBreaksRecord().getNumBreaks();
- }
public void setColumnGroupCollapsed( short columnNumber, boolean collapsed )
{
@@ -2520,8 +1931,8 @@ public final class Sheet implements Model {
}
public DataValidityTable getOrCreateDataValidityTable() {
if (_dataValidityTable == null) {
- DataValidityTable result = new DataValidityTable();
- RecordOrderer.addNewSheetRecord(records, result);
+ DataValidityTable result = new DataValidityTable();
+ RecordOrderer.addNewSheetRecord(records, result);
_dataValidityTable = result;
}
return _dataValidityTable;
diff --git a/src/java/org/apache/poi/hssf/record/DBCellRecord.java b/src/java/org/apache/poi/hssf/record/DBCellRecord.java
index 1da6b82c73..d14e689ed5 100644
--- a/src/java/org/apache/poi/hssf/record/DBCellRecord.java
+++ b/src/java/org/apache/poi/hssf/record/DBCellRecord.java
@@ -35,6 +35,7 @@ public final class DBCellRecord extends Record {
public DBCellRecord()
{
+ field_2_cell_offsets = new short[0];
}
/**
@@ -185,4 +186,9 @@ public final class DBCellRecord extends Record {
{
return true;
}
+ public Object clone() {
+ // TODO - make immutable.
+ // this should be safe because only the instantiating code mutates these objects
+ return this;
+ }
}
diff --git a/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java b/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java
index 874f304abd..a8518c7b31 100644
--- a/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java
+++ b/src/java/org/apache/poi/hssf/record/PrintSetupRecord.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;
@@ -24,18 +22,15 @@ import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
/**
- * Title: Print Setup Record- * Description: Stores print setup options -- bogus for HSSF (and marked as such)
- * REFERENCE: PG 385 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * Title: PAGESETUP (0x00A1)
+ * Description: Stores print setup options -- bogus for HSSF (and marked as such) + * REFERENCE: PG 385 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) * @author Andrew C. Oliver (acoliver at apache dot org) * @author Jason Height (jheight at chariot dot net dot au) * @version 2.0-pre */ - -public class PrintSetupRecord - extends Record -{ - public final static short sid = 0xa1; +public class PrintSetupRecord extends Record { + public final static short sid = 0x00A1; private short field_1_paper_size; private short field_2_scale; private short field_3_page_start; diff --git a/src/java/org/apache/poi/hssf/record/RowRecord.java b/src/java/org/apache/poi/hssf/record/RowRecord.java index 46d4a1efeb..2ef8763984 100644 --- a/src/java/org/apache/poi/hssf/record/RowRecord.java +++ b/src/java/org/apache/poi/hssf/record/RowRecord.java @@ -22,15 +22,17 @@ import org.apache.poi.util.BitFieldFactory; import org.apache.poi.util.LittleEndian; /** - * Title: Row Record- * Description: stores the row information for the sheet.
+ * Title: Row Record (0x0208)
+ * Description: stores the row information for the sheet. * REFERENCE: PG 379 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)* @author Andrew C. Oliver (acoliver at apache dot org) * @author Jason Height (jheight at chariot dot net dot au) * @version 2.0-pre */ public final class RowRecord extends Record implements Comparable { - public final static short sid = 0x208; + public final static short sid = 0x0208; + + public static final int ENCODED_SIZE = 20; private static final int OPTION_BITS_ALWAYS_SET = 0x0100; private static final int DEFAULT_HEIGHT_BIT = 0x8000; @@ -407,23 +409,23 @@ public final class RowRecord extends Record implements Comparable { public int serialize(int offset, byte [] data) { - LittleEndian.putShort(data, 0 + offset, sid); - LittleEndian.putShort(data, 2 + offset, ( short ) 16); - LittleEndian.putShort(data, 4 + offset, ( short ) getRowNumber()); - LittleEndian.putShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol()); - LittleEndian.putShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol()); - LittleEndian.putShort(data, 10 + offset, getHeight()); - LittleEndian.putShort(data, 12 + offset, getOptimize()); - LittleEndian.putShort(data, 14 + offset, field_6_reserved); - LittleEndian.putShort(data, 16 + offset, getOptionFlags()); + LittleEndian.putUShort(data, 0 + offset, sid); + LittleEndian.putUShort(data, 2 + offset, ENCODED_SIZE - 4); + LittleEndian.putUShort(data, 4 + offset, getRowNumber()); + LittleEndian.putUShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol()); + LittleEndian.putUShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol()); + LittleEndian.putUShort(data, 10 + offset, getHeight()); + LittleEndian.putUShort(data, 12 + offset, getOptimize()); + LittleEndian.putUShort(data, 14 + offset, field_6_reserved); + LittleEndian.putUShort(data, 16 + offset, getOptionFlags()); - LittleEndian.putShort(data, 18 + offset, getXFIndex()); - return getRecordSize(); + LittleEndian.putUShort(data, 18 + offset, getXFIndex()); + return ENCODED_SIZE; } public int getRecordSize() { - return 20; + return ENCODED_SIZE; } public short getSid() diff --git a/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java b/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java new file mode 100644 index 0000000000..cc8be41791 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java @@ -0,0 +1,525 @@ +/* ==================================================================== + 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.record.aggregates; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.poi.hssf.model.RecordStream; +import org.apache.poi.hssf.model.Sheet; +import org.apache.poi.hssf.record.BottomMarginRecord; +import org.apache.poi.hssf.record.FooterRecord; +import org.apache.poi.hssf.record.HCenterRecord; +import org.apache.poi.hssf.record.HeaderRecord; +import org.apache.poi.hssf.record.HorizontalPageBreakRecord; +import org.apache.poi.hssf.record.LeftMarginRecord; +import org.apache.poi.hssf.record.Margin; +import org.apache.poi.hssf.record.PageBreakRecord; +import org.apache.poi.hssf.record.PrintSetupRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RightMarginRecord; +import org.apache.poi.hssf.record.TopMarginRecord; +import org.apache.poi.hssf.record.VCenterRecord; +import org.apache.poi.hssf.record.VerticalPageBreakRecord; + +/** + * Groups the page settings records for a worksheet.
+ * + * See OOO excelfileformat.pdf sec 4.4 'Page Settings Block' + * + * @author Josh Micich + */ +public final class PageSettingsBlock extends RecordAggregate { + // Every one of these component records is optional + // (The whole PageSettingsBlock may not be present) + private PageBreakRecord _rowBreaksRecord; + private PageBreakRecord _columnBreaksRecord; + private HeaderRecord header; + private FooterRecord footer; + private HCenterRecord _hCenter; + private VCenterRecord _vCenter; + private LeftMarginRecord _leftMargin; + private RightMarginRecord _rightMargin; + private TopMarginRecord _topMargin; + private BottomMarginRecord _bottomMargin; + private Record _pls; + private PrintSetupRecord printSetup; + private Record _bitmap; + + public PageSettingsBlock(RecordStream rs) { + while(true) { + if (!readARecord(rs)) { + break; + } + } + } + + /** + * Creates a PageSettingsBlock with default settings + */ + public PageSettingsBlock() { + _rowBreaksRecord = new HorizontalPageBreakRecord(); + _columnBreaksRecord = new VerticalPageBreakRecord(); + header = createHeader(); + footer = createFooter(); + _hCenter = createHCenter(); + _vCenter = createVCenter(); + printSetup = createPrintSetup(); + } + + /** + * @returntrue
if the specified Record sid is one belonging to the
+ * 'Page Settings Block'.
+ */
+ public static boolean isComponentRecord(int sid) {
+ switch (sid) {
+ case HorizontalPageBreakRecord.sid:
+ case VerticalPageBreakRecord.sid:
+ case HeaderRecord.sid:
+ case FooterRecord.sid:
+ case HCenterRecord.sid:
+ case VCenterRecord.sid:
+ case LeftMarginRecord.sid:
+ case RightMarginRecord.sid:
+ case TopMarginRecord.sid:
+ case BottomMarginRecord.sid:
+ case 0x004D: // PLS
+ case PrintSetupRecord.sid:
+ case 0x00E9: // BITMAP
+ return true;
+ }
+ return false;
+ }
+
+ private boolean readARecord(RecordStream rs) {
+ switch (rs.peekNextSid()) {
+ case HorizontalPageBreakRecord.sid:
+ _rowBreaksRecord = (PageBreakRecord) rs.getNext();
+ break;
+ case VerticalPageBreakRecord.sid:
+ _columnBreaksRecord = (PageBreakRecord) rs.getNext();
+ break;
+ case HeaderRecord.sid:
+ header = (HeaderRecord) rs.getNext();
+ break;
+ case FooterRecord.sid:
+ footer = (FooterRecord) rs.getNext();
+ break;
+ case HCenterRecord.sid:
+ _hCenter = (HCenterRecord) rs.getNext();
+ break;
+ case VCenterRecord.sid:
+ _vCenter = (VCenterRecord) rs.getNext();
+ break;
+ case LeftMarginRecord.sid:
+ _leftMargin = (LeftMarginRecord) rs.getNext();
+ break;
+ case RightMarginRecord.sid:
+ _rightMargin = (RightMarginRecord) rs.getNext();
+ break;
+ case TopMarginRecord.sid:
+ _topMargin = (TopMarginRecord) rs.getNext();
+ break;
+ case BottomMarginRecord.sid:
+ _bottomMargin = (BottomMarginRecord) rs.getNext();
+ break;
+ case 0x004D: // PLS
+ _pls = rs.getNext();
+ break;
+ case PrintSetupRecord.sid:
+ printSetup = (PrintSetupRecord)rs.getNext();
+ break;
+ case 0x00E9: // BITMAP
+ _bitmap = rs.getNext();
+ break;
+ default:
+ // all other record types are not part of the PageSettingsBlock
+ return false;
+ }
+ return true;
+ }
+
+ private PageBreakRecord getRowBreaksRecord() {
+ if (_rowBreaksRecord == null) {
+ _rowBreaksRecord = new HorizontalPageBreakRecord();
+ }
+ return _rowBreaksRecord;
+ }
+
+ private PageBreakRecord getColumnBreaksRecord() {
+ if (_columnBreaksRecord == null) {
+ _columnBreaksRecord = new VerticalPageBreakRecord();
+ }
+ return _columnBreaksRecord;
+ }
+
+
+ /**
+ * Sets a page break at the indicated column
+ *
+ */
+ public void setColumnBreak(short column, short fromRow, short toRow) {
+ getColumnBreaksRecord().addBreak(column, fromRow, toRow);
+ }
+
+ /**
+ * Removes a page break at the indicated column
+ *
+ */
+ public void removeColumnBreak(int column) {
+ getColumnBreaksRecord().removeBreak(column);
+ }
+
+
+
+
+ public void visitContainedRecords(RecordVisitor rv) {
+ visitIfPresent(_rowBreaksRecord, rv);
+ visitIfPresent(_columnBreaksRecord, rv);
+ visitIfPresent(header, rv);
+ visitIfPresent(footer, rv);
+ visitIfPresent(_hCenter, rv);
+ visitIfPresent(_vCenter, rv);
+ visitIfPresent(_leftMargin, rv);
+ visitIfPresent(_rightMargin, rv);
+ visitIfPresent(_topMargin, rv);
+ visitIfPresent(_bottomMargin, rv);
+ visitIfPresent(_pls, rv);
+ visitIfPresent(printSetup, rv);
+ visitIfPresent(_bitmap, rv);
+ }
+ private static void visitIfPresent(Record r, RecordVisitor rv) {
+ if (r != null) {
+ rv.visitRecord(r);
+ }
+ }
+
+ /**
+ * creates the Header Record and sets it to nothing/0 length
+ */
+ private static HeaderRecord createHeader() {
+ HeaderRecord retval = new HeaderRecord();
+
+ retval.setHeaderLength(( byte ) 0);
+ retval.setHeader(null);
+ return retval;
+ }
+
+ /**
+ * creates the Footer Record and sets it to nothing/0 length
+ */
+ private static FooterRecord createFooter() {
+ FooterRecord retval = new FooterRecord();
+
+ retval.setFooterLength(( byte ) 0);
+ retval.setFooter(null);
+ return retval;
+ }
+
+ /**
+ * creates the HCenter Record and sets it to false (don't horizontally center)
+ */
+ private static HCenterRecord createHCenter() {
+ HCenterRecord retval = new HCenterRecord();
+
+ retval.setHCenter(false);
+ return retval;
+ }
+
+ /**
+ * creates the VCenter Record and sets it to false (don't horizontally center)
+ */
+ private static VCenterRecord createVCenter() {
+ VCenterRecord retval = new VCenterRecord();
+
+ retval.setVCenter(false);
+ return retval;
+ }
+
+ /**
+ * creates the PrintSetup Record and sets it to defaults and marks it invalid
+ * @see org.apache.poi.hssf.record.PrintSetupRecord
+ * @see org.apache.poi.hssf.record.Record
+ * @return record containing a PrintSetupRecord
+ */
+ private static PrintSetupRecord createPrintSetup() {
+ PrintSetupRecord retval = new PrintSetupRecord();
+
+ retval.setPaperSize(( short ) 1);
+ retval.setScale(( short ) 100);
+ retval.setPageStart(( short ) 1);
+ retval.setFitWidth(( short ) 1);
+ retval.setFitHeight(( short ) 1);
+ retval.setOptions(( short ) 2);
+ retval.setHResolution(( short ) 300);
+ retval.setVResolution(( short ) 300);
+ retval.setHeaderMargin( 0.5);
+ retval.setFooterMargin( 0.5);
+ retval.setCopies(( short ) 0);
+ return retval;
+ }
+
+
+ /**
+ * Returns the HeaderRecord.
+ * @return HeaderRecord for the sheet.
+ */
+ public HeaderRecord getHeader ()
+ {
+ return header;
+ }
+
+ /**
+ * Sets the HeaderRecord.
+ * @param newHeader The new HeaderRecord for the sheet.
+ */
+ public void setHeader (HeaderRecord newHeader)
+ {
+ header = newHeader;
+ }
+
+ /**
+ * Returns the FooterRecord.
+ * @return FooterRecord for the sheet.
+ */
+ public FooterRecord getFooter ()
+ {
+ return footer;
+ }
+
+ /**
+ * Sets the FooterRecord.
+ * @param newFooter The new FooterRecord for the sheet.
+ */
+ public void setFooter (FooterRecord newFooter)
+ {
+ footer = newFooter;
+ }
+
+ /**
+ * Returns the PrintSetupRecord.
+ * @return PrintSetupRecord for the sheet.
+ */
+ public PrintSetupRecord getPrintSetup ()
+ {
+ return printSetup;
+ }
+
+ /**
+ * Sets the PrintSetupRecord.
+ * @param newPrintSetup The new PrintSetupRecord for the sheet.
+ */
+ public void setPrintSetup (PrintSetupRecord newPrintSetup)
+ {
+ printSetup = newPrintSetup;
+ }
+
+
+ private Margin getMarginRec(int marginIndex) {
+ switch (marginIndex) {
+ case Sheet.LeftMargin: return _leftMargin;
+ case Sheet.RightMargin: return _rightMargin;
+ case Sheet.TopMargin: return _topMargin;
+ case Sheet.BottomMargin: return _bottomMargin;
+ }
+ throw new RuntimeException( "Unknown margin constant: " + marginIndex );
+ }
+
+
+ /**
+ * Gets the size of the margin in inches.
+ * @param margin which margin to get
+ * @return the size of the margin
+ */
+ public double getMargin(short margin) {
+ Margin m = getMarginRec(margin);
+ if (m != null) {
+ return m.getMargin();
+ } else {
+ switch ( margin )
+ {
+ case Sheet.LeftMargin:
+ return .75;
+ case Sheet.RightMargin:
+ return .75;
+ case Sheet.TopMargin:
+ return 1.0;
+ case Sheet.BottomMargin:
+ return 1.0;
+ }
+ throw new RuntimeException( "Unknown margin constant: " + margin );
+ }
+ }
+
+ /**
+ * Sets the size of the margin in inches.
+ * @param margin which margin to get
+ * @param size the size of the margin
+ */
+ public void setMargin(short margin, double size) {
+ Margin m = getMarginRec(margin);
+ if (m == null) {
+ switch ( margin )
+ {
+ case Sheet.LeftMargin:
+ _leftMargin = new LeftMarginRecord();
+ m = _leftMargin;
+ break;
+ case Sheet.RightMargin:
+ _rightMargin = new RightMarginRecord();
+ m = _rightMargin;
+ break;
+ case Sheet.TopMargin:
+ _topMargin = new TopMarginRecord();
+ m = _topMargin;
+ break;
+ case Sheet.BottomMargin:
+ _bottomMargin = new BottomMarginRecord();
+ m = _bottomMargin;
+ break;
+ default :
+ throw new RuntimeException( "Unknown margin constant: " + margin );
+ }
+ }
+ m.setMargin( size );
+ }
+
+ /**
+ * Shifts all the page breaks in the range "count" number of rows/columns
+ * @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
+ */
+ private static void shiftBreaks(PageBreakRecord breaks, int start, int stop, int count) {
+
+ Iterator iterator = breaks.getBreaksIterator();
+ List shiftedBreak = new ArrayList();
+ while(iterator.hasNext())
+ {
+ PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next();
+ int 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) {
+ getRowBreaksRecord().addBreak((short)row, fromCol, toCol);
+ }
+
+ /**
+ * Removes a page break at the indicated row
+ * @param row
+ */
+ public void removeRowBreak(int row) {
+ if (getRowBreaksRecord().getBreaks().length < 1)
+ throw new IllegalArgumentException("Sheet does not define any row breaks");
+ getRowBreaksRecord().removeBreak((short)row);
+ }
+
+ /**
+ * Queries if the specified row has a page break
+ * @param row
+ * @return true if the specified row has a page break
+ */
+ public boolean isRowBroken(int row) {
+ return getRowBreaksRecord().getBreak(row) != null;
+ }
+
+
+ /**
+ * Queries if the specified column has a page break
+ *
+ * @return true
if the specified column has a page break
+ */
+ public boolean isColumnBroken(int column) {
+ return getColumnBreaksRecord().getBreak(column) != null;
+ }
+
+ /**
+ * Shifts the horizontal page breaks for the indicated count
+ * @param startingRow
+ * @param endingRow
+ * @param count
+ */
+ public void shiftRowBreaks(int startingRow, int endingRow, int count) {
+ shiftBreaks(getRowBreaksRecord(), startingRow, endingRow, count);
+ }
+
+ /**
+ * Shifts the vertical page breaks for the indicated count
+ * @param startingCol
+ * @param endingCol
+ * @param count
+ */
+ public void shiftColumnBreaks(short startingCol, short endingCol, short count) {
+ shiftBreaks(getColumnBreaksRecord(), startingCol, endingCol, count);
+ }
+
+ /**
+ * @return all the horizontal page breaks, never null
+ */
+ public int[] getRowBreaks() {
+ return getRowBreaksRecord().getBreaks();
+ }
+
+ /**
+ * @return the number of row page breaks
+ */
+ public int getNumRowBreaks(){
+ return getRowBreaksRecord().getNumBreaks();
+ }
+
+ /**
+ * @return all the column page breaks, never null
+ */
+ public int[] getColumnBreaks(){
+ return getColumnBreaksRecord().getBreaks();
+ }
+
+ /**
+ * @return the number of column page breaks
+ */
+ public int getNumColumnBreaks(){
+ return getColumnBreaksRecord().getNumBreaks();
+ }
+
+ public VCenterRecord getVCenter() {
+ return _vCenter;
+ }
+
+ public HCenterRecord getHCenter() {
+ return _hCenter;
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java
index ce0bf89452..f9cbcd7770 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java
@@ -54,6 +54,10 @@ public abstract class RecordAggregate extends RecordBase {
}
public interface RecordVisitor {
+ /**
+ * Implementors may call non-mutating methods on Record r.
+ * @param r must not be null
+ */
void visitRecord(Record r);
}
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 65af632d3f..c9a302b614 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.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,85 +15,88 @@
limitations under the License.
==================================================================== */
-
package org.apache.poi.hssf.record.aggregates;
-import org.apache.poi.hssf.record.DBCellRecord;
-import org.apache.poi.hssf.record.Record;
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.record.RowRecord;
-
-
+import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.DBCellRecord;
+import org.apache.poi.hssf.record.IndexRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RowRecord;
+
/**
*
* @author andy
* @author Jason Height (jheight at chariot dot net dot au)
*/
-
-public final class RowRecordsAggregate extends Record {
- private int firstrow = -1;
- private int lastrow = -1;
- private Map records = null; // TODO - use a proper key in this map
- private int size = 0;
+public final class RowRecordsAggregate extends RecordAggregate {
+ private int _firstrow = -1;
+ private int _lastrow = -1;
+ private final Map _rowRecords;
+ private final ValueRecordsAggregate _valuesAgg;
/** Creates a new instance of ValueRecordsAggregate */
- public RowRecordsAggregate()
- {
- records = new TreeMap();
+ public RowRecordsAggregate() {
+ this(new TreeMap(), new ValueRecordsAggregate());
+ }
+ private RowRecordsAggregate(TreeMap rowRecords, ValueRecordsAggregate valuesAgg) {
+ _rowRecords = rowRecords;
+ _valuesAgg = valuesAgg;
}
- public void insertRow(RowRecord row)
- {
- size += row.getRecordSize();
-
+ public void insertRow(RowRecord row) {
// Integer integer = new Integer(row.getRowNumber());
- records.put(row, row);
- if ((row.getRowNumber() < firstrow) || (firstrow == -1))
+ _rowRecords.put(new Integer(row.getRowNumber()), row);
+ if ((row.getRowNumber() < _firstrow) || (_firstrow == -1))
{
- firstrow = row.getRowNumber();
+ _firstrow = row.getRowNumber();
}
- if ((row.getRowNumber() > lastrow) || (lastrow == -1))
+ if ((row.getRowNumber() > _lastrow) || (_lastrow == -1))
{
- lastrow = row.getRowNumber();
+ _lastrow = row.getRowNumber();
}
}
- public void removeRow(RowRecord row)
- {
- size -= row.getRecordSize();
-
- // Integer integer = new Integer(row.getRowNumber());
- records.remove(row);
+ public void removeRow(RowRecord row) {
+ int rowIndex = row.getRowNumber();
+ _valuesAgg.removeAllCellsValuesForRow(rowIndex);
+ Integer key = new Integer(rowIndex);
+ RowRecord rr = (RowRecord) _rowRecords.remove(key);
+ if (rr == null) {
+ throw new RuntimeException("Invalid row index (" + key.intValue() + ")");
+ }
+ if (row != rr) {
+ _rowRecords.put(key, rr);
+ throw new RuntimeException("Attempt to remove row that does not belong to this sheet");
+ }
}
- public RowRecord getRow(int rownum) {
- // Row must be between 0 and 65535
- if(rownum < 0 || rownum > 65535) {
+ public RowRecord getRow(int rowIndex) {
+ if (rowIndex < 0 || rowIndex > 65535) {
throw new IllegalArgumentException("The row number must be between 0 and 65535");
}
-
- RowRecord row = new RowRecord(rownum);
- return ( RowRecord ) records.get(row);
+ return (RowRecord) _rowRecords.get(new Integer(rowIndex));
}
public int getPhysicalNumberOfRows()
{
- return records.size();
+ return _rowRecords.size();
}
public int getFirstRowNum()
{
- return firstrow;
+ return _firstrow;
}
public int getLastRowNum()
{
- return lastrow;
+ return _lastrow;
}
/** Returns the number of row blocks.
@@ -102,184 +104,134 @@ public final class RowRecordsAggregate extends Record {
* after them
*/
public int getRowBlockCount() {
- int size = records.size()/DBCellRecord.BLOCK_SIZE;
- if ((records.size() % DBCellRecord.BLOCK_SIZE) != 0)
+ int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE;
+ if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0)
size++;
return size;
}
- public int getRowBlockSize(int block) {
- return 20 * getRowCountForBlock(block);
+ private int getRowBlockSize(int block) {
+ return RowRecord.ENCODED_SIZE * getRowCountForBlock(block);
}
/** Returns the number of physical rows within a block*/
public int getRowCountForBlock(int block) {
int startIndex = block * DBCellRecord.BLOCK_SIZE;
int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1;
- if (endIndex >= records.size())
- endIndex = records.size()-1;
+ if (endIndex >= _rowRecords.size())
+ endIndex = _rowRecords.size()-1;
return endIndex-startIndex+1;
}
/** Returns the physical row number of the first row in a block*/
- public int getStartRowNumberForBlock(int block) {
+ private int getStartRowNumberForBlock(int block) {
//Given that we basically iterate through the rows in order,
- //For a performance improvement, it would be better to return an instance of
+ // TODO - For a performance improvement, it would be better to return an instance of
//an iterator and use that instance throughout, rather than recreating one and
//having to move it to the right position.
int startIndex = block * DBCellRecord.BLOCK_SIZE;
- Iterator rowIter = records.values().iterator();
+ Iterator rowIter = _rowRecords.values().iterator();
RowRecord row = null;
//Position the iterator at the start of the block
for (int i=0; i<=startIndex;i++) {
row = (RowRecord)rowIter.next();
}
+ if (row == null) {
+ throw new RuntimeException("Did not find start row for block " + block);
+ }
return row.getRowNumber();
}
/** Returns the physical row number of the end row in a block*/
- public int getEndRowNumberForBlock(int block) {
+ private int getEndRowNumberForBlock(int block) {
int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1;
- if (endIndex >= records.size())
- endIndex = records.size()-1;
+ if (endIndex >= _rowRecords.size())
+ endIndex = _rowRecords.size()-1;
- Iterator rowIter = records.values().iterator();
+ Iterator rowIter = _rowRecords.values().iterator();
RowRecord row = null;
for (int i=0; i<=endIndex;i++) {
row = (RowRecord)rowIter.next();
}
+ if (row == null) {
+ throw new RuntimeException("Did not find start row for block " + block);
+ }
return row.getRowNumber();
}
-
-
- /** Serializes a block of the rows */
- private int serializeRowBlock(final int block, final int offset, byte[] data) {
- final int startIndex = block*DBCellRecord.BLOCK_SIZE;
- final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE;
-
- Iterator rowIterator = records.values().iterator();
- int pos = offset;
-
- //Given that we basically iterate through the rows in order,
- //For a performance improvement, it would be better to return an instance of
- //an iterator and use that instance throughout, rather than recreating one and
- //having to move it to the right position.
- int i=0;
- for (;inull
otherwise
*/
@@ -79,19 +78,19 @@ public final class HSSFConditionalFormattingRule
return getFontFormatting(false);
}
/**
- * create a new font formatting structure if it does not exist,
+ * create a new font formatting structure if it does not exist,
* otherwise just return existing object.
- * @return - font formatting object, never returns null
.
+ * @return - font formatting object, never returns null
.
*/
public HSSFFontFormatting createFontFormatting()
{
return getFontFormatting(true);
}
-
+
private HSSFBorderFormatting getBorderFormatting(boolean create)
{
BorderFormatting borderFormatting = cfRuleRecord.getBorderFormatting();
- if ( borderFormatting != null)
+ if ( borderFormatting != null)
{
cfRuleRecord.setBorderFormatting(borderFormatting);
return new HSSFBorderFormatting(cfRuleRecord);
@@ -115,19 +114,19 @@ public final class HSSFConditionalFormattingRule
return getBorderFormatting(false);
}
/**
- * create a new border formatting structure if it does not exist,
+ * create a new border formatting structure if it does not exist,
* otherwise just return existing object.
- * @return - border formatting object, never returns null
.
+ * @return - border formatting object, never returns null
.
*/
public HSSFBorderFormatting createBorderFormatting()
{
return getBorderFormatting(true);
}
-
+
private HSSFPatternFormatting getPatternFormatting(boolean create)
{
PatternFormatting patternFormatting = cfRuleRecord.getPatternFormatting();
- if ( patternFormatting != null)
+ if ( patternFormatting != null)
{
cfRuleRecord.setPatternFormatting(patternFormatting);
return new HSSFPatternFormatting(cfRuleRecord);
@@ -143,7 +142,7 @@ public final class HSSFConditionalFormattingRule
return null;
}
}
-
+
/**
* @return - pattern formatting object if defined, null
otherwise
*/
@@ -152,15 +151,29 @@ public final class HSSFConditionalFormattingRule
return getPatternFormatting(false);
}
/**
- * create a new pattern formatting structure if it does not exist,
+ * create a new pattern formatting structure if it does not exist,
* otherwise just return existing object.
- * @return - pattern formatting object, never returns null
.
+ * @return - pattern formatting object, never returns null
.
*/
public HSSFPatternFormatting createPatternFormatting()
{
return getPatternFormatting(true);
}
-
+
+ /**
+ * @return - the conditiontype for the cfrule
+ */
+ public byte getConditionType() {
+ return cfRuleRecord.getConditionType();
+ }
+
+ /**
+ * @return - the comparisionoperatation for the cfrule
+ */
+ public byte getComparisonOperation() {
+ return cfRuleRecord.getComparisonOperation();
+ }
+
public String getFormula1()
{
return toFormulaString(cfRuleRecord.getParsedExpression1());
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
index 9ad89c34a5..1a2b98f430 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
@@ -102,20 +102,17 @@ public final class HSSFRow implements Comparable, Row {
}
/**
- * Use this to create new cells within the row and return it.
- *
- * The cell that is returned is a CELL_TYPE_BLANK. The type can be changed
- * either through calling setCellValue
or setCellType
.
- *
- * @param column - the column number this cell represents
- *
- * @return HSSFCell a high level representation of the created cell.
+ * @deprecated (Aug 2008) use {@link HSSFRow#createCell(int) }
*/
- public HSSFCell createCell(short column)
- {
- return this.createCell(column,HSSFCell.CELL_TYPE_BLANK);
+ public HSSFCell createCell(short columnIndex) {
+ return createCell((int)columnIndex);
+ }
+ /**
+ * @deprecated (Aug 2008) use {@link HSSFRow#createCell(int, int) }
+ */
+ public HSSFCell createCell(short columnIndex, int type) {
+ return createCell((int)columnIndex, type);
}
-
/**
* Use this to create new cells within the row and return it.
*
@@ -128,11 +125,7 @@ public final class HSSFRow implements Comparable, Row {
*/
public HSSFCell createCell(int column)
{
- short shortCellNum = (short)column;
- if(column > 0x7FFF) {
- shortCellNum = (short)(0xffff - column);
- }
- return this.createCell(shortCellNum,HSSFCell.CELL_TYPE_BLANK);
+ return this.createCell(column,HSSFCell.CELL_TYPE_BLANK);
}
/**
@@ -141,14 +134,18 @@ public final class HSSFRow implements Comparable, Row {
* The cell that is returned is a CELL_TYPE_BLANK. The type can be changed
* either through calling setCellValue or setCellType.
*
- * @param column - the column number this cell represents
+ * @param columnIndex - the column number this cell represents
*
* @return HSSFCell a high level representation of the created cell.
*/
- public HSSFCell createCell(short column, int type)
+ public HSSFCell createCell(int columnIndex, int type)
{
- HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), column, type);
+ short shortCellNum = (short)columnIndex;
+ if(columnIndex > 0x7FFF) {
+ shortCellNum = (short)(0xffff - columnIndex);
+ }
+ HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), shortCellNum, type);
addCell(cell);
sheet.addValueRecord(getRowNum(), cell.getCellValueRecord());
return cell;
@@ -193,12 +190,12 @@ public final class HSSFRow implements Comparable, Row {
* records too.
*/
protected void removeAllCells() {
- for(int i=0; itrue
if there is a page break at the indicated row
*/
public boolean isRowBroken(int row) {
- return sheet.isRowBroken(row);
+ return sheet.getPageSettings().isRowBroken(row);
}
/**
* Removes the page break at the indicated row
- * @param row
*/
public void removeRowBreak(int row) {
- sheet.removeRowBreak(row);
+ sheet.getPageSettings().removeRowBreak(row);
}
/**
@@ -1468,7 +1434,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
*/
public int[] getRowBreaks(){
//we can probably cache this information, but this should be a sparsely used function
- return sheet.getRowBreaks();
+ return sheet.getPageSettings().getRowBreaks();
}
/**
@@ -1476,7 +1442,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
*/
public int[] getColumnBreaks(){
//we can probably cache this information, but this should be a sparsely used function
- return sheet.getColumnBreaks();
+ return sheet.getPageSettings().getColumnBreaks();
}
@@ -1486,7 +1452,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
*/
public void setColumnBreak(short column) {
validateColumn(column);
- sheet.setColumnBreak(column, (short)0, (short)65535);
+ sheet.getPageSettings().setColumnBreak(column, (short)0, (short)65535);
}
/**
@@ -1495,7 +1461,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
* @return FIXME: Document this!
*/
public boolean isColumnBroken(short column) {
- return sheet.isColumnBroken(column);
+ return sheet.getPageSettings().isColumnBroken(column);
}
/**
@@ -1503,7 +1469,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
* @param column
*/
public void removeColumnBreak(short column) {
- sheet.removeColumnBreak(column);
+ sheet.getPageSettings().removeColumnBreak(column);
}
/**
@@ -1610,9 +1576,9 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
* start from scratch!
*/
public HSSFPatriarch getDrawingPatriarch() {
- EscherAggregate agg = getDrawingEscherAggregate();
- if(agg == null) return null;
-
+ EscherAggregate agg = getDrawingEscherAggregate();
+ if(agg == null) return null;
+
HSSFPatriarch patriarch = new HSSFPatriarch(this, agg);
agg.setPatriarch(patriarch);
@@ -1687,7 +1653,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
* @param column the column index
*/
public void autoSizeColumn(short column) {
- autoSizeColumn(column, false);
+ autoSizeColumn(column, false);
}
/**
@@ -1736,19 +1702,19 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
HSSFCell cell = row.getCell(column);
if (cell == null) {
- continue;
- }
+ continue;
+ }
int colspan = 1;
for (int i = 0 ; i < getNumMergedRegions(); i++) {
CellRangeAddress region = getMergedRegion(i);
- if (containsCell(region, row.getRowNum(), column)) {
- if (!useMergedCells) {
- // If we're not using merged cells, skip this one and move on to the next.
- continue rows;
- }
- cell = row.getCell(region.getFirstColumn());
- colspan = 1 + region.getLastColumn() - region.getFirstColumn();
+ if (containsCell(region, row.getRowNum(), column)) {
+ if (!useMergedCells) {
+ // If we're not using merged cells, skip this one and move on to the next.
+ continue rows;
+ }
+ cell = row.getCell(region.getFirstColumn());
+ colspan = 1 + region.getLastColumn() - region.getFirstColumn();
}
}
@@ -1839,7 +1805,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
}
if (width != -1) {
if (width > Short.MAX_VALUE) { //width can be bigger that Short.MAX_VALUE!
- width = Short.MAX_VALUE;
+ width = Short.MAX_VALUE;
}
sheet.setColumnWidth(column, (short) (width * 256));
}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
index 5422776fc1..e663f38f2a 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
@@ -272,21 +272,11 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
// convert all LabelRecord records to LabelSSTRecord
convertLabelRecords(records, recOffset);
- while (recOffset < records.size())
- {
+ while (recOffset < records.size()) {
Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset );
- recOffset = sheet.getEofLoc()+1;
- if (recOffset == 1)
- {
- break;
- }
-
- HSSFSheet hsheet = new HSSFSheet(this, sheet);
-
- _sheets.add(hsheet);
-
- // workbook.setSheetName(sheets.size() -1, "Sheet"+sheets.size());
+ recOffset = sheet.getEofLoc()+1; // TODO - use better technique to keep track of the used records
+ _sheets.add(new HSSFSheet(this, sheet));
}
for (int i = 0 ; i < workbook.getNumNames() ; ++i){
diff --git a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java
index 0c46c5863d..bbed1cfdbb 100644
--- a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java
+++ b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java
@@ -59,8 +59,7 @@ public interface Row extends Iterable