123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- /* ====================================================================
- 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 static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
-
- import java.util.Collections;
- import java.util.LinkedHashMap;
- import java.util.Map;
- import java.util.function.Supplier;
-
- import org.apache.poi.util.BitField;
- import org.apache.poi.util.BitFieldFactory;
- import org.apache.poi.util.LittleEndianOutput;
-
- /**
- * Stores the row information for the sheet.
- *
- * @since 2.0-pre
- */
- public final class RowRecord extends StandardRecord {
- public static final 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 static final BitField outlineLevel = BitFieldFactory.getInstance(0x07);
- // bit 3 reserved
- private static final BitField collapsed = 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);
-
- 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 phoneticGuide = BitFieldFactory.getInstance(0x4000);
- // bit 15 is unused
-
- 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;
- /** 16 bit options flags */
- private int field_8_option_flags; // only if isFormatted
-
- public RowRecord(RowRecord other) {
- super(other);
- field_1_row_number = other.field_1_row_number;
- field_2_first_col = other.field_2_first_col;
- field_3_last_col = other.field_3_last_col;
- field_4_height = other.field_4_height;
- field_5_optimize = other.field_5_optimize;
- field_6_reserved = other.field_6_reserved;
- field_7_option_flags = other.field_7_option_flags;
- field_8_option_flags = other.field_8_option_flags;
- }
-
-
- 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 = collapsed.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 = phoneticGuide.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 (collapsed.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 phoneticGuide.isSet(field_8_option_flags);
- }
-
- 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;
- }
-
- @Override
- public RowRecord copy() {
- return new RowRecord(this);
- }
-
- @Override
- public HSSFRecordTypes getGenericRecordType() {
- return HSSFRecordTypes.ROW;
- }
-
- @Override
- public Map<String, Supplier<?>> getGenericProperties() {
- final Map<String,Supplier<?>> m = new LinkedHashMap<>();
- m.put("rowNumber", this::getRowNumber);
- m.put("firstCol", this::getFirstCol);
- m.put("lastCol", this::getLastCol);
- m.put("height", this::getHeight);
- m.put("optimized", this::getOptimize);
- m.put("reserved", () -> field_6_reserved);
- m.put("options", getBitsAsString(this::getOptionFlags,
- new BitField[]{collapsed,zeroHeight,badFontHeight,formatted},
- new String[]{"COLAPSED","ZERO_HEIGHT","BAD_FONT_HEIGHT","FORMATTED"}));
- m.put("outlineLevel", this::getOutlineLevel);
- m.put("optionFlags2", getBitsAsString(this::getOptionFlags2,
- new BitField[]{topBorder, bottomBorder, phoneticGuide},
- new String[]{"TOP_BORDER","BOTTOM_BORDER","PHOENETIC_GUIDE"}));
- m.put("xfIndex", this::getXFIndex);
- return Collections.unmodifiableMap(m);
- }
- }
|