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.

SXSSFCell.java 39KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306
  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.xssf.streaming;
  16. import java.text.DateFormat;
  17. import java.text.SimpleDateFormat;
  18. import java.util.Calendar;
  19. import java.util.Date;
  20. import java.util.Map;
  21. import org.apache.poi.ss.SpreadsheetVersion;
  22. import org.apache.poi.ss.formula.FormulaParseException;
  23. import org.apache.poi.ss.formula.eval.ErrorEval;
  24. import org.apache.poi.ss.usermodel.Cell;
  25. import org.apache.poi.ss.usermodel.CellBase;
  26. import org.apache.poi.ss.usermodel.CellStyle;
  27. import org.apache.poi.ss.usermodel.CellType;
  28. import org.apache.poi.ss.usermodel.Comment;
  29. import org.apache.poi.ss.usermodel.DateUtil;
  30. import org.apache.poi.ss.usermodel.FormulaError;
  31. import org.apache.poi.ss.usermodel.Hyperlink;
  32. import org.apache.poi.ss.usermodel.RichTextString;
  33. import org.apache.poi.ss.usermodel.Row;
  34. import org.apache.poi.ss.util.CellRangeAddress;
  35. import org.apache.poi.ss.util.CellReference;
  36. import org.apache.poi.util.*;
  37. import org.apache.poi.xssf.usermodel.XSSFHyperlink;
  38. import org.apache.poi.xssf.usermodel.XSSFRichTextString;
  39. /**
  40. * Streaming version of XSSFCell implementing the "BigGridDemo" strategy.
  41. */
  42. public class SXSSFCell extends CellBase {
  43. private final SXSSFRow _row;
  44. private Value _value;
  45. private CellStyle _style;
  46. private Property _firstProperty;
  47. public SXSSFCell(SXSSFRow row, CellType cellType)
  48. {
  49. _row=row;
  50. _value = new BlankValue();
  51. setType(cellType);
  52. }
  53. //start of interface implementation
  54. /**
  55. * Returns column index of this cell
  56. *
  57. * @return zero-based column index of a column in a sheet.
  58. */
  59. @Override
  60. public int getColumnIndex()
  61. {
  62. return _row.getCellIndex(this);
  63. }
  64. /**
  65. * Returns row index of a row in the sheet that contains this cell
  66. *
  67. * @return zero-based row index of a row in the sheet that contains this cell
  68. */
  69. @Override
  70. public int getRowIndex()
  71. {
  72. return _row.getRowNum();
  73. }
  74. /**
  75. * Returns the sheet this cell belongs to
  76. *
  77. * @return the sheet this cell belongs to
  78. */
  79. @Override
  80. public SXSSFSheet getSheet()
  81. {
  82. return _row.getSheet();
  83. }
  84. /**
  85. * Returns the Row this cell belongs to
  86. *
  87. * @return the Row that owns this cell
  88. */
  89. @Override
  90. public Row getRow()
  91. {
  92. return _row;
  93. }
  94. @Override
  95. protected void setCellTypeImpl(CellType cellType) {
  96. ensureType(cellType);
  97. }
  98. private boolean isFormulaCell() {
  99. return _value instanceof FormulaValue;
  100. }
  101. /**
  102. * Return the cell type.
  103. *
  104. * @return the cell type
  105. */
  106. @Override
  107. public CellType getCellType() {
  108. if (isFormulaCell()) {
  109. return CellType.FORMULA;
  110. }
  111. return _value.getType();
  112. }
  113. /**
  114. * Only valid for formula cells
  115. * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING},
  116. * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending
  117. * on the cached value of the formula
  118. */
  119. @Override
  120. public CellType getCachedFormulaResultType() {
  121. if (!isFormulaCell()) {
  122. throw new IllegalStateException("Only formula cells have cached results");
  123. }
  124. return ((FormulaValue)_value).getFormulaType();
  125. }
  126. /**
  127. * Only valid for formula cells
  128. * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING},
  129. * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending
  130. * on the cached value of the formula
  131. * @since POI 3.15 beta 3
  132. * @deprecated use <code>getCachedFormulaResultType</code> instead
  133. */
  134. @Deprecated
  135. @Removal(version = "4.2")
  136. @Override
  137. public CellType getCachedFormulaResultTypeEnum() {
  138. return getCachedFormulaResultType();
  139. }
  140. /**
  141. * {@inheritDoc}
  142. */
  143. @Override
  144. public void setCellValueImpl(double value) {
  145. ensureTypeOrFormulaType(CellType.NUMERIC);
  146. if(_value.getType() == CellType.FORMULA) {
  147. ((NumericFormulaValue) _value).setPreEvaluatedValue(value);
  148. } else {
  149. ((NumericValue)_value).setValue(value);
  150. }
  151. }
  152. /**
  153. * {@inheritDoc}
  154. */
  155. @Override
  156. protected void setCellValueImpl(Date value) {
  157. boolean date1904 = getSheet().getWorkbook().isDate1904();
  158. setCellValue(DateUtil.getExcelDate(value, date1904));
  159. }
  160. /**
  161. * {@inheritDoc}
  162. */
  163. @Override
  164. protected void setCellValueImpl(Calendar value) {
  165. boolean date1904 = getSheet().getWorkbook().isDate1904();
  166. setCellValue( DateUtil.getExcelDate(value, date1904 ));
  167. }
  168. /**
  169. * Set a rich string value for the cell.
  170. *
  171. * @param value value to set the cell to. For formulas: we'll set the formula
  172. * string, for String cells: we'll set its value. For other types we will
  173. * change the cell to a string cell and set its value.
  174. * If value is null then we will change the cell to a Blank cell.
  175. */
  176. @Override
  177. public void setCellValue(RichTextString value)
  178. {
  179. if (value != null && value.getString() != null) {
  180. if (value.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()) {
  181. throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters");
  182. }
  183. ensureRichTextStringType();
  184. if(_value instanceof RichTextStringFormulaValue) {
  185. ((RichTextStringFormulaValue) _value).setPreEvaluatedValue(value);
  186. } else {
  187. ((RichTextValue) _value).setValue(value);
  188. }
  189. } else {
  190. setBlank();
  191. }
  192. }
  193. /**
  194. * Set a string value for the cell.
  195. *
  196. * @param value value to set the cell to. For formulas we'll set the formula
  197. * string, for String cells we'll set its value. For other types we will
  198. * change the cell to a string cell and set its value.
  199. * If value is null then we will change the cell to a Blank cell.
  200. */
  201. @Override
  202. public void setCellValue(String value)
  203. {
  204. if (value != null) {
  205. if (value.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()) {
  206. throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters");
  207. }
  208. ensureTypeOrFormulaType(CellType.STRING);
  209. if(_value.getType() == CellType.FORMULA) {
  210. ((StringFormulaValue) _value).setPreEvaluatedValue(value);
  211. } else {
  212. ((PlainStringValue) _value).setValue(value);
  213. }
  214. } else {
  215. setBlank();
  216. }
  217. }
  218. /**
  219. * Sets formula for this cell.
  220. * <p>
  221. * Note, this method only sets the formula string and does not calculate the formula value.
  222. * To set the precalculated value use {@link #setCellValue(double)} or {@link #setCellValue(String)}
  223. * </p>
  224. *
  225. * @param formula the formula to set, e.g. <code>"SUM(C4:E4)"</code>.
  226. * If the argument is <code>null</code> then the current formula is removed.
  227. * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
  228. */
  229. @Override
  230. public void setCellFormulaImpl(String formula) throws FormulaParseException {
  231. assert formula != null;
  232. if (getCellType() == CellType.FORMULA) {
  233. ((FormulaValue)_value).setValue(formula);
  234. } else {
  235. switch (getCellType()) {
  236. case NUMERIC:
  237. _value = new NumericFormulaValue(formula, getNumericCellValue());
  238. break;
  239. case STRING:
  240. if (_value instanceof PlainStringValue) {
  241. _value = new StringFormulaValue(formula, getStringCellValue());
  242. } else {
  243. assert(_value instanceof RichTextValue);
  244. _value = new RichTextStringFormulaValue(formula, ((RichTextValue) _value).getValue());
  245. }
  246. break;
  247. case BOOLEAN:
  248. _value = new BooleanFormulaValue(formula, getBooleanCellValue());
  249. break;
  250. case ERROR:
  251. _value = new ErrorFormulaValue(formula, getErrorCellValue());
  252. break;
  253. case _NONE:
  254. // fall-through
  255. case FORMULA:
  256. // fall-through
  257. case BLANK:
  258. throw new AssertionError();
  259. }
  260. }
  261. }
  262. @Override
  263. protected void removeFormulaImpl() {
  264. assert getCellType() == CellType.FORMULA;
  265. switch (getCachedFormulaResultType()) {
  266. case NUMERIC:
  267. double numericValue = ((NumericFormulaValue)_value).getPreEvaluatedValue();
  268. _value = new NumericValue();
  269. ((NumericValue) _value).setValue(numericValue);
  270. break;
  271. case STRING:
  272. String stringValue = ((StringFormulaValue)_value).getPreEvaluatedValue();
  273. _value = new PlainStringValue();
  274. ((PlainStringValue) _value).setValue(stringValue);
  275. break;
  276. case BOOLEAN:
  277. boolean booleanValue = ((BooleanFormulaValue)_value).getPreEvaluatedValue();
  278. _value = new BooleanValue();
  279. ((BooleanValue) _value).setValue(booleanValue);
  280. break;
  281. case ERROR:
  282. byte errorValue = ((ErrorFormulaValue)_value).getPreEvaluatedValue();
  283. _value = new ErrorValue();
  284. ((ErrorValue) _value).setValue(errorValue);
  285. break;
  286. default:
  287. throw new AssertionError();
  288. }
  289. }
  290. /**
  291. * Return a formula for the cell, for example, <code>SUM(C4:E4)</code>
  292. *
  293. * @return a formula for the cell
  294. * @throws IllegalStateException if the cell type returned by {@link #getCellType()} is not CellType.FORMULA
  295. */
  296. @Override
  297. public String getCellFormula()
  298. {
  299. if(_value.getType()!=CellType.FORMULA)
  300. throw typeMismatch(CellType.FORMULA,_value.getType(),false);
  301. return ((FormulaValue)_value).getValue();
  302. }
  303. /**
  304. * Get the value of the cell as a number.
  305. * <p>
  306. * For strings we throw an exception. For blank cells we return a 0.
  307. * For formulas or error cells we return the precalculated value;
  308. * </p>
  309. * @return the value of the cell as a number
  310. * @throws IllegalStateException if the cell type returned by {@link #getCellType()} is CellType.STRING
  311. * @exception NumberFormatException if the cell value isn't a parsable <code>double</code>.
  312. * @see org.apache.poi.ss.usermodel.DataFormatter for turning this number into a string similar to that which Excel would render this number as.
  313. */
  314. @Override
  315. public double getNumericCellValue()
  316. {
  317. CellType cellType = getCellType();
  318. switch(cellType)
  319. {
  320. case BLANK:
  321. return 0.0;
  322. case FORMULA:
  323. {
  324. FormulaValue fv=(FormulaValue)_value;
  325. if(fv.getFormulaType()!=CellType.NUMERIC)
  326. throw typeMismatch(CellType.NUMERIC, CellType.FORMULA, false);
  327. return ((NumericFormulaValue)_value).getPreEvaluatedValue();
  328. }
  329. case NUMERIC:
  330. return ((NumericValue)_value).getValue();
  331. default:
  332. throw typeMismatch(CellType.NUMERIC, cellType, false);
  333. }
  334. }
  335. /**
  336. * Get the value of the cell as a date.
  337. * <p>
  338. * For strings we throw an exception. For blank cells we return a null.
  339. * </p>
  340. * @return the value of the cell as a date
  341. * @throws IllegalStateException if the cell type returned by {@link #getCellType()} is CellType.STRING
  342. * @exception NumberFormatException if the cell value isn't a parsable <code>double</code>.
  343. * @see org.apache.poi.ss.usermodel.DataFormatter for formatting this date into a string similar to how excel does.
  344. */
  345. @Override
  346. public Date getDateCellValue()
  347. {
  348. CellType cellType = getCellType();
  349. if (cellType == CellType.BLANK)
  350. {
  351. return null;
  352. }
  353. double value = getNumericCellValue();
  354. boolean date1904 = getSheet().getWorkbook().isDate1904();
  355. return DateUtil.getJavaDate(value, date1904);
  356. }
  357. /**
  358. * Get the value of the cell as a XSSFRichTextString
  359. * <p>
  360. * For numeric cells we throw an exception. For blank cells we return an empty string.
  361. * For formula cells we return the pre-calculated value if a string, otherwise an exception.
  362. * </p>
  363. * @return the value of the cell as a XSSFRichTextString
  364. */
  365. @Override
  366. public RichTextString getRichStringCellValue()
  367. {
  368. CellType cellType = getCellType();
  369. if(getCellType() != CellType.STRING)
  370. throw typeMismatch(CellType.STRING, cellType, false);
  371. StringValue sval = (StringValue)_value;
  372. if(sval.isRichText())
  373. return ((RichTextValue)_value).getValue();
  374. else {
  375. String plainText = getStringCellValue();
  376. return getSheet().getWorkbook().getCreationHelper().createRichTextString(plainText);
  377. }
  378. }
  379. /**
  380. * Get the value of the cell as a string
  381. * <p>
  382. * For numeric cells we throw an exception. For blank cells we return an empty string.
  383. * For formulaCells that are not string Formulas, we throw an exception.
  384. * </p>
  385. * @return the value of the cell as a string
  386. */
  387. @Override
  388. public String getStringCellValue()
  389. {
  390. CellType cellType = getCellType();
  391. switch(cellType)
  392. {
  393. case BLANK:
  394. return "";
  395. case FORMULA:
  396. {
  397. FormulaValue fv=(FormulaValue)_value;
  398. if(fv.getFormulaType()!=CellType.STRING)
  399. throw typeMismatch(CellType.STRING, CellType.FORMULA, false);
  400. if(_value instanceof RichTextStringFormulaValue) {
  401. return ((RichTextStringFormulaValue) _value).getPreEvaluatedValue().getString();
  402. } else {
  403. return ((StringFormulaValue) _value).getPreEvaluatedValue();
  404. }
  405. }
  406. case STRING:
  407. {
  408. if(((StringValue)_value).isRichText())
  409. return ((RichTextValue)_value).getValue().getString();
  410. else
  411. return ((PlainStringValue)_value).getValue();
  412. }
  413. default:
  414. throw typeMismatch(CellType.STRING, cellType, false);
  415. }
  416. }
  417. /**
  418. * Set a boolean value for the cell
  419. *
  420. * @param value the boolean value to set this cell to. For formulas we'll set the
  421. * precalculated value, for booleans we'll set its value. For other types we
  422. * will change the cell to a boolean cell and set its value.
  423. */
  424. @Override
  425. public void setCellValue(boolean value)
  426. {
  427. ensureTypeOrFormulaType(CellType.BOOLEAN);
  428. if(_value.getType()==CellType.FORMULA)
  429. ((BooleanFormulaValue)_value).setPreEvaluatedValue(value);
  430. else
  431. ((BooleanValue)_value).setValue(value);
  432. }
  433. /**
  434. * Set a error value for the cell
  435. *
  436. * @param value the error value to set this cell to. For formulas we'll set the
  437. * precalculated value , for errors we'll set
  438. * its value. For other types we will change the cell to an error
  439. * cell and set its value.
  440. * @see org.apache.poi.ss.usermodel.FormulaError
  441. */
  442. @Override
  443. public void setCellErrorValue(byte value) {
  444. // for formulas, we want to keep the type and only have an ERROR as formula value
  445. if(_value.getType()==CellType.FORMULA) {
  446. _value = new ErrorFormulaValue(getCellFormula(), value);
  447. } else {
  448. _value = new ErrorValue(value);
  449. }
  450. }
  451. /**
  452. * Get the value of the cell as a boolean.
  453. * <p>
  454. * For strings, numbers, and errors, we throw an exception. For blank cells we return a false.
  455. * </p>
  456. * @return the value of the cell as a boolean
  457. * @throws IllegalStateException if the cell type returned by {@link #getCellType()}
  458. * is not CellType.BOOLEAN, CellType.BLANK or CellType.FORMULA
  459. */
  460. @Override
  461. public boolean getBooleanCellValue()
  462. {
  463. CellType cellType = getCellType();
  464. switch(cellType)
  465. {
  466. case BLANK:
  467. return false;
  468. case FORMULA:
  469. {
  470. FormulaValue fv=(FormulaValue)_value;
  471. if(fv.getFormulaType()!=CellType.BOOLEAN)
  472. throw typeMismatch(CellType.BOOLEAN, CellType.FORMULA, false);
  473. return ((BooleanFormulaValue)_value).getPreEvaluatedValue();
  474. }
  475. case BOOLEAN:
  476. {
  477. return ((BooleanValue)_value).getValue();
  478. }
  479. default:
  480. throw typeMismatch(CellType.BOOLEAN, cellType, false);
  481. }
  482. }
  483. /**
  484. * Get the value of the cell as an error code.
  485. * <p>
  486. * For strings, numbers, and booleans, we throw an exception.
  487. * For blank cells we return a 0.
  488. * </p>
  489. *
  490. * @return the value of the cell as an error code
  491. * @throws IllegalStateException if the cell type returned by {@link #getCellType()} isn't CellType.ERROR
  492. * @see org.apache.poi.ss.usermodel.FormulaError for error codes
  493. */
  494. @Override
  495. public byte getErrorCellValue()
  496. {
  497. CellType cellType = getCellType();
  498. switch(cellType)
  499. {
  500. case BLANK:
  501. return 0;
  502. case FORMULA:
  503. {
  504. FormulaValue fv=(FormulaValue)_value;
  505. if(fv.getFormulaType()!=CellType.ERROR)
  506. throw typeMismatch(CellType.ERROR, CellType.FORMULA, false);
  507. return ((ErrorFormulaValue)_value).getPreEvaluatedValue();
  508. }
  509. case ERROR:
  510. {
  511. return ((ErrorValue)_value).getValue();
  512. }
  513. default:
  514. throw typeMismatch(CellType.ERROR, cellType, false);
  515. }
  516. }
  517. /**
  518. * <p>Set the style for the cell. The style should be an CellStyle created/retreived from
  519. * the Workbook.</p>
  520. *
  521. * <p>To change the style of a cell without affecting other cells that use the same style,
  522. * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, Map)}</p>
  523. *
  524. * @param style reference contained in the workbook.
  525. * If the value is null then the style information is removed causing the cell to used the default workbook style.
  526. * @see org.apache.poi.ss.usermodel.Workbook#createCellStyle
  527. */
  528. @Override
  529. public void setCellStyle(CellStyle style)
  530. {
  531. _style=style;
  532. }
  533. /**
  534. * Return the cell's style.
  535. *
  536. * @return the cell's style. Always not-null. Default cell style has zero index and can be obtained as
  537. * <code>workbook.getCellStyleAt(0)</code>
  538. * @see org.apache.poi.ss.usermodel.Workbook#getCellStyleAt(int)
  539. */
  540. @Override
  541. public CellStyle getCellStyle()
  542. {
  543. if(_style == null){
  544. SXSSFWorkbook wb = (SXSSFWorkbook)getRow().getSheet().getWorkbook();
  545. return wb.getCellStyleAt(0);
  546. } else {
  547. return _style;
  548. }
  549. }
  550. /**
  551. * {@inheritDoc}
  552. */
  553. @Override
  554. public void setAsActiveCell()
  555. {
  556. getSheet().setActiveCell(getAddress());
  557. }
  558. /**
  559. * Assign a comment to this cell
  560. *
  561. * @param comment comment associated with this cell
  562. */
  563. @Override
  564. public void setCellComment(Comment comment)
  565. {
  566. setProperty(Property.COMMENT,comment);
  567. }
  568. /**
  569. * Returns comment associated with this cell
  570. *
  571. * @return comment associated with this cell or <code>null</code> if not found
  572. */
  573. @Override
  574. public Comment getCellComment()
  575. {
  576. return (Comment)getPropertyValue(Property.COMMENT);
  577. }
  578. /**
  579. * Removes the comment for this cell, if there is one.
  580. */
  581. @Override
  582. public void removeCellComment()
  583. {
  584. removeProperty(Property.COMMENT);
  585. }
  586. /**
  587. * @return hyperlink associated with this cell or <code>null</code> if not found
  588. */
  589. @Override
  590. public Hyperlink getHyperlink()
  591. {
  592. return (Hyperlink)getPropertyValue(Property.HYPERLINK);
  593. }
  594. /**
  595. * Assign a hyperlink to this cell. If the supplied hyperlink is null, the
  596. * hyperlink for this cell will be removed.
  597. *
  598. * @param link hyperlink associated with this cell
  599. */
  600. @Override
  601. public void setHyperlink(Hyperlink link)
  602. {
  603. if (link == null) {
  604. removeHyperlink();
  605. return;
  606. }
  607. setProperty(Property.HYPERLINK,link);
  608. XSSFHyperlink xssfobj = (XSSFHyperlink)link;
  609. // Assign to us
  610. CellReference ref = new CellReference(getRowIndex(), getColumnIndex());
  611. xssfobj.setCellReference( ref );
  612. // Add to the lists
  613. getSheet()._sh.addHyperlink(xssfobj);
  614. }
  615. /**
  616. * Removes the hyperlink for this cell, if there is one.
  617. */
  618. @Override
  619. public void removeHyperlink()
  620. {
  621. removeProperty(Property.HYPERLINK);
  622. getSheet()._sh.removeHyperlink(getRowIndex(), getColumnIndex());
  623. }
  624. /**
  625. * Only valid for array formula cells
  626. *
  627. * @return range of the array formula group that the cell belongs to.
  628. */
  629. // TODO: What is this?
  630. @NotImplemented
  631. public CellRangeAddress getArrayFormulaRange()
  632. {
  633. return null;
  634. }
  635. /**
  636. * @return <code>true</code> if this cell is part of group of cells having a common array formula.
  637. */
  638. //TODO: What is this?
  639. @NotImplemented
  640. public boolean isPartOfArrayFormulaGroup()
  641. {
  642. return false;
  643. }
  644. //end of interface implementation
  645. /**
  646. * Returns a string representation of the cell
  647. * <p>
  648. * Formula cells return the formula string, rather than the formula result.
  649. * Dates are displayed in dd-MMM-yyyy format
  650. * Errors are displayed as #ERR&lt;errIdx&gt;
  651. * </p>
  652. */
  653. @Override
  654. public String toString() {
  655. switch (getCellType()) {
  656. case BLANK:
  657. return "";
  658. case BOOLEAN:
  659. return getBooleanCellValue() ? "TRUE" : "FALSE";
  660. case ERROR:
  661. return ErrorEval.getText(getErrorCellValue());
  662. case FORMULA:
  663. return getCellFormula();
  664. case NUMERIC:
  665. if (DateUtil.isCellDateFormatted(this)) {
  666. DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", LocaleUtil.getUserLocale());
  667. sdf.setTimeZone(LocaleUtil.getUserTimeZone());
  668. return sdf.format(getDateCellValue());
  669. }
  670. return getNumericCellValue() + "";
  671. case STRING:
  672. return getRichStringCellValue().toString();
  673. default:
  674. return "Unknown Cell Type: " + getCellType();
  675. }
  676. }
  677. /*package*/ void removeProperty(int type)
  678. {
  679. Property current=_firstProperty;
  680. Property previous=null;
  681. while(current!=null&&current.getType()!=type)
  682. {
  683. previous=current;
  684. current=current._next;
  685. }
  686. if(current!=null)
  687. {
  688. if(previous!=null)
  689. {
  690. previous._next=current._next;
  691. }
  692. else
  693. {
  694. _firstProperty=current._next;
  695. }
  696. }
  697. }
  698. /*package*/ void setProperty(int type,Object value)
  699. {
  700. Property current=_firstProperty;
  701. Property previous=null;
  702. while(current!=null&&current.getType()!=type)
  703. {
  704. previous=current;
  705. current=current._next;
  706. }
  707. if(current!=null)
  708. {
  709. current.setValue(value);
  710. }
  711. else
  712. {
  713. switch(type)
  714. {
  715. case Property.COMMENT:
  716. {
  717. current=new CommentProperty(value);
  718. break;
  719. }
  720. case Property.HYPERLINK:
  721. {
  722. current=new HyperlinkProperty(value);
  723. break;
  724. }
  725. default:
  726. {
  727. throw new IllegalArgumentException("Invalid type: " + type);
  728. }
  729. }
  730. if(previous!=null)
  731. {
  732. previous._next=current;
  733. }
  734. else
  735. {
  736. _firstProperty=current;
  737. }
  738. }
  739. }
  740. /*package*/ Object getPropertyValue(int type)
  741. {
  742. return getPropertyValue(type,null);
  743. }
  744. /*package*/ Object getPropertyValue(int type,String defaultValue)
  745. {
  746. Property current=_firstProperty;
  747. while(current!=null&&current.getType()!=type) current=current._next;
  748. return current==null?defaultValue:current.getValue();
  749. }
  750. /*package*/ void ensurePlainStringType()
  751. {
  752. if(_value.getType()!=CellType.STRING
  753. ||((StringValue)_value).isRichText())
  754. _value = new PlainStringValue();
  755. }
  756. /*package*/ void ensureRichTextStringType()
  757. {
  758. // don't change cell type for formulas
  759. if(_value.getType() == CellType.FORMULA) {
  760. String formula = ((FormulaValue)_value).getValue();
  761. _value = new RichTextStringFormulaValue(formula, new XSSFRichTextString(""));
  762. } else if(_value.getType()!=CellType.STRING ||
  763. !((StringValue)_value).isRichText()) {
  764. _value = new RichTextValue();
  765. }
  766. }
  767. /*package*/ void ensureType(CellType type)
  768. {
  769. if(_value.getType()!=type)
  770. setType(type);
  771. }
  772. /*
  773. * Sets the cell type to type if it is different
  774. */
  775. /*package*/ void ensureTypeOrFormulaType(CellType type)
  776. {
  777. if(_value.getType()==type)
  778. {
  779. if(type==CellType.STRING&&((StringValue)_value).isRichText())
  780. setType(CellType.STRING);
  781. return;
  782. }
  783. if(_value.getType()==CellType.FORMULA)
  784. {
  785. if(((FormulaValue)_value).getFormulaType()==type)
  786. return;
  787. switch (type) {
  788. case BOOLEAN:
  789. _value = new BooleanFormulaValue(getCellFormula(), false);
  790. break;
  791. case NUMERIC:
  792. _value = new NumericFormulaValue(getCellFormula(), 0);
  793. break;
  794. case STRING:
  795. _value = new StringFormulaValue(getCellFormula(), "");
  796. break;
  797. case ERROR:
  798. _value = new ErrorFormulaValue(getCellFormula(), FormulaError._NO_ERROR.getCode());
  799. break;
  800. default:
  801. throw new AssertionError();
  802. }
  803. return;
  804. }
  805. setType(type);
  806. }
  807. /**
  808. * changes the cell type to the specified type, and resets the value to the default value for that type
  809. * If cell type is the same as specified type, this will reset the value to the default value for that type
  810. *
  811. * @param type the cell type to set
  812. * @throws IllegalArgumentException if type is not a recognized type
  813. */
  814. /*package*/ void setType(CellType type)
  815. {
  816. switch(type)
  817. {
  818. case NUMERIC:
  819. {
  820. _value = new NumericValue();
  821. break;
  822. }
  823. case STRING:
  824. {
  825. PlainStringValue sval = new PlainStringValue();
  826. if(_value != null){
  827. // if a cell is not blank then convert the old value to string
  828. String str = convertCellValueToString();
  829. sval.setValue(str);
  830. }
  831. _value = sval;
  832. break;
  833. }
  834. case FORMULA:
  835. {
  836. if (getCellType() == CellType.BLANK) {
  837. _value = new NumericFormulaValue("", 0);
  838. }
  839. break;
  840. }
  841. case BLANK:
  842. {
  843. _value = new BlankValue();
  844. break;
  845. }
  846. case BOOLEAN:
  847. {
  848. BooleanValue bval = new BooleanValue();
  849. if(_value != null){
  850. // if a cell is not blank then convert the old value to string
  851. boolean val = convertCellValueToBoolean();
  852. bval.setValue(val);
  853. }
  854. _value = bval;
  855. break;
  856. }
  857. case ERROR:
  858. {
  859. _value = new ErrorValue();
  860. break;
  861. }
  862. default:
  863. {
  864. throw new IllegalArgumentException("Illegal type " + type);
  865. }
  866. }
  867. }
  868. //COPIED FROM https://svn.apache.org/repos/asf/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java since the functions are declared private there
  869. /**
  870. * Used to help format error messages
  871. */
  872. private static RuntimeException typeMismatch(CellType expectedTypeCode, CellType actualTypeCode, boolean isFormulaCell) {
  873. String msg = "Cannot get a " + expectedTypeCode + " value from a " + actualTypeCode
  874. + " " + (isFormulaCell ? "formula " : "") + "cell";
  875. return new IllegalStateException(msg);
  876. }
  877. private boolean convertCellValueToBoolean() {
  878. CellType cellType = getCellType();
  879. if (cellType == CellType.FORMULA) {
  880. cellType = getCachedFormulaResultType();
  881. }
  882. switch (cellType) {
  883. case BOOLEAN:
  884. return getBooleanCellValue();
  885. case STRING:
  886. String text = getStringCellValue();
  887. return Boolean.parseBoolean(text);
  888. case NUMERIC:
  889. return getNumericCellValue() != 0;
  890. case ERROR:
  891. case BLANK:
  892. return false;
  893. default: throw new RuntimeException("Unexpected cell type (" + cellType + ")");
  894. }
  895. }
  896. private String convertCellValueToString() {
  897. CellType cellType = getCellType();
  898. return convertCellValueToString(cellType);
  899. }
  900. private String convertCellValueToString(CellType cellType) {
  901. switch (cellType) {
  902. case BLANK:
  903. return "";
  904. case BOOLEAN:
  905. return getBooleanCellValue() ? "TRUE" : "FALSE";
  906. case STRING:
  907. return getStringCellValue();
  908. case NUMERIC:
  909. return Double.toString( getNumericCellValue() );
  910. case ERROR:
  911. byte errVal = getErrorCellValue();
  912. return FormulaError.forInt(errVal).getString();
  913. case FORMULA:
  914. if (_value != null) {
  915. FormulaValue fv = (FormulaValue)_value;
  916. if (fv.getFormulaType() != CellType.FORMULA) {
  917. return convertCellValueToString(fv.getFormulaType());
  918. }
  919. }
  920. return "";
  921. default:
  922. throw new IllegalStateException("Unexpected cell type (" + cellType + ")");
  923. }
  924. }
  925. //END OF COPIED CODE
  926. static abstract class Property
  927. {
  928. static final int COMMENT=1;
  929. static final int HYPERLINK=2;
  930. Object _value;
  931. Property _next;
  932. public Property(Object value)
  933. {
  934. _value = value;
  935. }
  936. abstract int getType();
  937. void setValue(Object value)
  938. {
  939. _value = value;
  940. }
  941. Object getValue()
  942. {
  943. return _value;
  944. }
  945. }
  946. static class CommentProperty extends Property
  947. {
  948. public CommentProperty(Object value)
  949. {
  950. super(value);
  951. }
  952. @Override
  953. public int getType()
  954. {
  955. return COMMENT;
  956. }
  957. }
  958. static class HyperlinkProperty extends Property
  959. {
  960. public HyperlinkProperty(Object value)
  961. {
  962. super(value);
  963. }
  964. @Override
  965. public int getType()
  966. {
  967. return HYPERLINK;
  968. }
  969. }
  970. interface Value
  971. {
  972. CellType getType();
  973. }
  974. static class NumericValue implements Value {
  975. double _value;
  976. public NumericValue() {
  977. _value = 0;
  978. }
  979. public NumericValue(double _value) {
  980. this._value = _value;
  981. }
  982. public CellType getType()
  983. {
  984. return CellType.NUMERIC;
  985. }
  986. void setValue(double value)
  987. {
  988. _value = value;
  989. }
  990. double getValue()
  991. {
  992. return _value;
  993. }
  994. }
  995. static abstract class StringValue implements Value
  996. {
  997. public CellType getType()
  998. {
  999. return CellType.STRING;
  1000. }
  1001. //We cannot introduce a new type CellType.RICH_TEXT because the types are public so we have to make rich text as a type of string
  1002. abstract boolean isRichText(); // using the POI style which seems to avoid "instanceof".
  1003. }
  1004. static class PlainStringValue extends StringValue
  1005. {
  1006. String _value;
  1007. void setValue(String value)
  1008. {
  1009. _value = value;
  1010. }
  1011. String getValue()
  1012. {
  1013. return _value;
  1014. }
  1015. @Override
  1016. boolean isRichText()
  1017. {
  1018. return false;
  1019. }
  1020. }
  1021. static class RichTextValue extends StringValue
  1022. {
  1023. RichTextString _value;
  1024. @Override
  1025. public CellType getType()
  1026. {
  1027. return CellType.STRING;
  1028. }
  1029. void setValue(RichTextString value)
  1030. {
  1031. _value = value;
  1032. }
  1033. RichTextString getValue()
  1034. {
  1035. return _value;
  1036. }
  1037. @Override
  1038. boolean isRichText()
  1039. {
  1040. return true;
  1041. }
  1042. }
  1043. static abstract class FormulaValue implements Value
  1044. {
  1045. String _value;
  1046. public FormulaValue(String _value) {
  1047. this._value = _value;
  1048. }
  1049. public CellType getType()
  1050. {
  1051. return CellType.FORMULA;
  1052. }
  1053. void setValue(String value)
  1054. {
  1055. _value = value;
  1056. }
  1057. String getValue()
  1058. {
  1059. return _value;
  1060. }
  1061. abstract CellType getFormulaType();
  1062. }
  1063. static class NumericFormulaValue extends FormulaValue {
  1064. double _preEvaluatedValue;
  1065. public NumericFormulaValue(String formula, double _preEvaluatedValue) {
  1066. super(formula);
  1067. this._preEvaluatedValue = _preEvaluatedValue;
  1068. }
  1069. @Override
  1070. CellType getFormulaType()
  1071. {
  1072. return CellType.NUMERIC;
  1073. }
  1074. void setPreEvaluatedValue(double value)
  1075. {
  1076. _preEvaluatedValue=value;
  1077. }
  1078. double getPreEvaluatedValue()
  1079. {
  1080. return _preEvaluatedValue;
  1081. }
  1082. }
  1083. static class StringFormulaValue extends FormulaValue {
  1084. String _preEvaluatedValue;
  1085. public StringFormulaValue(String formula, String value) {
  1086. super(formula);
  1087. _preEvaluatedValue = value;
  1088. }
  1089. @Override
  1090. CellType getFormulaType()
  1091. {
  1092. return CellType.STRING;
  1093. }
  1094. void setPreEvaluatedValue(String value)
  1095. {
  1096. _preEvaluatedValue=value;
  1097. }
  1098. String getPreEvaluatedValue()
  1099. {
  1100. return _preEvaluatedValue;
  1101. }
  1102. }
  1103. static class RichTextStringFormulaValue extends FormulaValue {
  1104. RichTextString _preEvaluatedValue;
  1105. public RichTextStringFormulaValue(String formula, RichTextString value) {
  1106. super(formula);
  1107. _preEvaluatedValue = value;
  1108. }
  1109. @Override
  1110. CellType getFormulaType()
  1111. {
  1112. return CellType.STRING;
  1113. }
  1114. void setPreEvaluatedValue(RichTextString value)
  1115. {
  1116. _preEvaluatedValue=value;
  1117. }
  1118. RichTextString getPreEvaluatedValue()
  1119. {
  1120. return _preEvaluatedValue;
  1121. }
  1122. }
  1123. static class BooleanFormulaValue extends FormulaValue {
  1124. boolean _preEvaluatedValue;
  1125. public BooleanFormulaValue(String formula, boolean value) {
  1126. super(formula);
  1127. _preEvaluatedValue = value;
  1128. }
  1129. @Override
  1130. CellType getFormulaType()
  1131. {
  1132. return CellType.BOOLEAN;
  1133. }
  1134. void setPreEvaluatedValue(boolean value)
  1135. {
  1136. _preEvaluatedValue=value;
  1137. }
  1138. boolean getPreEvaluatedValue()
  1139. {
  1140. return _preEvaluatedValue;
  1141. }
  1142. }
  1143. static class ErrorFormulaValue extends FormulaValue {
  1144. byte _preEvaluatedValue;
  1145. public ErrorFormulaValue(String formula, byte value) {
  1146. super(formula);
  1147. _preEvaluatedValue = value;
  1148. }
  1149. @Override
  1150. CellType getFormulaType()
  1151. {
  1152. return CellType.ERROR;
  1153. }
  1154. void setPreEvaluatedValue(byte value)
  1155. {
  1156. _preEvaluatedValue=value;
  1157. }
  1158. byte getPreEvaluatedValue()
  1159. {
  1160. return _preEvaluatedValue;
  1161. }
  1162. }
  1163. static class BlankValue implements Value {
  1164. public CellType getType()
  1165. {
  1166. return CellType.BLANK;
  1167. }
  1168. }
  1169. static class BooleanValue implements Value {
  1170. boolean _value;
  1171. public BooleanValue() {
  1172. _value = false;
  1173. }
  1174. public BooleanValue(boolean _value) {
  1175. this._value = _value;
  1176. }
  1177. public CellType getType()
  1178. {
  1179. return CellType.BOOLEAN;
  1180. }
  1181. void setValue(boolean value)
  1182. {
  1183. _value = value;
  1184. }
  1185. boolean getValue()
  1186. {
  1187. return _value;
  1188. }
  1189. }
  1190. static class ErrorValue implements Value
  1191. {
  1192. byte _value;
  1193. public ErrorValue() {
  1194. _value = FormulaError._NO_ERROR.getCode();
  1195. }
  1196. public ErrorValue(byte _value) {
  1197. this._value = _value;
  1198. }
  1199. public CellType getType()
  1200. {
  1201. return CellType.ERROR;
  1202. }
  1203. void setValue(byte value)
  1204. {
  1205. _value = value;
  1206. }
  1207. byte getValue()
  1208. {
  1209. return _value;
  1210. }
  1211. }
  1212. }