PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/components/forks/poi/src/loci/poi/hssf/usermodel/HSSFCell.java

http://github.com/openmicroscopy/bioformats
Java | 1061 lines | 587 code | 111 blank | 363 comment | 112 complexity | a320b63ccf16b2c1798c3d8c1abc8ed7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0, BSD-2-Clause, MPL-2.0-no-copyleft-exception
  1. /*
  2. * #%L
  3. * Fork of Apache Jakarta POI.
  4. * %%
  5. * Copyright (C) 2008 - 2013 Open Microscopy Environment:
  6. * - Board of Regents of the University of Wisconsin-Madison
  7. * - Glencoe Software, Inc.
  8. * - University of Dundee
  9. * %%
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. * #L%
  22. */
  23. /* ====================================================================
  24. Licensed to the Apache Software Foundation (ASF) under one or more
  25. contributor license agreements. See the NOTICE file distributed with
  26. this work for additional information regarding copyright ownership.
  27. The ASF licenses this file to You under the Apache License, Version 2.0
  28. (the "License"); you may not use this file except in compliance with
  29. the License. You may obtain a copy of the License at
  30. http://www.apache.org/licenses/LICENSE-2.0
  31. Unless required by applicable law or agreed to in writing, software
  32. distributed under the License is distributed on an "AS IS" BASIS,
  33. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  34. See the License for the specific language governing permissions and
  35. limitations under the License.
  36. ==================================================================== */
  37. /*
  38. * Cell.java
  39. *
  40. * Created on September 30, 2001, 3:46 PM
  41. */
  42. package loci.poi.hssf.usermodel;
  43. import loci.poi.hssf.model.FormulaParser;
  44. import loci.poi.hssf.model.Sheet;
  45. import loci.poi.hssf.model.Workbook;
  46. import loci.poi.hssf.record.*;
  47. import loci.poi.hssf.record.aggregates.FormulaRecordAggregate;
  48. import loci.poi.hssf.record.formula.Ptg;
  49. import java.text.DateFormat;
  50. import java.text.SimpleDateFormat;
  51. import java.util.*;
  52. /**
  53. * High level representation of a cell in a row of a spreadsheet.
  54. * Cells can be numeric, formula-based or string-based (text). The cell type
  55. * specifies this. String cells cannot conatin numbers and numeric cells cannot
  56. * contain strings (at least according to our model). Client apps should do the
  57. * conversions themselves. Formula cells have the formula string, as well as
  58. * the formula result, which can be numeric or string.
  59. * <p>
  60. * Cells should have their number (0 based) before being added to a row. Only
  61. * cells that have values should be added.
  62. * <p>
  63. *
  64. * @author Andrew C. Oliver (acoliver at apache dot org)
  65. * @author Dan Sherman (dsherman at isisph.com)
  66. * @author Brian Sanders (kestrel at burdell dot org) Active Cell support
  67. * @author Yegor Kozlov cell comments support
  68. * @version 1.0-pre
  69. */
  70. public class HSSFCell
  71. {
  72. /**
  73. * Numeric Cell type (0)
  74. * @see #setCellType(int)
  75. * @see #getCellType()
  76. */
  77. public final static int CELL_TYPE_NUMERIC = 0;
  78. /**
  79. * String Cell type (1)
  80. * @see #setCellType(int)
  81. * @see #getCellType()
  82. */
  83. public final static int CELL_TYPE_STRING = 1;
  84. /**
  85. * Formula Cell type (2)
  86. * @see #setCellType(int)
  87. * @see #getCellType()
  88. */
  89. public final static int CELL_TYPE_FORMULA = 2;
  90. /**
  91. * Blank Cell type (3)
  92. * @see #setCellType(int)
  93. * @see #getCellType()
  94. */
  95. public final static int CELL_TYPE_BLANK = 3;
  96. /**
  97. * Boolean Cell type (4)
  98. * @see #setCellType(int)
  99. * @see #getCellType()
  100. */
  101. public final static int CELL_TYPE_BOOLEAN = 4;
  102. /**
  103. * Error Cell type (5)
  104. * @see #setCellType(int)
  105. * @see #getCellType()
  106. */
  107. public final static int CELL_TYPE_ERROR = 5;
  108. public final static short ENCODING_UNCHANGED = -1;
  109. public final static short ENCODING_COMPRESSED_UNICODE = 0;
  110. public final static short ENCODING_UTF_16 = 1;
  111. private int cellType;
  112. private HSSFRichTextString stringValue;
  113. private short encoding = ENCODING_UNCHANGED;
  114. private Workbook book;
  115. private Sheet sheet;
  116. private CellValueRecordInterface record;
  117. private HSSFComment comment;
  118. /**
  119. * Creates new Cell - Should only be called by HSSFRow. This creates a cell
  120. * from scratch.
  121. * <p>
  122. * When the cell is initially created it is set to CELL_TYPE_BLANK. Cell types
  123. * can be changed/overwritten by calling setCellValue with the appropriate
  124. * type as a parameter although conversions from one type to another may be
  125. * prohibited.
  126. *
  127. * @param book - Workbook record of the workbook containing this cell
  128. * @param sheet - Sheet record of the sheet containing this cell
  129. * @param row - the row of this cell
  130. * @param col - the column for this cell
  131. *
  132. * @see loci.poi.hssf.usermodel.HSSFRow#createCell(short)
  133. */
  134. //protected HSSFCell(Workbook book, Sheet sheet, short row, short col)
  135. protected HSSFCell(Workbook book, Sheet sheet, int row, short col)
  136. {
  137. checkBounds(col);
  138. stringValue = null;
  139. this.book = book;
  140. this.sheet = sheet;
  141. // Relying on the fact that by default the cellType is set to 0 which
  142. // is different to CELL_TYPE_BLANK hence the following method call correctly
  143. // creates a new blank cell.
  144. short xfindex = sheet.getXFIndexForColAt(col);
  145. setCellType(CELL_TYPE_BLANK, false, row, col,xfindex);
  146. }
  147. /**
  148. * Creates new Cell - Should only be called by HSSFRow. This creates a cell
  149. * from scratch.
  150. *
  151. * @param book - Workbook record of the workbook containing this cell
  152. * @param sheet - Sheet record of the sheet containing this cell
  153. * @param row - the row of this cell
  154. * @param col - the column for this cell
  155. * @param type - CELL_TYPE_NUMERIC, CELL_TYPE_STRING, CELL_TYPE_FORMULA, CELL_TYPE_BLANK,
  156. * CELL_TYPE_BOOLEAN, CELL_TYPE_ERROR
  157. * Type of cell
  158. * @see loci.poi.hssf.usermodel.HSSFRow#createCell(short,int)
  159. */
  160. //protected HSSFCell(Workbook book, Sheet sheet, short row, short col,
  161. protected HSSFCell(Workbook book, Sheet sheet, int row, short col,
  162. int type)
  163. {
  164. checkBounds(col);
  165. cellType = -1; // Force 'setCellType' to create a first Record
  166. stringValue = null;
  167. this.book = book;
  168. this.sheet = sheet;
  169. short xfindex = sheet.getXFIndexForColAt(col);
  170. setCellType(type,false,row,col,xfindex);
  171. }
  172. /**
  173. * Creates an HSSFCell from a CellValueRecordInterface. HSSFSheet uses this when
  174. * reading in cells from an existing sheet.
  175. *
  176. * @param book - Workbook record of the workbook containing this cell
  177. * @param sheet - Sheet record of the sheet containing this cell
  178. * @param cval - the Cell Value Record we wish to represent
  179. */
  180. //protected HSSFCell(Workbook book, Sheet sheet, short row,
  181. protected HSSFCell(Workbook book, Sheet sheet, int row,
  182. CellValueRecordInterface cval)
  183. {
  184. record = cval;
  185. cellType = determineType(cval);
  186. stringValue = null;
  187. this.book = book;
  188. this.sheet = sheet;
  189. switch (cellType)
  190. {
  191. case CELL_TYPE_STRING :
  192. stringValue = new HSSFRichTextString(book, (LabelSSTRecord ) cval);
  193. break;
  194. case CELL_TYPE_BLANK :
  195. break;
  196. case CELL_TYPE_FORMULA :
  197. stringValue=new HSSFRichTextString(((FormulaRecordAggregate) cval).getStringValue());
  198. break;
  199. }
  200. ExtendedFormatRecord xf = book.getExFormatAt(cval.getXFIndex());
  201. setCellStyle(new HSSFCellStyle(( short ) cval.getXFIndex(), xf));
  202. }
  203. /**
  204. * private constructor to prevent blank construction
  205. */
  206. private HSSFCell()
  207. {
  208. }
  209. /**
  210. * used internally -- given a cell value record, figure out its type
  211. */
  212. private int determineType(CellValueRecordInterface cval)
  213. {
  214. Record record = ( Record ) cval;
  215. int sid = record.getSid();
  216. int retval = 0;
  217. switch (sid)
  218. {
  219. case NumberRecord.sid :
  220. retval = HSSFCell.CELL_TYPE_NUMERIC;
  221. break;
  222. case BlankRecord.sid :
  223. retval = HSSFCell.CELL_TYPE_BLANK;
  224. break;
  225. case LabelSSTRecord.sid :
  226. retval = HSSFCell.CELL_TYPE_STRING;
  227. break;
  228. case FormulaRecordAggregate.sid :
  229. retval = HSSFCell.CELL_TYPE_FORMULA;
  230. break;
  231. case BoolErrRecord.sid :
  232. BoolErrRecord boolErrRecord = ( BoolErrRecord ) record;
  233. retval = (boolErrRecord.isBoolean())
  234. ? HSSFCell.CELL_TYPE_BOOLEAN
  235. : HSSFCell.CELL_TYPE_ERROR;
  236. break;
  237. }
  238. return retval;
  239. }
  240. /**
  241. * Returns the Workbook that this Cell is bound to
  242. * @return
  243. */
  244. protected Workbook getBoundWorkbook() {
  245. return book;
  246. }
  247. /**
  248. * set the cell's number within the row (0 based)
  249. * @param num short the cell number
  250. */
  251. public void setCellNum(short num)
  252. {
  253. record.setColumn(num);
  254. }
  255. /**
  256. * get the cell's number within the row
  257. * @return short reperesenting the column number (logical!)
  258. */
  259. public short getCellNum()
  260. {
  261. return record.getColumn();
  262. }
  263. /**
  264. * set the cells type (numeric, formula or string)
  265. * @see #CELL_TYPE_NUMERIC
  266. * @see #CELL_TYPE_STRING
  267. * @see #CELL_TYPE_FORMULA
  268. * @see #CELL_TYPE_BLANK
  269. * @see #CELL_TYPE_BOOLEAN
  270. * @see #CELL_TYPE_ERROR
  271. */
  272. public void setCellType(int cellType)
  273. {
  274. int row=record.getRow();
  275. short col=record.getColumn();
  276. short styleIndex=record.getXFIndex();
  277. setCellType(cellType, true, row, col, styleIndex);
  278. }
  279. /**
  280. * sets the cell type. The setValue flag indicates whether to bother about
  281. * trying to preserve the current value in the new record if one is created.
  282. * <p>
  283. * The @see #setCellValue method will call this method with false in setValue
  284. * since it will overwrite the cell value later
  285. *
  286. */
  287. private void setCellType(int cellType, boolean setValue, int row,short col, short styleIndex)
  288. {
  289. // if (cellType == CELL_TYPE_FORMULA)
  290. // {
  291. // throw new RuntimeException(
  292. // "Formulas have not been implemented in this release");
  293. // }
  294. if (cellType > CELL_TYPE_ERROR)
  295. {
  296. throw new RuntimeException("I have no idea what type that is!");
  297. }
  298. switch (cellType)
  299. {
  300. case CELL_TYPE_FORMULA :
  301. FormulaRecordAggregate frec = null;
  302. if (cellType != this.cellType)
  303. {
  304. frec = new FormulaRecordAggregate(new FormulaRecord(),null);
  305. }
  306. else
  307. {
  308. frec = ( FormulaRecordAggregate ) record;
  309. }
  310. frec.setColumn(col);
  311. if (setValue)
  312. {
  313. frec.getFormulaRecord().setValue(getNumericCellValue());
  314. }
  315. frec.setXFIndex(styleIndex);
  316. frec.setRow(row);
  317. record = frec;
  318. break;
  319. case CELL_TYPE_NUMERIC :
  320. NumberRecord nrec = null;
  321. if (cellType != this.cellType)
  322. {
  323. nrec = new NumberRecord();
  324. }
  325. else
  326. {
  327. nrec = ( NumberRecord ) record;
  328. }
  329. nrec.setColumn(col);
  330. if (setValue)
  331. {
  332. nrec.setValue(getNumericCellValue());
  333. }
  334. nrec.setXFIndex(styleIndex);
  335. nrec.setRow(row);
  336. record = nrec;
  337. break;
  338. case CELL_TYPE_STRING :
  339. LabelSSTRecord lrec = null;
  340. if (cellType != this.cellType)
  341. {
  342. lrec = new LabelSSTRecord();
  343. }
  344. else
  345. {
  346. lrec = ( LabelSSTRecord ) record;
  347. }
  348. lrec.setColumn(col);
  349. lrec.setRow(row);
  350. lrec.setXFIndex(styleIndex);
  351. if (setValue)
  352. {
  353. if ((getStringCellValue() != null)
  354. && (!getStringCellValue().equals("")))
  355. {
  356. int sst = 0;
  357. UnicodeString str = getRichStringCellValue().getUnicodeString();
  358. //jmh if (encoding == ENCODING_COMPRESSED_UNICODE)
  359. //jmh {
  360. // jmh str.setCompressedUnicode();
  361. // jmh } else if (encoding == ENCODING_UTF_16)
  362. // jmh {
  363. // jmh str.setUncompressedUnicode();
  364. // jmh }
  365. sst = book.addSSTString(str);
  366. lrec.setSSTIndex(sst);
  367. getRichStringCellValue().setUnicodeString(book.getSSTString(sst));
  368. }
  369. }
  370. record = lrec;
  371. break;
  372. case CELL_TYPE_BLANK :
  373. BlankRecord brec = null;
  374. if (cellType != this.cellType)
  375. {
  376. brec = new BlankRecord();
  377. }
  378. else
  379. {
  380. brec = ( BlankRecord ) record;
  381. }
  382. brec.setColumn(col);
  383. // During construction the cellStyle may be null for a Blank cell.
  384. brec.setXFIndex(styleIndex);
  385. brec.setRow(row);
  386. record = brec;
  387. break;
  388. case CELL_TYPE_BOOLEAN :
  389. BoolErrRecord boolRec = null;
  390. if (cellType != this.cellType)
  391. {
  392. boolRec = new BoolErrRecord();
  393. }
  394. else
  395. {
  396. boolRec = ( BoolErrRecord ) record;
  397. }
  398. boolRec.setColumn(col);
  399. if (setValue)
  400. {
  401. boolRec.setValue(getBooleanCellValue());
  402. }
  403. boolRec.setXFIndex(styleIndex);
  404. boolRec.setRow(row);
  405. record = boolRec;
  406. break;
  407. case CELL_TYPE_ERROR :
  408. BoolErrRecord errRec = null;
  409. if (cellType != this.cellType)
  410. {
  411. errRec = new BoolErrRecord();
  412. }
  413. else
  414. {
  415. errRec = ( BoolErrRecord ) record;
  416. }
  417. errRec.setColumn(col);
  418. if (setValue)
  419. {
  420. errRec.setValue(getErrorCellValue());
  421. }
  422. errRec.setXFIndex(styleIndex);
  423. errRec.setRow(row);
  424. record = errRec;
  425. break;
  426. }
  427. if (cellType != this.cellType &&
  428. this.cellType!=-1 ) // Special Value to indicate an uninitialized Cell
  429. {
  430. int loc = sheet.getLoc();
  431. sheet.replaceValueRecord(record);
  432. sheet.setLoc(loc);
  433. }
  434. this.cellType = cellType;
  435. }
  436. /**
  437. * get the cells type (numeric, formula or string)
  438. * @see #CELL_TYPE_STRING
  439. * @see #CELL_TYPE_NUMERIC
  440. * @see #CELL_TYPE_FORMULA
  441. * @see #CELL_TYPE_BOOLEAN
  442. * @see #CELL_TYPE_ERROR
  443. */
  444. public int getCellType()
  445. {
  446. return cellType;
  447. }
  448. /**
  449. * set a numeric value for the cell
  450. *
  451. * @param value the numeric value to set this cell to. For formulas we'll set the
  452. * precalculated value, for numerics we'll set its value. For other types we
  453. * will change the cell to a numeric cell and set its value.
  454. */
  455. public void setCellValue(double value)
  456. {
  457. int row=record.getRow();
  458. short col=record.getColumn();
  459. short styleIndex=record.getXFIndex();
  460. if ((cellType != CELL_TYPE_NUMERIC) && (cellType != CELL_TYPE_FORMULA))
  461. {
  462. setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex);
  463. }
  464. (( NumberRecord ) record).setValue(value);
  465. }
  466. /**
  467. * set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as
  468. * a date.
  469. *
  470. * @param value the date value to set this cell to. For formulas we'll set the
  471. * precalculated value, for numerics we'll set its value. For other types we
  472. * will change the cell to a numeric cell and set its value.
  473. */
  474. public void setCellValue(Date value)
  475. {
  476. setCellValue(HSSFDateUtil.getExcelDate(value));
  477. }
  478. /**
  479. * set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as
  480. * a date.
  481. *
  482. * @param value the date value to set this cell to. For formulas we'll set the
  483. * precalculated value, for numerics we'll set its value. For othertypes we
  484. * will change the cell to a numeric cell and set its value.
  485. */
  486. public void setCellValue(Calendar value)
  487. {
  488. setCellValue(value.getTime());
  489. }
  490. /**
  491. * set a string value for the cell. Please note that if you are using
  492. * full 16 bit unicode you should call <code>setEncoding()</code> first.
  493. *
  494. * @param value value to set the cell to. For formulas we'll set the formula
  495. * string, for String cells we'll set its value. For other types we will
  496. * change the cell to a string cell and set its value.
  497. * If value is null then we will change the cell to a Blank cell.
  498. * @deprecated Use setCellValue(HSSFRichTextString) instead.
  499. */
  500. public void setCellValue(String value)
  501. {
  502. HSSFRichTextString str = new HSSFRichTextString(value);
  503. setCellValue(str);
  504. }
  505. /**
  506. * set a string value for the cell. Please note that if you are using
  507. * full 16 bit unicode you should call <code>setEncoding()</code> first.
  508. *
  509. * @param value value to set the cell to. For formulas we'll set the formula
  510. * string, for String cells we'll set its value. For other types we will
  511. * change the cell to a string cell and set its value.
  512. * If value is null then we will change the cell to a Blank cell.
  513. */
  514. public void setCellValue(HSSFRichTextString value)
  515. {
  516. int row=record.getRow();
  517. short col=record.getColumn();
  518. short styleIndex=record.getXFIndex();
  519. if (value == null)
  520. {
  521. setCellType(CELL_TYPE_BLANK, false, row, col, styleIndex);
  522. }
  523. else
  524. {
  525. if ((cellType != CELL_TYPE_STRING ) && ( cellType != CELL_TYPE_FORMULA))
  526. {
  527. setCellType(CELL_TYPE_STRING, false, row, col, styleIndex);
  528. }
  529. int index = 0;
  530. UnicodeString str = value.getUnicodeString();
  531. // jmh if (encoding == ENCODING_COMPRESSED_UNICODE)
  532. // jmh {
  533. // jmh str.setCompressedUnicode();
  534. // jmh } else if (encoding == ENCODING_UTF_16)
  535. // jmh {
  536. // jmh str.setUncompressedUnicode();
  537. // jmh }
  538. index = book.addSSTString(str);
  539. (( LabelSSTRecord ) record).setSSTIndex(index);
  540. stringValue = value;
  541. stringValue.setWorkbookReferences(book, (( LabelSSTRecord ) record));
  542. stringValue.setUnicodeString(book.getSSTString(index));
  543. }
  544. }
  545. public void setCellFormula(String formula) {
  546. int row=record.getRow();
  547. short col=record.getColumn();
  548. short styleIndex=record.getXFIndex();
  549. //Workbook.currentBook=book;
  550. if (formula==null) {
  551. setCellType(CELL_TYPE_BLANK,false,row,col,styleIndex);
  552. } else {
  553. setCellType(CELL_TYPE_FORMULA,false,row,col,styleIndex);
  554. FormulaRecordAggregate rec = (FormulaRecordAggregate) record;
  555. FormulaRecord frec = rec.getFormulaRecord();
  556. frec.setOptions(( short ) 2);
  557. frec.setValue(0);
  558. //only set to default if there is no extended format index already set
  559. if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f);
  560. FormulaParser fp = new FormulaParser(formula+";",book);
  561. fp.parse();
  562. Ptg[] ptg = fp.getRPNPtg();
  563. int size = 0;
  564. // clear the Ptg Stack
  565. for (int i=0, iSize=frec.getNumberOfExpressionTokens(); i<iSize; i++) {
  566. frec.popExpressionToken();
  567. }
  568. // fill the Ptg Stack with Ptgs of new formula
  569. for (int k = 0; k < ptg.length; k++) {
  570. size += ptg[ k ].getSize();
  571. frec.pushExpressionToken(ptg[ k ]);
  572. }
  573. rec.getFormulaRecord().setExpressionLength(( short ) size);
  574. //Workbook.currentBook = null;
  575. }
  576. }
  577. public String getCellFormula() {
  578. //Workbook.currentBook=book;
  579. String retval = FormulaParser.toFormulaString(book, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
  580. //Workbook.currentBook=null;
  581. return retval;
  582. }
  583. /**
  584. * get the value of the cell as a number. For strings we throw an exception.
  585. * For blank cells we return a 0.
  586. */
  587. public double getNumericCellValue()
  588. {
  589. if (cellType == CELL_TYPE_BLANK)
  590. {
  591. return 0;
  592. }
  593. if (cellType == CELL_TYPE_STRING)
  594. {
  595. throw new NumberFormatException(
  596. "You cannot get a numeric value from a String based cell");
  597. }
  598. if (cellType == CELL_TYPE_BOOLEAN)
  599. {
  600. throw new NumberFormatException(
  601. "You cannot get a numeric value from a boolean cell");
  602. }
  603. if (cellType == CELL_TYPE_ERROR)
  604. {
  605. throw new NumberFormatException(
  606. "You cannot get a numeric value from an error cell");
  607. }
  608. if(cellType == CELL_TYPE_NUMERIC)
  609. {
  610. return ((NumberRecord)record).getValue();
  611. }
  612. if(cellType == CELL_TYPE_FORMULA)
  613. {
  614. return ((FormulaRecordAggregate)record).getFormulaRecord().getValue();
  615. }
  616. throw new NumberFormatException("Unknown Record Type in Cell:"+cellType);
  617. }
  618. /**
  619. * get the value of the cell as a date. For strings we throw an exception.
  620. * For blank cells we return a null.
  621. */
  622. public Date getDateCellValue()
  623. {
  624. if (cellType == CELL_TYPE_BLANK)
  625. {
  626. return null;
  627. }
  628. if (cellType == CELL_TYPE_STRING)
  629. {
  630. throw new NumberFormatException(
  631. "You cannot get a date value from a String based cell");
  632. }
  633. if (cellType == CELL_TYPE_BOOLEAN)
  634. {
  635. throw new NumberFormatException(
  636. "You cannot get a date value from a boolean cell");
  637. }
  638. if (cellType == CELL_TYPE_ERROR)
  639. {
  640. throw new NumberFormatException(
  641. "You cannot get a date value from an error cell");
  642. }
  643. double value=this.getNumericCellValue();
  644. if (book.isUsing1904DateWindowing()) {
  645. return HSSFDateUtil.getJavaDate(value,true);
  646. }
  647. else {
  648. return HSSFDateUtil.getJavaDate(value,false);
  649. }
  650. }
  651. /**
  652. * get the value of the cell as a string - for numeric cells we throw an exception.
  653. * For blank cells we return an empty string.
  654. * For formulaCells that are not string Formulas, we return empty String
  655. * @deprecated Use the HSSFRichTextString return
  656. */
  657. public String getStringCellValue()
  658. {
  659. HSSFRichTextString str = getRichStringCellValue();
  660. return str.getString();
  661. }
  662. /**
  663. * get the value of the cell as a string - for numeric cells we throw an exception.
  664. * For blank cells we return an empty string.
  665. * For formulaCells that are not string Formulas, we return empty String
  666. */
  667. public HSSFRichTextString getRichStringCellValue()
  668. {
  669. if (cellType == CELL_TYPE_BLANK)
  670. {
  671. return new HSSFRichTextString("");
  672. }
  673. if (cellType == CELL_TYPE_NUMERIC)
  674. {
  675. throw new NumberFormatException(
  676. "You cannot get a string value from a numeric cell");
  677. }
  678. if (cellType == CELL_TYPE_BOOLEAN)
  679. {
  680. throw new NumberFormatException(
  681. "You cannot get a string value from a boolean cell");
  682. }
  683. if (cellType == CELL_TYPE_ERROR)
  684. {
  685. throw new NumberFormatException(
  686. "You cannot get a string value from an error cell");
  687. }
  688. if (cellType == CELL_TYPE_FORMULA)
  689. {
  690. if (stringValue==null) return new HSSFRichTextString("");
  691. }
  692. return stringValue;
  693. }
  694. /**
  695. * set a boolean value for the cell
  696. *
  697. * @param value the boolean value to set this cell to. For formulas we'll set the
  698. * precalculated value, for booleans we'll set its value. For other types we
  699. * will change the cell to a boolean cell and set its value.
  700. */
  701. public void setCellValue(boolean value)
  702. {
  703. int row=record.getRow();
  704. short col=record.getColumn();
  705. short styleIndex=record.getXFIndex();
  706. if ((cellType != CELL_TYPE_BOOLEAN ) && ( cellType != CELL_TYPE_FORMULA))
  707. {
  708. setCellType(CELL_TYPE_BOOLEAN, false, row, col, styleIndex);
  709. }
  710. (( BoolErrRecord ) record).setValue(value);
  711. }
  712. /**
  713. * set a error value for the cell
  714. *
  715. * @param value the error value to set this cell to. For formulas we'll set the
  716. * precalculated value ??? IS THIS RIGHT??? , for errors we'll set
  717. * its value. For other types we will change the cell to an error
  718. * cell and set its value.
  719. */
  720. public void setCellErrorValue(byte value)
  721. {
  722. int row=record.getRow();
  723. short col=record.getColumn();
  724. short styleIndex=record.getXFIndex();
  725. if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA))
  726. {
  727. setCellType(CELL_TYPE_ERROR, false, row, col, styleIndex);
  728. }
  729. (( BoolErrRecord ) record).setValue(value);
  730. }
  731. /**
  732. * get the value of the cell as a boolean. For strings, numbers, and errors, we throw an exception.
  733. * For blank cells we return a false.
  734. */
  735. public boolean getBooleanCellValue()
  736. {
  737. if (cellType == CELL_TYPE_BOOLEAN)
  738. {
  739. return (( BoolErrRecord ) record).getBooleanValue();
  740. }
  741. if (cellType == CELL_TYPE_BLANK)
  742. {
  743. return false;
  744. }
  745. throw new NumberFormatException(
  746. "You cannot get a boolean value from a non-boolean cell");
  747. }
  748. /**
  749. * get the value of the cell as an error code. For strings, numbers, and booleans, we throw an exception.
  750. * For blank cells we return a 0.
  751. */
  752. public byte getErrorCellValue()
  753. {
  754. if (cellType == CELL_TYPE_ERROR)
  755. {
  756. return (( BoolErrRecord ) record).getErrorValue();
  757. }
  758. if (cellType == CELL_TYPE_BLANK)
  759. {
  760. return ( byte ) 0;
  761. }
  762. throw new NumberFormatException(
  763. "You cannot get an error value from a non-error cell");
  764. }
  765. /**
  766. * set the style for the cell. The style should be an HSSFCellStyle created/retreived from
  767. * the HSSFWorkbook.
  768. *
  769. * @param style reference contained in the workbook
  770. * @see loci.poi.hssf.usermodel.HSSFWorkbook#createCellStyle()
  771. * @see loci.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
  772. */
  773. public void setCellStyle(HSSFCellStyle style)
  774. {
  775. record.setXFIndex(style.getIndex());
  776. }
  777. /**
  778. * get the style for the cell. This is a reference to a cell style contained in the workbook
  779. * object.
  780. * @see loci.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
  781. */
  782. public HSSFCellStyle getCellStyle()
  783. {
  784. short styleIndex=record.getXFIndex();
  785. ExtendedFormatRecord xf = book.getExFormatAt(styleIndex);
  786. return new HSSFCellStyle(styleIndex, xf);
  787. }
  788. /**
  789. * used for internationalization, currently -1 for unchanged, 0 for compressed unicode or 1 for 16-bit
  790. *
  791. * @see #ENCODING_UNCHANGED
  792. * @see #ENCODING_COMPRESSED_UNICODE
  793. * @see #ENCODING_UTF_16
  794. *
  795. * @return -1, 1 or 0 for unchanged, compressed or uncompressed (used only with String type)
  796. *
  797. * @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding.
  798. */
  799. public short getEncoding()
  800. {
  801. return encoding;
  802. }
  803. /**
  804. * set the encoding to either 8 or 16 bit. (US/UK use 8-bit, rest of the western world use 16bit)
  805. *
  806. * @see #ENCODING_UNCHANGED
  807. * @see #ENCODING_COMPRESSED_UNICODE
  808. * @see #ENCODING_UTF_16
  809. *
  810. * @param encoding either ENCODING_COMPRESSED_UNICODE (0) or ENCODING_UTF_16 (1)
  811. * @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding.
  812. */
  813. public void setEncoding(short encoding)
  814. {
  815. this.encoding = encoding;
  816. }
  817. /**
  818. * Should only be used by HSSFSheet and friends. Returns the low level CellValueRecordInterface record
  819. *
  820. * @return CellValueRecordInterface representing the cell via the low level api.
  821. */
  822. protected CellValueRecordInterface getCellValueRecord()
  823. {
  824. return record;
  825. }
  826. /**
  827. * @throws RuntimeException if the bounds are exceeded.
  828. */
  829. private void checkBounds(int cellNum) {
  830. if (cellNum > 255) {
  831. throw new RuntimeException("You cannot have more than 255 columns "+
  832. "in a given row (IV). Because Excel can't handle it");
  833. }
  834. else if (cellNum < 0) {
  835. throw new RuntimeException("You cannot reference columns with an index of less then 0.");
  836. }
  837. }
  838. /**
  839. * Sets this cell as the active cell for the worksheet
  840. */
  841. public void setAsActiveCell()
  842. {
  843. int row=record.getRow();
  844. short col=record.getColumn();
  845. this.sheet.setActiveCellRow(row);
  846. this.sheet.setActiveCellCol(col);
  847. }
  848. /**
  849. * Returns a string representation of the cell
  850. *
  851. * This method returns a simple representation,
  852. * anthing more complex should be in user code, with
  853. * knowledge of the semantics of the sheet being processed.
  854. *
  855. * Formula cells return the formula string,
  856. * rather than the formula result.
  857. * Dates are displayed in dd-MMM-yyyy format
  858. * Errors are displayed as #ERR&lt;errIdx&gt;
  859. */
  860. public String toString() {
  861. switch (getCellType()) {
  862. case CELL_TYPE_BLANK:
  863. return "";
  864. case CELL_TYPE_BOOLEAN:
  865. return getBooleanCellValue()?"TRUE":"FALSE";
  866. case CELL_TYPE_ERROR:
  867. return "#ERR"+getErrorCellValue();
  868. case CELL_TYPE_FORMULA:
  869. return getCellFormula();
  870. case CELL_TYPE_NUMERIC:
  871. //TODO apply the dataformat for this cell
  872. if (HSSFDateUtil.isCellDateFormatted(this)) {
  873. DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
  874. return sdf.format(getDateCellValue());
  875. }else {
  876. return getNumericCellValue() + "";
  877. }
  878. case CELL_TYPE_STRING:
  879. return getStringCellValue();
  880. default:
  881. return "Unknown Cell Type: " + getCellType();
  882. }
  883. }
  884. /**
  885. * Assign a comment to this cell
  886. *
  887. * @param comment comment associated with this cell
  888. */
  889. public void setCellComment(HSSFComment comment){
  890. comment.setRow((short)record.getRow());
  891. comment.setColumn(record.getColumn());
  892. this.comment = comment;
  893. }
  894. /**
  895. * Returns comment associated with this cell
  896. *
  897. * @return comment associated with this cell
  898. */
  899. public HSSFComment getCellComment(){
  900. if (comment == null) {
  901. comment = findCellComment(sheet, record.getRow(), record.getColumn());
  902. }
  903. return comment;
  904. }
  905. /**
  906. * Cell comment finder.
  907. * Returns cell comment for the specified sheet, row and column.
  908. *
  909. * @return cell comment or <code>null</code> if not found
  910. */
  911. protected static HSSFComment findCellComment(Sheet sheet, int row, int column){
  912. HSSFComment comment = null;
  913. HashMap txshapes = new HashMap(); //map shapeId and TextObjectRecord
  914. for (Iterator it = sheet.getRecords().iterator(); it.hasNext(); ) {
  915. Record rec = ( Record ) it.next();
  916. if (rec instanceof NoteRecord){
  917. NoteRecord note = (NoteRecord)rec;
  918. if (note.getRow() == row && note.getColumn() == column){
  919. TextObjectRecord txo = (TextObjectRecord)txshapes.get(new Integer(note.getShapeId()));
  920. comment = new HSSFComment(note, txo);
  921. comment.setRow(note.getRow());
  922. comment.setColumn(note.getColumn());
  923. comment.setAuthor(note.getAuthor());
  924. comment.setVisible(note.getFlags() == NoteRecord.NOTE_VISIBLE);
  925. comment.setString(txo.getStr());
  926. break;
  927. }
  928. } else if (rec instanceof ObjRecord){
  929. ObjRecord obj = (ObjRecord)rec;
  930. SubRecord sub = (SubRecord)obj.getSubRecords().get(0);
  931. if (sub instanceof CommonObjectDataSubRecord){
  932. CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord)sub;
  933. if (cmo.getObjectType() == CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT){
  934. //find the nearest TextObjectRecord which holds comment's text and map it to its shapeId
  935. while(it.hasNext()) {
  936. rec = ( Record ) it.next();
  937. if (rec instanceof TextObjectRecord) {
  938. txshapes.put(new Integer(cmo.getObjectId()), rec);
  939. break;
  940. }
  941. }
  942. }
  943. }
  944. }
  945. }
  946. return comment;
  947. }
  948. }