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.

HSSFCellStyle.java 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  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.usermodel;
  16. import java.util.List;
  17. import java.util.Objects;
  18. import org.apache.poi.common.Duplicatable;
  19. import org.apache.poi.hssf.model.InternalWorkbook;
  20. import org.apache.poi.hssf.record.ExtendedFormatRecord;
  21. import org.apache.poi.hssf.record.FontRecord;
  22. import org.apache.poi.hssf.record.FormatRecord;
  23. import org.apache.poi.hssf.record.StyleRecord;
  24. import org.apache.poi.hssf.util.HSSFColor;
  25. import org.apache.poi.hssf.util.HSSFColor.HSSFColorPredefined;
  26. import org.apache.poi.ss.usermodel.BorderStyle;
  27. import org.apache.poi.ss.usermodel.CellStyle;
  28. import org.apache.poi.ss.usermodel.FillPatternType;
  29. import org.apache.poi.ss.usermodel.Font;
  30. import org.apache.poi.ss.usermodel.HorizontalAlignment;
  31. import org.apache.poi.ss.usermodel.VerticalAlignment;
  32. import org.apache.poi.util.Removal;
  33. import org.apache.poi.util.ThreadLocalUtil;
  34. /**
  35. * High level representation of the style of a cell in a sheet of a workbook.
  36. *
  37. * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createCellStyle()
  38. * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(int)
  39. * @see org.apache.poi.hssf.usermodel.HSSFCell#setCellStyle(HSSFCellStyle)
  40. */
  41. public final class HSSFCellStyle implements CellStyle, Duplicatable {
  42. private final ExtendedFormatRecord _format;
  43. private final short _index;
  44. private final InternalWorkbook _workbook;
  45. /** Creates new HSSFCellStyle why would you want to do this?? */
  46. protected HSSFCellStyle(short index, ExtendedFormatRecord rec, HSSFWorkbook workbook)
  47. {
  48. this(index, rec, workbook.getWorkbook());
  49. }
  50. protected HSSFCellStyle(short index, ExtendedFormatRecord rec, InternalWorkbook workbook)
  51. {
  52. _workbook = workbook;
  53. _index = index;
  54. _format = rec;
  55. }
  56. protected HSSFCellStyle(HSSFCellStyle other) {
  57. _workbook = other._workbook;
  58. _index = other._index;
  59. _format = other._format;
  60. }
  61. /**
  62. * get the index within the HSSFWorkbook (sequence within the collection of ExtendedFormat objects)
  63. * @return unique index number of the underlying record this style represents (probably you don't care
  64. * unless you're comparing which one is which)
  65. */
  66. @Override
  67. public short getIndex() {
  68. return _index;
  69. }
  70. /**
  71. * Return the parent style for this cell style.
  72. * In most cases this will be null, but in a few
  73. * cases there'll be a fully defined parent.
  74. */
  75. public HSSFCellStyle getParentStyle() {
  76. short parentIndex = _format.getParentIndex();
  77. // parentIndex equal 0xFFF indicates no inheritance from a cell style XF (See 2.4.353 XF)
  78. if(parentIndex == 0 || parentIndex == 0xFFF) {
  79. return null;
  80. }
  81. return new HSSFCellStyle(
  82. parentIndex,
  83. _workbook.getExFormatAt(parentIndex),
  84. _workbook
  85. );
  86. }
  87. /**
  88. * set the data format (must be a valid format)
  89. * @see org.apache.poi.hssf.usermodel.HSSFDataFormat
  90. */
  91. @Override
  92. public void setDataFormat(short fmt)
  93. {
  94. _format.setFormatIndex(fmt);
  95. }
  96. /**
  97. * get the index of the format
  98. * @see org.apache.poi.hssf.usermodel.HSSFDataFormat
  99. */
  100. @Override
  101. public short getDataFormat()
  102. {
  103. return _format.getFormatIndex();
  104. }
  105. // we keep the cached data in ThreadLocal members in order to
  106. // avoid multi-threading issues when different workbooks are accessed in
  107. // multiple threads at the same time
  108. private static final ThreadLocal<Short> lastDateFormat = ThreadLocal.withInitial(() -> Short.MIN_VALUE);
  109. private static final ThreadLocal<List<FormatRecord>> lastFormats = new ThreadLocal<>();
  110. private static final ThreadLocal<String> getDataFormatStringCache = new ThreadLocal<>();
  111. static {
  112. // allow to clear all thread-locals via ThreadLocalUtil
  113. ThreadLocalUtil.registerCleaner(() -> {
  114. lastDateFormat.remove();
  115. lastFormats.remove();
  116. getDataFormatStringCache.remove();
  117. });
  118. }
  119. /**
  120. * Get the contents of the format string, by looking up
  121. * the DataFormat against the bound workbook
  122. * @see org.apache.poi.hssf.usermodel.HSSFDataFormat
  123. * @return the format string or "General" if not found
  124. */
  125. @Override
  126. public String getDataFormatString() {
  127. if (getDataFormatStringCache.get() != null) {
  128. if (lastDateFormat.get() == getDataFormat() && _workbook.getFormats().equals(lastFormats.get())) {
  129. return getDataFormatStringCache.get();
  130. }
  131. }
  132. lastFormats.set(_workbook.getFormats());
  133. lastDateFormat.set(getDataFormat());
  134. getDataFormatStringCache.set(getDataFormatString(_workbook));
  135. return getDataFormatStringCache.get();
  136. }
  137. /**
  138. * Get the contents of the format string, by looking up
  139. * the DataFormat against the supplied workbook
  140. * @see org.apache.poi.hssf.usermodel.HSSFDataFormat
  141. *
  142. * @return the format string or "General" if not found
  143. */
  144. public String getDataFormatString(org.apache.poi.ss.usermodel.Workbook workbook) {
  145. HSSFDataFormat format = new HSSFDataFormat( ((HSSFWorkbook)workbook).getWorkbook() );
  146. int idx = getDataFormat();
  147. return idx == -1 ? "General" : format.getFormat(getDataFormat());
  148. }
  149. /**
  150. * Get the contents of the format string, by looking up
  151. * the DataFormat against the supplied low level workbook
  152. * @see org.apache.poi.hssf.usermodel.HSSFDataFormat
  153. */
  154. public String getDataFormatString(org.apache.poi.hssf.model.InternalWorkbook workbook) {
  155. HSSFDataFormat format = new HSSFDataFormat( workbook );
  156. return format.getFormat(getDataFormat());
  157. }
  158. /**
  159. * set the font for this style
  160. * @param font a font object created or retrieved from the HSSFWorkbook object
  161. * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createFont()
  162. * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(int)
  163. */
  164. @Override
  165. public void setFont(Font font) {
  166. setFont((HSSFFont)font);
  167. }
  168. public void setFont(HSSFFont font) {
  169. _format.setIndentNotParentFont(true);
  170. short fontindex = (short) font.getIndex();
  171. _format.setFontIndex(fontindex);
  172. }
  173. /**
  174. * gets the index of the font for this style
  175. * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(int)
  176. * @since 5.0.0 (used to return a short value)
  177. */
  178. @Override
  179. public int getFontIndex()
  180. {
  181. return _format.getFontIndex();
  182. }
  183. /**
  184. * gets the index of the font for this style
  185. * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(int)
  186. * @deprecated use {@link #getFontIndex()} instead
  187. * @since 4.0.0
  188. */
  189. @Deprecated
  190. @Removal(version = "6.0.0")
  191. @Override
  192. public int getFontIndexAsInt()
  193. {
  194. return _format.getFontIndex();
  195. }
  196. /**
  197. * gets the font for this style
  198. * @param parentWorkbook The HSSFWorkbook that this style belongs to
  199. * @see org.apache.poi.hssf.usermodel.HSSFCellStyle#getFontIndex()
  200. * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(int)
  201. */
  202. public HSSFFont getFont(org.apache.poi.ss.usermodel.Workbook parentWorkbook) {
  203. return ((HSSFWorkbook) parentWorkbook).getFontAt(getFontIndex());
  204. }
  205. /**
  206. * set the cell's using this style to be hidden
  207. * @param hidden - whether the cell using this style should be hidden
  208. */
  209. @Override
  210. public void setHidden(boolean hidden)
  211. {
  212. _format.setIndentNotParentCellOptions(true);
  213. _format.setHidden(hidden);
  214. }
  215. /**
  216. * get whether the cell's using this style are to be hidden
  217. * @return hidden - whether the cell using this style should be hidden
  218. */
  219. @Override
  220. public boolean getHidden()
  221. {
  222. return _format.isHidden();
  223. }
  224. /**
  225. * set the cell's using this style to be locked
  226. * @param locked - whether the cell using this style should be locked
  227. */
  228. @Override
  229. public void setLocked(boolean locked)
  230. {
  231. _format.setIndentNotParentCellOptions(true);
  232. _format.setLocked(locked);
  233. }
  234. /**
  235. * get whether the cell's using this style are to be locked
  236. * @return hidden - whether the cell using this style should be locked
  237. */
  238. @Override
  239. public boolean getLocked()
  240. {
  241. return _format.isLocked();
  242. }
  243. /**
  244. * Turn on or off "Quote Prefix" or "123 Prefix" for the style,
  245. * which is used to tell Excel that the thing which looks like
  246. * a number or a formula shouldn't be treated as on.
  247. */
  248. @Override
  249. public void setQuotePrefixed(boolean quotePrefix) {
  250. _format.set123Prefix(quotePrefix);
  251. }
  252. /**
  253. * Is "Quote Prefix" or "123 Prefix" enabled for the cell?
  254. */
  255. @Override
  256. public boolean getQuotePrefixed() {
  257. return _format.get123Prefix();
  258. }
  259. /**
  260. * set the type of horizontal alignment for the cell
  261. * @param align - the type of alignment
  262. */
  263. @Override
  264. public void setAlignment(HorizontalAlignment align)
  265. {
  266. _format.setIndentNotParentAlignment(true);
  267. _format.setAlignment(align.getCode());
  268. }
  269. @Override
  270. public HorizontalAlignment getAlignment()
  271. {
  272. return HorizontalAlignment.forInt(_format.getAlignment());
  273. }
  274. /**
  275. * set whether the text should be wrapped
  276. * @param wrapped wrap text or not
  277. */
  278. @Override
  279. public void setWrapText(boolean wrapped)
  280. {
  281. _format.setIndentNotParentAlignment(true);
  282. _format.setWrapText(wrapped);
  283. }
  284. /**
  285. * get whether the text should be wrapped
  286. * @return wrap text or not
  287. */
  288. @Override
  289. public boolean getWrapText()
  290. {
  291. return _format.getWrapText();
  292. }
  293. /**
  294. * set the type of vertical alignment for the cell
  295. * @param align the type of alignment
  296. */
  297. @Override
  298. public void setVerticalAlignment(VerticalAlignment align)
  299. {
  300. _format.setVerticalAlignment(align.getCode());
  301. }
  302. @Override
  303. public VerticalAlignment getVerticalAlignment() {
  304. return VerticalAlignment.forInt(_format.getVerticalAlignment());
  305. }
  306. /**
  307. * set the degree of rotation for the text in the cell
  308. *
  309. * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF
  310. * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges
  311. * accordingly, however the corresponding getter is returning values in the range mandated by the current type
  312. * of Excel file-format that this CellStyle is applied to.
  313. *
  314. * @param rotation degrees (between -90 and 90 degrees, of 0xff for vertical)
  315. */
  316. @Override
  317. public void setRotation(short rotation)
  318. {
  319. if (rotation == 0xff) {
  320. // Special cases for vertically aligned text
  321. }
  322. else if ((rotation < 0)&&(rotation >= -90)) {
  323. //Take care of the funny 4th quadrant issue
  324. //The 4th quadrant (-1 to -90) is stored as (91 to 180)
  325. rotation = (short)(90 - rotation);
  326. }
  327. else if (rotation > 90 && rotation <= 180) {
  328. // stay compatible with the range used by XSSF, map from ]90..180] to ]0..-90]
  329. // we actually don't need to do anything here as the internal value is stored in [0-180] anyway!
  330. }
  331. else if ((rotation < -90) || (rotation > 90)) {
  332. //Do not allow an incorrect rotation to be set
  333. throw new IllegalArgumentException("The rotation must be between -90 and 90 degrees, or 0xff");
  334. }
  335. _format.setRotation(rotation);
  336. }
  337. /**
  338. * get the degree of rotation for the text in the cell
  339. * @return rotation degrees (between -90 and 90 degrees, or 0xff for vertical)
  340. */
  341. @Override
  342. public short getRotation()
  343. {
  344. short rotation = _format.getRotation();
  345. if (rotation == 0xff) {
  346. // Vertical aligned special case
  347. return rotation;
  348. }
  349. if (rotation > 90) {
  350. //This is actually the 4th quadrant
  351. rotation = (short)(90-rotation);
  352. }
  353. return rotation;
  354. }
  355. /**
  356. * set the number of spaces to indent the text in the cell
  357. * @param indent - number of spaces
  358. */
  359. @Override
  360. public void setIndention(short indent)
  361. {
  362. _format.setIndent(indent);
  363. }
  364. /**
  365. * get the number of spaces to indent the text in the cell
  366. * @return indent - number of spaces
  367. */
  368. @Override
  369. public short getIndention()
  370. {
  371. return _format.getIndent();
  372. }
  373. /**
  374. * set the type of border to use for the left border of the cell
  375. * @param border type
  376. * @since POI 3.15
  377. */
  378. @Override
  379. public void setBorderLeft(BorderStyle border)
  380. {
  381. _format.setIndentNotParentBorder(true);
  382. _format.setBorderLeft(border.getCode());
  383. }
  384. @Override
  385. public BorderStyle getBorderLeft()
  386. {
  387. return BorderStyle.valueOf(_format.getBorderLeft());
  388. }
  389. /**
  390. * set the type of border to use for the right border of the cell
  391. * @param border type
  392. * @since POI 3.15
  393. */
  394. @Override
  395. public void setBorderRight(BorderStyle border)
  396. {
  397. _format.setIndentNotParentBorder(true);
  398. _format.setBorderRight(border.getCode());
  399. }
  400. @Override
  401. public BorderStyle getBorderRight()
  402. {
  403. return BorderStyle.valueOf(_format.getBorderRight());
  404. }
  405. /**
  406. * set the type of border to use for the top border of the cell
  407. * @param border type
  408. * @since POI 3.15
  409. */
  410. @Override
  411. public void setBorderTop(BorderStyle border)
  412. {
  413. _format.setIndentNotParentBorder(true);
  414. _format.setBorderTop(border.getCode());
  415. }
  416. @Override
  417. public BorderStyle getBorderTop()
  418. {
  419. return BorderStyle.valueOf(_format.getBorderTop());
  420. }
  421. /**
  422. * set the type of border to use for the bottom border of the cell
  423. * @param border type
  424. * @since 3.15 beta 2
  425. */
  426. @Override
  427. public void setBorderBottom(BorderStyle border)
  428. {
  429. _format.setIndentNotParentBorder(true);
  430. _format.setBorderBottom(border.getCode());
  431. }
  432. @Override
  433. public BorderStyle getBorderBottom()
  434. {
  435. return BorderStyle.valueOf(_format.getBorderBottom());
  436. }
  437. /**
  438. * set the color to use for the left border
  439. * @param color The index of the color definition
  440. */
  441. @Override
  442. public void setLeftBorderColor(short color)
  443. {
  444. _format.setLeftBorderPaletteIdx(color);
  445. }
  446. /**
  447. * get the color to use for the left border
  448. * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
  449. * @return The index of the color definition
  450. */
  451. @Override
  452. public short getLeftBorderColor()
  453. {
  454. return _format.getLeftBorderPaletteIdx();
  455. }
  456. /**
  457. * set the color to use for the right border
  458. * @param color The index of the color definition
  459. */
  460. @Override
  461. public void setRightBorderColor(short color)
  462. {
  463. _format.setRightBorderPaletteIdx(color);
  464. }
  465. /**
  466. * get the color to use for the left border
  467. * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
  468. * @return The index of the color definition
  469. */
  470. @Override
  471. public short getRightBorderColor()
  472. {
  473. return _format.getRightBorderPaletteIdx();
  474. }
  475. /**
  476. * set the color to use for the top border
  477. * @param color The index of the color definition
  478. */
  479. @Override
  480. public void setTopBorderColor(short color)
  481. {
  482. _format.setTopBorderPaletteIdx(color);
  483. }
  484. /**
  485. * get the color to use for the top border
  486. * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
  487. * @return The index of the color definition
  488. */
  489. @Override
  490. public short getTopBorderColor()
  491. {
  492. return _format.getTopBorderPaletteIdx();
  493. }
  494. /**
  495. * set the color to use for the bottom border
  496. * @param color The index of the color definition
  497. */
  498. @Override
  499. public void setBottomBorderColor(short color)
  500. {
  501. _format.setBottomBorderPaletteIdx(color);
  502. }
  503. /**
  504. * get the color to use for the left border
  505. * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
  506. * @return The index of the color definition
  507. */
  508. @Override
  509. public short getBottomBorderColor()
  510. {
  511. return _format.getBottomBorderPaletteIdx();
  512. }
  513. /**
  514. * setting to one fills the cell with the foreground color... No idea about
  515. * other values
  516. *
  517. * @param fp fill pattern (set to {@link FillPatternType#SOLID_FOREGROUND} to fill w/foreground color)
  518. */
  519. @Override
  520. public void setFillPattern(FillPatternType fp)
  521. {
  522. _format.setAdtlFillPattern(fp.getCode());
  523. }
  524. @Override
  525. public FillPatternType getFillPattern()
  526. {
  527. return FillPatternType.forInt(_format.getAdtlFillPattern());
  528. }
  529. /**
  530. * Checks if the background and foreground fills are set correctly when one
  531. * or the other is set to the default color.
  532. * <p>Works like the logic table below:</p>
  533. * <p>BACKGROUND FOREGROUND</p>
  534. * <p>NONE AUTOMATIC</p>
  535. * <p>0x41 0x40</p>
  536. * <p>NONE RED/ANYTHING</p>
  537. * <p>0x40 0xSOMETHING</p>
  538. */
  539. private void checkDefaultBackgroundFills() {
  540. final short autoIdx = HSSFColorPredefined.AUTOMATIC.getIndex();
  541. if (_format.getFillForeground() == autoIdx) {
  542. //JMH: Why +1, hell why not. I guess it made some sense to someone at the time. Doesnt
  543. //to me now.... But experience has shown that when the fore is set to AUTOMATIC then the
  544. //background needs to be incremented......
  545. if (_format.getFillBackground() != autoIdx+1) {
  546. setFillBackgroundColor((short)(autoIdx+1));
  547. }
  548. } else if (_format.getFillBackground() == autoIdx+1) {
  549. //Now if the forground changes to a non-AUTOMATIC color the background resets itself!!!
  550. if (_format.getFillForeground() != autoIdx) {
  551. setFillBackgroundColor(autoIdx);
  552. }
  553. }
  554. }
  555. /**
  556. * set the background fill color.
  557. * <p>
  558. * For example:
  559. * <pre>
  560. * cs.setFillPattern(HSSFCellStyle.FINE_DOTS );
  561. * cs.setFillBackgroundColor(new HSSFColor.RED().getIndex());
  562. * </pre>
  563. * optionally a Foreground and background fill can be applied:
  564. * <i>Note: Ensure Foreground color is set prior to background</i>
  565. * <pre>
  566. * cs.setFillPattern(HSSFCellStyle.FINE_DOTS );
  567. * cs.setFillForegroundColor(new HSSFColor.BLUE().getIndex());
  568. * cs.setFillBackgroundColor(new HSSFColor.RED().getIndex());
  569. * </pre>
  570. * or, for the special case of SOLID_FILL:
  571. * <pre>
  572. * cs.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND );
  573. * cs.setFillForegroundColor(new HSSFColor.RED().getIndex());
  574. * </pre>
  575. * It is necessary to set the fill style in order
  576. * for the color to be shown in the cell.
  577. *
  578. * @param bg color
  579. */
  580. @Override
  581. public void setFillBackgroundColor(short bg)
  582. {
  583. _format.setFillBackground(bg);
  584. checkDefaultBackgroundFills();
  585. }
  586. /**
  587. * Set the background fill color represented as a {@link org.apache.poi.ss.usermodel.Color} value.
  588. * <br>
  589. * @param color the color to use
  590. * @throws IllegalArgumentException if you provide a <code>Color</code> instance that is not a {@link HSSFColor}
  591. * @since POI 5.2.3
  592. */
  593. @Override
  594. public void setFillBackgroundColor(org.apache.poi.ss.usermodel.Color color)
  595. {
  596. if (color instanceof HSSFColor) {
  597. final short index = ((HSSFColor)color).getIndex();
  598. if (index != -1) setFillBackgroundColor(index);
  599. } else if (color != null) {
  600. throw new IllegalArgumentException("HSSFCellStyle only accepts HSSFColor instances");
  601. }
  602. }
  603. /**
  604. * Get the background fill color.
  605. * Note - many cells are actually filled with a foreground
  606. * fill, not a background fill - see {@link #getFillForegroundColor()}
  607. * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
  608. * @return fill color
  609. */
  610. @Override
  611. public short getFillBackgroundColor() {
  612. final short autoIndex = HSSFColorPredefined.AUTOMATIC.getIndex();
  613. short result = _format.getFillBackground();
  614. //JMH: Do this ridiculous conversion, and let HSSFCellStyle
  615. //internally migrate back and forth
  616. if (result == autoIndex+1) {
  617. return autoIndex;
  618. }
  619. return result;
  620. }
  621. @Override
  622. public HSSFColor getFillBackgroundColorColor() {
  623. HSSFPalette pallette = new HSSFPalette(
  624. _workbook.getCustomPalette()
  625. );
  626. return pallette.getColor(
  627. getFillBackgroundColor()
  628. );
  629. }
  630. /**
  631. * set the foreground fill color
  632. * <i>Note: Ensure Foreground color is set prior to background color.</i>
  633. * @param bg color
  634. */
  635. @Override
  636. public void setFillForegroundColor(short bg)
  637. {
  638. _format.setFillForeground(bg);
  639. checkDefaultBackgroundFills();
  640. }
  641. /**
  642. * Set the foreground fill color represented as a {@link org.apache.poi.ss.usermodel.Color} value.
  643. * <br>
  644. * @param color the color to use
  645. * @throws IllegalArgumentException if you provide a <code>Color</code> instance that is not a {@link HSSFColor}
  646. * @since POI 5.2.3
  647. */
  648. @Override
  649. public void setFillForegroundColor(org.apache.poi.ss.usermodel.Color color)
  650. {
  651. if (color instanceof HSSFColor) {
  652. final short index = ((HSSFColor)color).getIndex();
  653. if (index != -1) setFillForegroundColor(index);
  654. } else if (color != null) {
  655. throw new IllegalArgumentException("HSSFCellStyle only accepts HSSFColor instances");
  656. }
  657. }
  658. /**
  659. * Get the foreground fill color.
  660. * Many cells are filled with this, instead of a
  661. * background color ({@link #getFillBackgroundColor()})
  662. * @see org.apache.poi.hssf.usermodel.HSSFPalette#getColor(short)
  663. * @return fill color
  664. */
  665. @Override
  666. public short getFillForegroundColor()
  667. {
  668. return _format.getFillForeground();
  669. }
  670. @Override
  671. public HSSFColor getFillForegroundColorColor() {
  672. HSSFPalette pallette = new HSSFPalette(
  673. _workbook.getCustomPalette()
  674. );
  675. return pallette.getColor(
  676. getFillForegroundColor()
  677. );
  678. }
  679. /**
  680. * Gets the name of the user defined style.
  681. * Returns null for built in styles, and
  682. * styles where no name has been defined
  683. */
  684. public String getUserStyleName() {
  685. StyleRecord sr = _workbook.getStyleRecord(_index);
  686. if(sr == null) {
  687. return null;
  688. }
  689. if(sr.isBuiltin()) {
  690. return null;
  691. }
  692. return sr.getName();
  693. }
  694. /**
  695. * Sets the name of the user defined style.
  696. * Will complain if you try this on a built in style.
  697. */
  698. public void setUserStyleName(String styleName) {
  699. StyleRecord sr = _workbook.getStyleRecord(_index);
  700. if(sr == null) {
  701. sr = _workbook.createStyleRecord(_index);
  702. }
  703. // All Style records start as "builtin", but generally
  704. // only 20 and below really need to be
  705. if(sr.isBuiltin() && _index <= 20) {
  706. throw new IllegalArgumentException("Unable to set user specified style names for built in styles!");
  707. }
  708. sr.setName(styleName);
  709. }
  710. /**
  711. * Controls if the Cell should be auto-sized
  712. * to shrink to fit if the text is too long
  713. */
  714. @Override
  715. public void setShrinkToFit(boolean shrinkToFit) {
  716. _format.setShrinkToFit(shrinkToFit);
  717. }
  718. /**
  719. * Should the Cell be auto-sized by Excel to shrink
  720. * it to fit if this text is too long?
  721. */
  722. @Override
  723. public boolean getShrinkToFit() {
  724. return _format.getShrinkToFit();
  725. }
  726. /**
  727. * Get the reading order, for RTL/LTR ordering of
  728. * the text.
  729. * <p>0 means Context (Default), 1 means Left To Right,
  730. * and 2 means Right to Left</p>
  731. *
  732. * @return order - the reading order (0,1,2)
  733. */
  734. public short getReadingOrder() {
  735. return _format.getReadingOrder();
  736. }
  737. /**
  738. * Sets the reading order, for RTL/LTR ordering of
  739. * the text.
  740. * <p>0 means Context (Default), 1 means Left To Right,
  741. * and 2 means Right to Left</p>
  742. *
  743. * @param order - the reading order (0,1,2)
  744. */
  745. public void setReadingOrder(short order) {
  746. _format.setReadingOrder(order);
  747. }
  748. /**
  749. * Verifies that this style belongs to the supplied Workbook.
  750. * Will throw an exception if it belongs to a different one.
  751. * This is normally called when trying to assign a style to a
  752. * cell, to ensure the cell and the style are from the same
  753. * workbook (if they're not, it won't work)
  754. * @throws IllegalArgumentException if there's a workbook mis-match
  755. */
  756. public void verifyBelongsToWorkbook(HSSFWorkbook wb) {
  757. if(wb.getWorkbook() != _workbook) {
  758. throw new IllegalArgumentException("This Style does not belong to the supplied Workbook. Are you trying to assign a style from one workbook to the cell of a differnt workbook?");
  759. }
  760. }
  761. /**
  762. * Clones all the style information from another
  763. * HSSFCellStyle, onto this one. This
  764. * HSSFCellStyle will then have all the same
  765. * properties as the source, but the two may
  766. * be edited independently.
  767. * Any stylings on this HSSFCellStyle will be lost!
  768. *
  769. * The source HSSFCellStyle could be from another
  770. * HSSFWorkbook if you like. This allows you to
  771. * copy styles from one HSSFWorkbook to another.
  772. */
  773. @Override
  774. public void cloneStyleFrom(CellStyle source) {
  775. if(source instanceof HSSFCellStyle) {
  776. this.cloneStyleFrom((HSSFCellStyle)source);
  777. } else {
  778. throw new IllegalArgumentException("Can only clone from one HSSFCellStyle to another, not between HSSFCellStyle and XSSFCellStyle");
  779. }
  780. }
  781. public void cloneStyleFrom(HSSFCellStyle source) {
  782. // First we need to clone the extended format
  783. // record
  784. _format.cloneStyleFrom(source._format);
  785. // Handle matching things if we cross workbooks
  786. if(_workbook != source._workbook) {
  787. lastDateFormat.set(Short.MIN_VALUE);
  788. lastFormats.remove();
  789. getDataFormatStringCache.remove();
  790. // Then we need to clone the format string,
  791. // and update the format record for this
  792. short fmt = (short)_workbook.createFormat(source.getDataFormatString() );
  793. setDataFormat(fmt);
  794. // Finally we need to clone the font,
  795. // and update the format record for this
  796. FontRecord fr = _workbook.createNewFont();
  797. fr.cloneStyleFrom(
  798. source._workbook.getFontRecordAt(
  799. source.getFontIndex()
  800. )
  801. );
  802. HSSFFont font = new HSSFFont(
  803. (short)_workbook.getFontIndex(fr), fr
  804. );
  805. setFont(font);
  806. }
  807. }
  808. @Override
  809. public int hashCode() {
  810. return Objects.hash(_format, _index);
  811. }
  812. @Override
  813. public boolean equals(Object obj) {
  814. if (this == obj) {
  815. return true;
  816. }
  817. if (obj == null) {
  818. return false;
  819. }
  820. if (obj instanceof HSSFCellStyle) {
  821. final HSSFCellStyle other = (HSSFCellStyle) obj;
  822. if (_format == null) {
  823. if (other._format != null) {
  824. return false;
  825. }
  826. } else if (!_format.equals(other._format)) {
  827. return false;
  828. }
  829. if (_index != other._index) {
  830. return false;
  831. }
  832. return true;
  833. }
  834. return false;
  835. }
  836. @Override
  837. public HSSFCellStyle copy() {
  838. return new HSSFCellStyle(this);
  839. }
  840. }