425 lines
14 KiB
Java
425 lines
14 KiB
Java
/* ====================================================================
|
|
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;
|
|
|
|
import org.apache.poi.util.BitField;
|
|
import org.apache.poi.util.BitFieldFactory;
|
|
import org.apache.poi.util.HexDump;
|
|
import org.apache.poi.util.LittleEndianOutput;
|
|
|
|
/**
|
|
* Title: Row Record (0x0208)<p>
|
|
* Description: stores the row information for the sheet.<p>
|
|
* REFERENCE: PG 379 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
|
*
|
|
* @since 2.0-pre
|
|
*/
|
|
public final class RowRecord extends StandardRecord {
|
|
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;
|
|
|
|
private int field_1_row_number;
|
|
private int field_2_first_col;
|
|
private int field_3_last_col; // plus 1
|
|
private short field_4_height;
|
|
private short field_5_optimize; // hint field for gui, can/should be set to zero
|
|
|
|
// for generated sheets.
|
|
private short field_6_reserved;
|
|
/** 16 bit options flags */
|
|
private int field_7_option_flags;
|
|
private static final BitField outlineLevel = BitFieldFactory.getInstance(0x07);
|
|
// bit 3 reserved
|
|
private static final BitField colapsed = BitFieldFactory.getInstance(0x10);
|
|
private static final BitField zeroHeight = BitFieldFactory.getInstance(0x20);
|
|
private static final BitField badFontHeight = BitFieldFactory.getInstance(0x40);
|
|
private static final BitField formatted = BitFieldFactory.getInstance(0x80);
|
|
|
|
/** 16 bit options flags */
|
|
private int field_8_option_flags; // only if isFormatted
|
|
private static final BitField xfIndex = BitFieldFactory.getInstance(0xFFF);
|
|
private static final BitField topBorder = BitFieldFactory.getInstance(0x1000);
|
|
private static final BitField bottomBorder = BitFieldFactory.getInstance(0x2000);
|
|
private static final BitField phoeneticGuide = BitFieldFactory.getInstance(0x4000);
|
|
// bit 15 is unused
|
|
|
|
public RowRecord(int rowNumber) {
|
|
if(rowNumber < 0) {
|
|
throw new IllegalArgumentException("Invalid row number (" + rowNumber + ")");
|
|
}
|
|
field_1_row_number = rowNumber;
|
|
field_4_height = (short)0xFF;
|
|
field_5_optimize = ( short ) 0;
|
|
field_6_reserved = ( short ) 0;
|
|
field_7_option_flags = OPTION_BITS_ALWAYS_SET; // seems necessary for outlining
|
|
|
|
field_8_option_flags = ( short ) 0xf;
|
|
setEmpty();
|
|
}
|
|
|
|
public RowRecord(RecordInputStream in) {
|
|
field_1_row_number = in.readUShort();
|
|
if(field_1_row_number < 0) {
|
|
throw new IllegalArgumentException("Invalid row number " + field_1_row_number + " found in InputStream");
|
|
}
|
|
field_2_first_col = in.readShort();
|
|
field_3_last_col = in.readShort();
|
|
field_4_height = in.readShort();
|
|
field_5_optimize = in.readShort();
|
|
field_6_reserved = in.readShort();
|
|
field_7_option_flags = in.readShort();
|
|
field_8_option_flags = in.readShort();
|
|
}
|
|
|
|
/**
|
|
* Updates the firstCol and lastCol fields to the reserved value (-1)
|
|
* to signify that this row is empty
|
|
*/
|
|
public void setEmpty() {
|
|
field_2_first_col = 0;
|
|
field_3_last_col = 0;
|
|
}
|
|
public boolean isEmpty() {
|
|
return (field_2_first_col | field_3_last_col) == 0;
|
|
}
|
|
|
|
/**
|
|
* set the logical row number for this row (0 based index)
|
|
* @param row - the row number
|
|
*/
|
|
public void setRowNumber(int row) {
|
|
field_1_row_number = row;
|
|
}
|
|
|
|
/**
|
|
* set the logical col number for the first cell this row (0 based index)
|
|
* @param col - the col number
|
|
*/
|
|
public void setFirstCol(int col) {
|
|
field_2_first_col = col;
|
|
}
|
|
|
|
/**
|
|
* @param col - one past the zero-based index to the last cell in this row
|
|
*/
|
|
public void setLastCol(int col) {
|
|
field_3_last_col = col;
|
|
}
|
|
|
|
/**
|
|
* set the height of the row
|
|
* @param height of the row
|
|
*/
|
|
public void setHeight(short height) {
|
|
field_4_height = height;
|
|
}
|
|
|
|
/**
|
|
* set whether to optimize or not (set to 0)
|
|
* @param optimize (set to 0)
|
|
*/
|
|
public void setOptimize(short optimize) {
|
|
field_5_optimize = optimize;
|
|
}
|
|
|
|
// option bitfields
|
|
|
|
/**
|
|
* set the outline level of this row
|
|
* @param ol - the outline level
|
|
*/
|
|
public void setOutlineLevel(short ol) {
|
|
field_7_option_flags = outlineLevel.setValue(field_7_option_flags, ol);
|
|
}
|
|
|
|
/**
|
|
* set whether or not to collapse this row
|
|
* @param c - collapse or not
|
|
*/
|
|
public void setColapsed(boolean c) {
|
|
field_7_option_flags = colapsed.setBoolean(field_7_option_flags, c);
|
|
}
|
|
|
|
/**
|
|
* set whether or not to display this row with 0 height
|
|
* @param z height is zero or not.
|
|
*/
|
|
public void setZeroHeight(boolean z) {
|
|
field_7_option_flags = zeroHeight.setBoolean(field_7_option_flags, z);
|
|
}
|
|
|
|
/**
|
|
* set whether the font and row height are not compatible
|
|
* @param f true if they aren't compatible (damn not logic)
|
|
*/
|
|
public void setBadFontHeight(boolean f) {
|
|
field_7_option_flags = badFontHeight.setBoolean(field_7_option_flags, f);
|
|
}
|
|
|
|
/**
|
|
* set whether the row has been formatted (even if its got all blank cells)
|
|
* @param f formatted or not
|
|
*/
|
|
public void setFormatted(boolean f) {
|
|
field_7_option_flags = formatted.setBoolean(field_7_option_flags, f);
|
|
}
|
|
|
|
// end bitfields
|
|
|
|
/**
|
|
* if the row is formatted then this is the index to the extended format record
|
|
* @see org.apache.poi.hssf.record.ExtendedFormatRecord
|
|
* @param index to the XF record
|
|
*/
|
|
public void setXFIndex(short index) {
|
|
field_8_option_flags = xfIndex.setValue(field_8_option_flags, index);
|
|
}
|
|
|
|
/**
|
|
* bit that specifies whether any cell in the row has a thick top border, or any
|
|
* cell in the row directly above the current row has a thick bottom border.
|
|
* @param f has thick top border
|
|
*/
|
|
public void setTopBorder(boolean f) {
|
|
field_8_option_flags = topBorder.setBoolean(field_8_option_flags, f);
|
|
}
|
|
|
|
/**
|
|
* A bit that specifies whether any cell in the row has a medium or thick
|
|
* bottom border, or any cell in the row directly below the current row has
|
|
* a medium or thick top border.
|
|
* @param f has thick bottom border
|
|
*/
|
|
public void setBottomBorder(boolean f) {
|
|
field_8_option_flags = bottomBorder.setBoolean(field_8_option_flags, f);
|
|
}
|
|
|
|
/**
|
|
* A bit that specifies whether the phonetic guide feature is enabled for
|
|
* any cell in this row.
|
|
* @param f use phoenetic guide
|
|
*/
|
|
public void setPhoeneticGuide(boolean f) {
|
|
field_8_option_flags = phoeneticGuide.setBoolean(field_8_option_flags, f);
|
|
}
|
|
|
|
/**
|
|
* get the logical row number for this row (0 based index)
|
|
* @return row - the row number
|
|
*/
|
|
public int getRowNumber() {
|
|
return field_1_row_number;
|
|
}
|
|
|
|
/**
|
|
* get the logical col number for the first cell this row (0 based index)
|
|
* @return col - the col number
|
|
*/
|
|
public int getFirstCol() {
|
|
return field_2_first_col;
|
|
}
|
|
|
|
/**
|
|
* get the logical col number for the last cell this row (0 based index), plus one
|
|
* @return col - the last col index + 1
|
|
*/
|
|
public int getLastCol() {
|
|
return field_3_last_col;
|
|
}
|
|
|
|
/**
|
|
* get the height of the row
|
|
* @return height of the row
|
|
*/
|
|
public short getHeight() {
|
|
return field_4_height;
|
|
}
|
|
|
|
/**
|
|
* get whether to optimize or not (set to 0)
|
|
* @return optimize (set to 0)
|
|
*/
|
|
public short getOptimize() {
|
|
return field_5_optimize;
|
|
}
|
|
|
|
/**
|
|
* gets the option bitmask. (use the individual bit setters that refer to this
|
|
* method)
|
|
* @return options - the bitmask
|
|
*/
|
|
public short getOptionFlags() {
|
|
return (short)field_7_option_flags;
|
|
}
|
|
|
|
// option bitfields
|
|
|
|
/**
|
|
* get the outline level of this row
|
|
* @return ol - the outline level
|
|
* @see #getOptionFlags()
|
|
*/
|
|
public short getOutlineLevel() {
|
|
return (short)outlineLevel.getValue(field_7_option_flags);
|
|
}
|
|
|
|
/**
|
|
* get whether or not to colapse this row
|
|
* @return c - colapse or not
|
|
* @see #getOptionFlags()
|
|
*/
|
|
public boolean getColapsed() {
|
|
return (colapsed.isSet(field_7_option_flags));
|
|
}
|
|
|
|
/**
|
|
* get whether or not to display this row with 0 height
|
|
* @return - z height is zero or not.
|
|
* @see #getOptionFlags()
|
|
*/
|
|
public boolean getZeroHeight() {
|
|
return zeroHeight.isSet(field_7_option_flags);
|
|
}
|
|
|
|
/**
|
|
* get whether the font and row height are not compatible
|
|
* @return - f -true if they aren't compatible (damn not logic)
|
|
* @see #getOptionFlags()
|
|
*/
|
|
public boolean getBadFontHeight() {
|
|
return badFontHeight.isSet(field_7_option_flags);
|
|
}
|
|
|
|
/**
|
|
* get whether the row has been formatted (even if its got all blank cells)
|
|
* @return formatted or not
|
|
* @see #getOptionFlags()
|
|
*/
|
|
public boolean getFormatted() {
|
|
return formatted.isSet(field_7_option_flags);
|
|
}
|
|
|
|
// end bitfields
|
|
|
|
/**
|
|
* gets the 2nd option bitmask. (use the individual bit setters that refer to this
|
|
* method)
|
|
* @return options - the bitmask
|
|
*/
|
|
public short getOptionFlags2() {
|
|
return (short)field_8_option_flags;
|
|
}
|
|
|
|
/**
|
|
* if the row is formatted then this is the index to the extended format record
|
|
* @see org.apache.poi.hssf.record.ExtendedFormatRecord
|
|
* @return index to the XF record or bogus value (undefined) if isn't formatted
|
|
*/
|
|
public short getXFIndex() {
|
|
return xfIndex.getShortValue((short)field_8_option_flags);
|
|
}
|
|
|
|
/**
|
|
* A bit that specifies whether any cell in the row has a thick top border, or any
|
|
* cell in the row directly above the current row has a thick bottom border.
|
|
* @return has cells with a thick top border
|
|
*/
|
|
public boolean getTopBorder() {
|
|
return topBorder.isSet(field_8_option_flags);
|
|
}
|
|
|
|
/**
|
|
* A bit that specifies whether any cell in the row has a medium or thick bottom border,
|
|
* or any cell in the row directly below the current row has a medium or thick top border.
|
|
* @return has cells with a thick bottom border
|
|
*/
|
|
public boolean getBottomBorder() {
|
|
return bottomBorder.isSet(field_8_option_flags);
|
|
}
|
|
|
|
/**
|
|
* A bit that specifies whether the phonetic guide feature is enabled for
|
|
* any cell in this row.
|
|
* @return has phoentic guide
|
|
*/
|
|
public boolean getPhoeneticGuide() {
|
|
return phoeneticGuide.isSet(field_8_option_flags);
|
|
}
|
|
|
|
public String toString() {
|
|
StringBuffer sb = new StringBuffer();
|
|
|
|
sb.append("[ROW]\n");
|
|
sb.append(" .rownumber = ").append(Integer.toHexString(getRowNumber()))
|
|
.append("\n");
|
|
sb.append(" .firstcol = ").append(HexDump.shortToHex(getFirstCol())).append("\n");
|
|
sb.append(" .lastcol = ").append(HexDump.shortToHex(getLastCol())).append("\n");
|
|
sb.append(" .height = ").append(HexDump.shortToHex(getHeight())).append("\n");
|
|
sb.append(" .optimize = ").append(HexDump.shortToHex(getOptimize())).append("\n");
|
|
sb.append(" .reserved = ").append(HexDump.shortToHex(field_6_reserved)).append("\n");
|
|
sb.append(" .optionflags = ").append(HexDump.shortToHex(getOptionFlags())).append("\n");
|
|
sb.append(" .outlinelvl = ").append(Integer.toHexString(getOutlineLevel())).append("\n");
|
|
sb.append(" .colapsed = ").append(getColapsed()).append("\n");
|
|
sb.append(" .zeroheight = ").append(getZeroHeight()).append("\n");
|
|
sb.append(" .badfontheig= ").append(getBadFontHeight()).append("\n");
|
|
sb.append(" .formatted = ").append(getFormatted()).append("\n");
|
|
sb.append(" .optionsflags2 = ").append(HexDump.shortToHex(getOptionFlags2())).append("\n");
|
|
sb.append(" .xfindex = ").append(Integer.toHexString(getXFIndex())).append("\n");
|
|
sb.append(" .topBorder = ").append(getTopBorder()).append("\n");
|
|
sb.append(" .bottomBorder = ").append(getBottomBorder()).append("\n");
|
|
sb.append(" .phoeneticGuide= ").append(getPhoeneticGuide()).append("\n");
|
|
sb.append("[/ROW]\n");
|
|
return sb.toString();
|
|
}
|
|
|
|
public void serialize(LittleEndianOutput out) {
|
|
out.writeShort(getRowNumber());
|
|
out.writeShort(getFirstCol() == -1 ? (short)0 : getFirstCol());
|
|
out.writeShort(getLastCol() == -1 ? (short)0 : getLastCol());
|
|
out.writeShort(getHeight());
|
|
out.writeShort(getOptimize());
|
|
out.writeShort(field_6_reserved);
|
|
out.writeShort(getOptionFlags());
|
|
out.writeShort(getOptionFlags2());
|
|
}
|
|
|
|
protected int getDataSize() {
|
|
return ENCODED_SIZE - 4;
|
|
}
|
|
|
|
public short getSid() {
|
|
return sid;
|
|
}
|
|
|
|
public Object clone() {
|
|
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;
|
|
rec.field_5_optimize = field_5_optimize;
|
|
rec.field_6_reserved = field_6_reserved;
|
|
rec.field_7_option_flags = field_7_option_flags;
|
|
rec.field_8_option_flags = field_8_option_flags;
|
|
return rec;
|
|
}
|
|
}
|