You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RowRecord.java 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.hssf.record;
  16. import org.apache.poi.util.BitField;
  17. import org.apache.poi.util.BitFieldFactory;
  18. import org.apache.poi.util.HexDump;
  19. import org.apache.poi.util.LittleEndianOutput;
  20. /**
  21. * Title: Row Record (0x0208)<P/>
  22. * Description: stores the row information for the sheet. <P/>
  23. * REFERENCE: PG 379 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
  24. * @author Andrew C. Oliver (acoliver at apache dot org)
  25. * @author Jason Height (jheight at chariot dot net dot au)
  26. * @version 2.0-pre
  27. */
  28. public final class RowRecord extends StandardRecord {
  29. public final static short sid = 0x0208;
  30. public static final int ENCODED_SIZE = 20;
  31. private static final int OPTION_BITS_ALWAYS_SET = 0x0100;
  32. //private static final int DEFAULT_HEIGHT_BIT = 0x8000;
  33. private int field_1_row_number;
  34. private int field_2_first_col;
  35. private int field_3_last_col; // plus 1
  36. private short field_4_height;
  37. private short field_5_optimize; // hint field for gui, can/should be set to zero
  38. // for generated sheets.
  39. private short field_6_reserved;
  40. /** 16 bit options flags */
  41. private int field_7_option_flags;
  42. private static final BitField outlineLevel = BitFieldFactory.getInstance(0x07);
  43. // bit 3 reserved
  44. private static final BitField colapsed = BitFieldFactory.getInstance(0x10);
  45. private static final BitField zeroHeight = BitFieldFactory.getInstance(0x20);
  46. private static final BitField badFontHeight = BitFieldFactory.getInstance(0x40);
  47. private static final BitField formatted = BitFieldFactory.getInstance(0x80);
  48. /** 16 bit options flags */
  49. private int field_8_option_flags; // only if isFormatted
  50. private static final BitField xfIndex = BitFieldFactory.getInstance(0xFFF);
  51. private static final BitField topBorder = BitFieldFactory.getInstance(0x1000);
  52. private static final BitField bottomBorder = BitFieldFactory.getInstance(0x2000);
  53. private static final BitField phoeneticGuide = BitFieldFactory.getInstance(0x4000);
  54. // bit 15 is unused
  55. public RowRecord(int rowNumber) {
  56. if(rowNumber < 0) {
  57. throw new IllegalArgumentException("Invalid row number (" + rowNumber + ")");
  58. }
  59. field_1_row_number = rowNumber;
  60. field_4_height = (short)0xFF;
  61. field_5_optimize = ( short ) 0;
  62. field_6_reserved = ( short ) 0;
  63. field_7_option_flags = OPTION_BITS_ALWAYS_SET; // seems necessary for outlining
  64. field_8_option_flags = ( short ) 0xf;
  65. setEmpty();
  66. }
  67. public RowRecord(RecordInputStream in) {
  68. field_1_row_number = in.readUShort();
  69. if(field_1_row_number < 0) {
  70. throw new IllegalArgumentException("Invalid row number " + field_1_row_number + " found in InputStream");
  71. }
  72. field_2_first_col = in.readShort();
  73. field_3_last_col = in.readShort();
  74. field_4_height = in.readShort();
  75. field_5_optimize = in.readShort();
  76. field_6_reserved = in.readShort();
  77. field_7_option_flags = in.readShort();
  78. field_8_option_flags = in.readShort();
  79. }
  80. /**
  81. * Updates the firstCol and lastCol fields to the reserved value (-1)
  82. * to signify that this row is empty
  83. */
  84. public void setEmpty() {
  85. field_2_first_col = 0;
  86. field_3_last_col = 0;
  87. }
  88. public boolean isEmpty() {
  89. return (field_2_first_col | field_3_last_col) == 0;
  90. }
  91. /**
  92. * set the logical row number for this row (0 based index)
  93. * @param row - the row number
  94. */
  95. public void setRowNumber(int row) {
  96. field_1_row_number = row;
  97. }
  98. /**
  99. * set the logical col number for the first cell this row (0 based index)
  100. * @param col - the col number
  101. */
  102. public void setFirstCol(int col) {
  103. field_2_first_col = col;
  104. }
  105. /**
  106. * @param col - one past the zero-based index to the last cell in this row
  107. */
  108. public void setLastCol(int col) {
  109. field_3_last_col = col;
  110. }
  111. /**
  112. * set the height of the row
  113. * @param height of the row
  114. */
  115. public void setHeight(short height) {
  116. field_4_height = height;
  117. }
  118. /**
  119. * set whether to optimize or not (set to 0)
  120. * @param optimize (set to 0)
  121. */
  122. public void setOptimize(short optimize) {
  123. field_5_optimize = optimize;
  124. }
  125. // option bitfields
  126. /**
  127. * set the outline level of this row
  128. * @param ol - the outline level
  129. */
  130. public void setOutlineLevel(short ol) {
  131. field_7_option_flags = outlineLevel.setValue(field_7_option_flags, ol);
  132. }
  133. /**
  134. * set whether or not to collapse this row
  135. * @param c - collapse or not
  136. */
  137. public void setColapsed(boolean c) {
  138. field_7_option_flags = colapsed.setBoolean(field_7_option_flags, c);
  139. }
  140. /**
  141. * set whether or not to display this row with 0 height
  142. * @param z height is zero or not.
  143. */
  144. public void setZeroHeight(boolean z) {
  145. field_7_option_flags = zeroHeight.setBoolean(field_7_option_flags, z);
  146. }
  147. /**
  148. * set whether the font and row height are not compatible
  149. * @param f true if they aren't compatible (damn not logic)
  150. */
  151. public void setBadFontHeight(boolean f) {
  152. field_7_option_flags = badFontHeight.setBoolean(field_7_option_flags, f);
  153. }
  154. /**
  155. * set whether the row has been formatted (even if its got all blank cells)
  156. * @param f formatted or not
  157. */
  158. public void setFormatted(boolean f) {
  159. field_7_option_flags = formatted.setBoolean(field_7_option_flags, f);
  160. }
  161. // end bitfields
  162. /**
  163. * if the row is formatted then this is the index to the extended format record
  164. * @see org.apache.poi.hssf.record.ExtendedFormatRecord
  165. * @param index to the XF record
  166. */
  167. public void setXFIndex(short index) {
  168. field_8_option_flags = xfIndex.setValue(field_8_option_flags, index);
  169. }
  170. /**
  171. * bit that specifies whether any cell in the row has a thick top border, or any
  172. * cell in the row directly above the current row has a thick bottom border.
  173. * @param f has thick top border
  174. */
  175. public void setTopBorder(boolean f) {
  176. field_8_option_flags = topBorder.setBoolean(field_8_option_flags, f);
  177. }
  178. /**
  179. * A bit that specifies whether any cell in the row has a medium or thick
  180. * bottom border, or any cell in the row directly below the current row has
  181. * a medium or thick top border.
  182. * @param f has thick bottom border
  183. */
  184. public void setBottomBorder(boolean f) {
  185. field_8_option_flags = bottomBorder.setBoolean(field_8_option_flags, f);
  186. }
  187. /**
  188. * A bit that specifies whether the phonetic guide feature is enabled for
  189. * any cell in this row.
  190. * @param f use phoenetic guide
  191. */
  192. public void setPhoeneticGuide(boolean f) {
  193. field_8_option_flags = phoeneticGuide.setBoolean(field_8_option_flags, f);
  194. }
  195. /**
  196. * get the logical row number for this row (0 based index)
  197. * @return row - the row number
  198. */
  199. public int getRowNumber() {
  200. return field_1_row_number;
  201. }
  202. /**
  203. * get the logical col number for the first cell this row (0 based index)
  204. * @return col - the col number
  205. */
  206. public int getFirstCol() {
  207. return field_2_first_col;
  208. }
  209. /**
  210. * get the logical col number for the last cell this row (0 based index), plus one
  211. * @return col - the last col index + 1
  212. */
  213. public int getLastCol() {
  214. return field_3_last_col;
  215. }
  216. /**
  217. * get the height of the row
  218. * @return height of the row
  219. */
  220. public short getHeight() {
  221. return field_4_height;
  222. }
  223. /**
  224. * get whether to optimize or not (set to 0)
  225. * @return optimize (set to 0)
  226. */
  227. public short getOptimize() {
  228. return field_5_optimize;
  229. }
  230. /**
  231. * gets the option bitmask. (use the individual bit setters that refer to this
  232. * method)
  233. * @return options - the bitmask
  234. */
  235. public short getOptionFlags() {
  236. return (short)field_7_option_flags;
  237. }
  238. // option bitfields
  239. /**
  240. * get the outline level of this row
  241. * @return ol - the outline level
  242. * @see #getOptionFlags()
  243. */
  244. public short getOutlineLevel() {
  245. return (short)outlineLevel.getValue(field_7_option_flags);
  246. }
  247. /**
  248. * get whether or not to colapse this row
  249. * @return c - colapse or not
  250. * @see #getOptionFlags()
  251. */
  252. public boolean getColapsed() {
  253. return (colapsed.isSet(field_7_option_flags));
  254. }
  255. /**
  256. * get whether or not to display this row with 0 height
  257. * @return - z height is zero or not.
  258. * @see #getOptionFlags()
  259. */
  260. public boolean getZeroHeight() {
  261. return zeroHeight.isSet(field_7_option_flags);
  262. }
  263. /**
  264. * get whether the font and row height are not compatible
  265. * @return - f -true if they aren't compatible (damn not logic)
  266. * @see #getOptionFlags()
  267. */
  268. public boolean getBadFontHeight() {
  269. return badFontHeight.isSet(field_7_option_flags);
  270. }
  271. /**
  272. * get whether the row has been formatted (even if its got all blank cells)
  273. * @return formatted or not
  274. * @see #getOptionFlags()
  275. */
  276. public boolean getFormatted() {
  277. return formatted.isSet(field_7_option_flags);
  278. }
  279. // end bitfields
  280. /**
  281. * gets the 2nd option bitmask. (use the individual bit setters that refer to this
  282. * method)
  283. * @return options - the bitmask
  284. */
  285. public short getOptionFlags2() {
  286. return (short)field_8_option_flags;
  287. }
  288. /**
  289. * if the row is formatted then this is the index to the extended format record
  290. * @see org.apache.poi.hssf.record.ExtendedFormatRecord
  291. * @return index to the XF record or bogus value (undefined) if isn't formatted
  292. */
  293. public short getXFIndex() {
  294. return xfIndex.getShortValue((short)field_8_option_flags);
  295. }
  296. /**
  297. * A bit that specifies whether any cell in the row has a thick top border, or any
  298. * cell in the row directly above the current row has a thick bottom border.
  299. * @return has cells with a thick top border
  300. */
  301. public boolean getTopBorder() {
  302. return topBorder.isSet(field_8_option_flags);
  303. }
  304. /**
  305. * A bit that specifies whether any cell in the row has a medium or thick bottom border,
  306. * or any cell in the row directly below the current row has a medium or thick top border.
  307. * @return has cells with a thick bottom border
  308. */
  309. public boolean getBottomBorder() {
  310. return bottomBorder.isSet(field_8_option_flags);
  311. }
  312. /**
  313. * A bit that specifies whether the phonetic guide feature is enabled for
  314. * any cell in this row.
  315. * @return has phoentic guide
  316. */
  317. public boolean getPhoeneticGuide() {
  318. return phoeneticGuide.isSet(field_8_option_flags);
  319. }
  320. public String toString() {
  321. StringBuffer sb = new StringBuffer();
  322. sb.append("[ROW]\n");
  323. sb.append(" .rownumber = ").append(Integer.toHexString(getRowNumber()))
  324. .append("\n");
  325. sb.append(" .firstcol = ").append(HexDump.shortToHex(getFirstCol())).append("\n");
  326. sb.append(" .lastcol = ").append(HexDump.shortToHex(getLastCol())).append("\n");
  327. sb.append(" .height = ").append(HexDump.shortToHex(getHeight())).append("\n");
  328. sb.append(" .optimize = ").append(HexDump.shortToHex(getOptimize())).append("\n");
  329. sb.append(" .reserved = ").append(HexDump.shortToHex(field_6_reserved)).append("\n");
  330. sb.append(" .optionflags = ").append(HexDump.shortToHex(getOptionFlags())).append("\n");
  331. sb.append(" .outlinelvl = ").append(Integer.toHexString(getOutlineLevel())).append("\n");
  332. sb.append(" .colapsed = ").append(getColapsed()).append("\n");
  333. sb.append(" .zeroheight = ").append(getZeroHeight()).append("\n");
  334. sb.append(" .badfontheig= ").append(getBadFontHeight()).append("\n");
  335. sb.append(" .formatted = ").append(getFormatted()).append("\n");
  336. sb.append(" .optionsflags2 = ").append(HexDump.shortToHex(getOptionFlags2())).append("\n");
  337. sb.append(" .xfindex = ").append(Integer.toHexString(getXFIndex())).append("\n");
  338. sb.append(" .topBorder = ").append(getTopBorder()).append("\n");
  339. sb.append(" .bottomBorder = ").append(getBottomBorder()).append("\n");
  340. sb.append(" .phoeneticGuide= ").append(getPhoeneticGuide()).append("\n");
  341. sb.append("[/ROW]\n");
  342. return sb.toString();
  343. }
  344. public void serialize(LittleEndianOutput out) {
  345. out.writeShort(getRowNumber());
  346. out.writeShort(getFirstCol() == -1 ? (short)0 : getFirstCol());
  347. out.writeShort(getLastCol() == -1 ? (short)0 : getLastCol());
  348. out.writeShort(getHeight());
  349. out.writeShort(getOptimize());
  350. out.writeShort(field_6_reserved);
  351. out.writeShort(getOptionFlags());
  352. out.writeShort(getOptionFlags2());
  353. }
  354. protected int getDataSize() {
  355. return ENCODED_SIZE - 4;
  356. }
  357. public short getSid() {
  358. return sid;
  359. }
  360. public Object clone() {
  361. RowRecord rec = new RowRecord(field_1_row_number);
  362. rec.field_2_first_col = field_2_first_col;
  363. rec.field_3_last_col = field_3_last_col;
  364. rec.field_4_height = field_4_height;
  365. rec.field_5_optimize = field_5_optimize;
  366. rec.field_6_reserved = field_6_reserved;
  367. rec.field_7_option_flags = field_7_option_flags;
  368. rec.field_8_option_flags = field_8_option_flags;
  369. return rec;
  370. }
  371. }