1    
2    /* ====================================================================
3     * The Apache Software License, Version 1.1
4     *
5     * Copyright (c) 2002 The Apache Software Foundation.  All rights
6     * reserved.
7     *
8     * Redistribution and use in source and binary forms, with or without
9     * modification, are permitted provided that the following conditions
10    * are met:
11    *
12    * 1. Redistributions of source code must retain the above copyright
13    *    notice, this list of conditions and the following disclaimer.
14    *
15    * 2. Redistributions in binary form must reproduce the above copyright
16    *    notice, this list of conditions and the following disclaimer in
17    *    the documentation and/or other materials provided with the
18    *    distribution.
19    *
20    * 3. The end-user documentation included with the redistribution,
21    *    if any, must include the following acknowledgment:
22    *       "This product includes software developed by the
23    *        Apache Software Foundation (http://www.apache.org/)."
24    *    Alternately, this acknowledgment may appear in the software itself,
25    *    if and wherever such third-party acknowledgments normally appear.
26    *
27    * 4. The names "Apache" and "Apache Software Foundation" and
28    *    "Apache POI" must not be used to endorse or promote products
29    *    derived from this software without prior written permission. For
30    *    written permission, please contact apache@apache.org.
31    *
32    * 5. Products derived from this software may not be called "Apache",
33    *    "Apache POI", nor may "Apache" appear in their name, without
34    *    prior written permission of the Apache Software Foundation.
35    *
36    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47    * SUCH DAMAGE.
48    * ====================================================================
49    *
50    * This software consists of voluntary contributions made by many
51    * individuals on behalf of the Apache Software Foundation.  For more
52    * information on the Apache Software Foundation, please see
53    * <http://www.apache.org/>.
54    */
55   
56   /*
57    * Cell.java
58    *
59    * Created on September 30, 2001, 3:46 PM
60    */
61   package org.apache.poi.hssf.usermodel;
62   
63   import org.apache.poi.hssf.model.Workbook;
64   import org.apache.poi.hssf.model.Sheet;
65   import org.apache.poi.hssf.record.CellValueRecordInterface;
66   import org.apache.poi.hssf.record.Record;
67   import org.apache.poi.hssf.record.FormulaRecord;
68   import org.apache.poi.hssf.record.LabelSSTRecord;
69   import org.apache.poi.hssf.record.NumberRecord;
70   import org.apache.poi.hssf.record.BlankRecord;
71   import org.apache.poi.hssf.record.BoolErrRecord;
72   import org.apache.poi.hssf.record.ExtendedFormatRecord;
73   import org.apache.poi.hssf.record.formula.Ptg;
74   
75   import org.apache.poi.hssf.record.formula.FormulaParser;
76   
77   import java.util.Date;
78   import java.util.Calendar;
79   
80   /**
81    * High level representation of a cell in a row of a spreadsheet.
82    * Cells can be numeric, formula-based or string-based (text).  The cell type
83    * specifies this.  String cells cannot conatin numbers and numeric cells cannot
84    * contain strings (at least according to our model).  Client apps should do the
85    * conversions themselves.  Formula cells are treated like string cells, simply
86    * containing a formula string.  They'll be rendered differently.
87    * <p>
88    * Cells should have their number (0 based) before being added to a row.  Only
89    * cells that have values should be added.
90    * <p>
91    * NOTE: the alpha won't be implementing formulas
92    *
93    * @author  Andrew C. Oliver (acoliver at apache dot org)
94    * @version 1.0-pre
95    */
96   
97   public class HSSFCell
98   {
99   
100      /**
101       * Numeric Cell type (0)
102       * @see #setCellType(int)
103       * @see #getCellType()
104       */
105  
106      public final static int          CELL_TYPE_NUMERIC           = 0;
107  
108      /**
109       * String Cell type (1)
110       * @see #setCellType(int)
111       * @see #getCellType()
112       */
113  
114      public final static int          CELL_TYPE_STRING            = 1;
115  
116      /**
117       * Formula Cell type (2)
118       * @see #setCellType(int)
119       * @see #getCellType()
120       */
121  
122      public final static int          CELL_TYPE_FORMULA           = 2;
123  
124      /**
125       * Blank Cell type (3)
126       * @see #setCellType(int)
127       * @see #getCellType()
128       */
129  
130      public final static int          CELL_TYPE_BLANK             = 3;
131  
132      /**
133       * Boolean Cell type (4)
134       * @see #setCellType(int)
135       * @see #getCellType()
136       */
137  
138      public final static int          CELL_TYPE_BOOLEAN           = 4;
139  
140      /**
141       * Error Cell type (5)
142       * @see #setCellType(int)
143       * @see #getCellType()
144       */
145  
146      public final static int          CELL_TYPE_ERROR             = 5;
147      public final static short        ENCODING_COMPRESSED_UNICODE = 0;
148      public final static short        ENCODING_UTF_16             = 1;
149      private short                    cellNum;
150      private int                      cellType;
151      private HSSFCellStyle            cellStyle;
152      private double                   cellValue;
153      private String                   stringValue;
154      private boolean                  booleanValue;
155      private byte                     errorValue;
156      private short                    encoding;
157      private Workbook                 book;
158      private Sheet                    sheet;
159      //private short                    row;
160      private int                    row;
161      private CellValueRecordInterface record;
162  
163      /**
164       * Creates new Cell - Should only be called by HSSFRow.  This creates a cell
165       * from scratch.
166       * <p>
167       * When the cell is initially created it is set to CELL_TYPE_BLANK. Cell types
168       * can be changed/overwritten by calling setCellValue with the appropriate
169       * type as a parameter although conversions from one type to another may be
170       * prohibited.
171       *
172       * @param book - Workbook record of the workbook containing this cell
173       * @param sheet - Sheet record of the sheet containing this cell
174       * @param row   - the row of this cell
175       * @param col   - the column for this cell
176       *
177       * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short)
178       */
179  
180      //protected HSSFCell(Workbook book, Sheet sheet, short row, short col)
181      protected HSSFCell(Workbook book, Sheet sheet, int row, short col)
182      {
183          cellNum      = col;
184          this.row     = row;
185          cellStyle    = null;
186          cellValue    = 0;
187          stringValue  = null;
188          booleanValue = false;
189          errorValue   = ( byte ) 0;
190          this.book    = book;
191          this.sheet   = sheet;
192  
193          // Relying on the fact that by default the cellType is set to 0 which
194          // is different to CELL_TYPE_BLANK hence the following method call correctly
195          // creates a new blank cell.
196          setCellType(CELL_TYPE_BLANK, false);
197          ExtendedFormatRecord xf = book.getExFormatAt(0xf);
198  
199          setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
200      }
201  
202      /**
203       * Creates new Cell - Should only be called by HSSFRow.  This creates a cell
204       * from scratch.
205       *
206       * @param book - Workbook record of the workbook containing this cell
207       * @param sheet - Sheet record of the sheet containing this cell
208       * @param row   - the row of this cell
209       * @param col   - the column for this cell
210       * @param type  - CELL_TYPE_NUMERIC, CELL_TYPE_STRING, CELL_TYPE_FORMULA, CELL_TYPE_BLANK,
211       *                CELL_TYPE_BOOLEAN, CELL_TYPE_ERROR
212       *                Type of cell
213       * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short,int)
214       * @deprecated As of 22-Jan-2002 use @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short)
215       * and use setCellValue to specify the type lazily.
216       */
217  
218      //protected HSSFCell(Workbook book, Sheet sheet, short row, short col,
219      protected HSSFCell(Workbook book, Sheet sheet, int row, short col,
220                         int type)
221      {
222          cellNum      = col;
223          this.row     = row;
224          cellType     = type;
225          cellStyle    = null;
226          cellValue    = 0;
227          stringValue  = null;
228          booleanValue = false;
229          errorValue   = ( byte ) 0;
230          this.book    = book;
231          this.sheet   = sheet;
232          switch (type)
233          {
234  
235              case CELL_TYPE_NUMERIC :
236                  record = new NumberRecord();
237                  (( NumberRecord ) record).setColumn(col);
238                  (( NumberRecord ) record).setRow(row);
239                  (( NumberRecord ) record).setValue(( short ) 0);
240                  (( NumberRecord ) record).setXFIndex(( short ) 0);
241                  break;
242  
243              case CELL_TYPE_STRING :
244                  record = new LabelSSTRecord();
245                  (( LabelSSTRecord ) record).setColumn(col);
246                  (( LabelSSTRecord ) record).setRow(row);
247                  (( LabelSSTRecord ) record).setXFIndex(( short ) 0);
248                  break;
249  
250              case CELL_TYPE_BLANK :
251                  record = new BlankRecord();
252                  (( BlankRecord ) record).setColumn(col);
253                  (( BlankRecord ) record).setRow(row);
254                  (( BlankRecord ) record).setXFIndex(( short ) 0);
255                  break;
256  
257              case CELL_TYPE_FORMULA :
258                  record = new FormulaRecord();
259                  (( FormulaRecord ) record).setColumn(col);
260                  (( FormulaRecord ) record).setRow(row);
261                  (( FormulaRecord ) record).setXFIndex(( short ) 0);
262              case CELL_TYPE_BOOLEAN :
263                  record = new BoolErrRecord();
264                  (( BoolErrRecord ) record).setColumn(col);
265                  (( BoolErrRecord ) record).setRow(row);
266                  (( BoolErrRecord ) record).setXFIndex(( short ) 0);
267                  (( BoolErrRecord ) record).setValue(false);
268                  break;
269  
270              case CELL_TYPE_ERROR :
271                  record = new BoolErrRecord();
272                  (( BoolErrRecord ) record).setColumn(col);
273                  (( BoolErrRecord ) record).setRow(row);
274                  (( BoolErrRecord ) record).setXFIndex(( short ) 0);
275                  (( BoolErrRecord ) record).setValue(( byte ) 0);
276                  break;
277          }
278          ExtendedFormatRecord xf = book.getExFormatAt(0xf);
279  
280          setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
281      }
282  
283      /**
284       * Creates an HSSFCell from a CellValueRecordInterface.  HSSFSheet uses this when
285       * reading in cells from an existing sheet.
286       *
287       * @param book - Workbook record of the workbook containing this cell
288       * @param sheet - Sheet record of the sheet containing this cell
289       * @param cval - the Cell Value Record we wish to represent
290       */
291  
292      //protected HSSFCell(Workbook book, Sheet sheet, short row,
293      protected HSSFCell(Workbook book, Sheet sheet, int row,
294                         CellValueRecordInterface cval)
295      {
296          cellNum     = cval.getColumn();
297          record      = cval;
298          this.row    = row;
299          cellType    = determineType(cval);
300          cellStyle   = null;
301          stringValue = null;
302          this.book   = book;
303          this.sheet  = sheet;
304          switch (cellType)
305          {
306  
307              case CELL_TYPE_NUMERIC :
308                  cellValue = (( NumberRecord ) cval).getValue();
309                  break;
310  
311              case CELL_TYPE_STRING :
312                  stringValue =
313                      book
314                      .getSSTString((( LabelSSTRecord ) cval).getSSTIndex());
315                  break;
316  
317              case CELL_TYPE_BLANK :
318                  break;
319  
320              case CELL_TYPE_FORMULA :
321                  cellValue = (( FormulaRecord ) cval).getValue();
322                  break;
323  
324              case CELL_TYPE_BOOLEAN :
325                  booleanValue = (( BoolErrRecord ) cval).getBooleanValue();
326                  break;
327  
328              case CELL_TYPE_ERROR :
329                  errorValue = (( BoolErrRecord ) cval).getErrorValue();
330                  break;
331          }
332          ExtendedFormatRecord xf = book.getExFormatAt(cval.getXFIndex());
333  
334          setCellStyle(new HSSFCellStyle(( short ) cval.getXFIndex(), xf));
335      }
336  
337      /**
338       * private constructor to prevent blank construction
339       */
340      private HSSFCell()
341      {
342      }
343  
344      /**
345       * used internally -- given a cell value record, figure out its type
346       */
347      private int determineType(CellValueRecordInterface cval)
348      {
349          Record record = ( Record ) cval;
350          int    sid    = record.getSid();
351          int    retval = 0;
352  
353          switch (sid)
354          {
355  
356              case NumberRecord.sid :
357                  retval = HSSFCell.CELL_TYPE_NUMERIC;
358                  break;
359  
360              case BlankRecord.sid :
361                  retval = HSSFCell.CELL_TYPE_BLANK;
362                  break;
363  
364              case LabelSSTRecord.sid :
365                  retval = HSSFCell.CELL_TYPE_STRING;
366                  break;
367  
368              case FormulaRecord.sid :
369                  retval = HSSFCell.CELL_TYPE_FORMULA;
370                  break;
371  
372              case BoolErrRecord.sid :
373                  BoolErrRecord boolErrRecord = ( BoolErrRecord ) record;
374  
375                  retval = (boolErrRecord.isBoolean())
376                           ? HSSFCell.CELL_TYPE_BOOLEAN
377                           : HSSFCell.CELL_TYPE_ERROR;
378                  break;
379          }
380          return retval;
381      }
382  
383      /**
384       * set the cell's number within the row (0 based)
385       * @param num  short the cell number
386       */
387  
388      public void setCellNum(short num)
389      {
390          cellNum = num;
391          record.setColumn(num);
392      }
393  
394      /**
395       *  get the cell's number within the row
396       * @return short reperesenting the column number (logical!)
397       */
398  
399      public short getCellNum()
400      {
401          return cellNum;
402      }
403  
404      /**
405       * set the cells type (numeric, formula or string) -- DONT USE FORMULAS IN THIS RELEASE
406       * WE'LL THROW YOU A RUNTIME EXCEPTION IF YOU DO
407       * @see #CELL_TYPE_NUMERIC
408       * @see #CELL_TYPE_STRING
409       * @see #CELL_TYPE_FORMULA
410       * @see #CELL_TYPE_BLANK
411       * @see #CELL_TYPE_BOOLEAN
412       * @see #CELL_TYPE_ERROR
413       */
414  
415      public void setCellType(int cellType)
416      {
417          setCellType(cellType, true);
418      }
419  
420      /**
421       * sets the cell type. The setValue flag indicates whether to bother about
422       *  trying to preserve the current value in the new record if one is created.
423       *  <p>
424       *  The @see #setCellValue method will call this method with false in setValue
425       *  since it will overwrite the cell value later
426       *
427       */
428  
429      private void setCellType(int cellType, boolean setValue)
430      {
431  
432          // if (cellType == CELL_TYPE_FORMULA)
433          // {
434          // throw new RuntimeException(
435          // "Formulas have not been implemented in this release");
436          // }
437          if (cellType > CELL_TYPE_ERROR)
438          {
439              throw new RuntimeException("I have no idea what type that is!");
440          }
441          switch (cellType)
442          {
443  
444              case CELL_TYPE_FORMULA :
445                  FormulaRecord frec = null;
446  
447                  if (cellType != this.cellType)
448                  {
449                      frec = new FormulaRecord();
450                  }
451                  else
452                  {
453                      frec = ( FormulaRecord ) record;
454                  }
455                  frec.setColumn(getCellNum());
456                  if (setValue)
457                  {
458                      frec.setValue(getNumericCellValue());
459                  }
460                  frec.setXFIndex(( short ) cellStyle.getIndex());
461                  frec.setRow(row);
462                  record = frec;
463                  break;
464  
465              case CELL_TYPE_NUMERIC :
466                  NumberRecord nrec = null;
467  
468                  if (cellType != this.cellType)
469                  {
470                      nrec = new NumberRecord();
471                  }
472                  else
473                  {
474                      nrec = ( NumberRecord ) record;
475                  }
476                  nrec.setColumn(getCellNum());
477                  if (setValue)
478                  {
479                      nrec.setValue(getNumericCellValue());
480                  }
481                  nrec.setXFIndex(( short ) cellStyle.getIndex());
482                  nrec.setRow(row);
483                  record = nrec;
484                  break;
485  
486              case CELL_TYPE_STRING :
487                  LabelSSTRecord lrec = null;
488  
489                  if (cellType != this.cellType)
490                  {
491                      lrec = new LabelSSTRecord();
492                  }
493                  else
494                  {
495                      lrec = ( LabelSSTRecord ) record;
496                  }
497                  lrec.setColumn(getCellNum());
498                  lrec.setRow(row);
499                  lrec.setXFIndex(( short ) cellStyle.getIndex());
500                  if (setValue)
501                  {
502                      if ((getStringCellValue() != null)
503                              && (!getStringCellValue().equals("")))
504                      {
505                          int sst = 0;
506  
507                          if (encoding == ENCODING_COMPRESSED_UNICODE)
508                          {
509                              sst = book.addSSTString(getStringCellValue());
510                          }
511                          if (encoding == ENCODING_UTF_16)
512                          {
513                              sst = book.addSSTString(getStringCellValue(),
514                                                      true);
515                          }
516                          lrec.setSSTIndex(sst);
517                      }
518                  }
519                  record = lrec;
520                  break;
521  
522              case CELL_TYPE_BLANK :
523                  BlankRecord brec = null;
524  
525                  if (cellType != this.cellType)
526                  {
527                      brec = new BlankRecord();
528                  }
529                  else
530                  {
531                      brec = ( BlankRecord ) record;
532                  }
533                  brec.setColumn(getCellNum());
534  
535                  // During construction the cellStyle may be null for a Blank cell.
536                  if (cellStyle != null)
537                  {
538                      brec.setXFIndex(( short ) cellStyle.getIndex());
539                  }
540                  else
541                  {
542                      brec.setXFIndex(( short ) 0);
543                  }
544                  brec.setRow(row);
545                  record = brec;
546                  break;
547  
548              case CELL_TYPE_BOOLEAN :
549                  BoolErrRecord boolRec = null;
550  
551                  if (cellType != this.cellType)
552                  {
553                      boolRec = new BoolErrRecord();
554                  }
555                  else
556                  {
557                      boolRec = ( BoolErrRecord ) record;
558                  }
559                  boolRec.setColumn(getCellNum());
560                  if (setValue)
561                  {
562                      boolRec.setValue(getBooleanCellValue());
563                  }
564                  boolRec.setXFIndex(( short ) cellStyle.getIndex());
565                  boolRec.setRow(row);
566                  record = boolRec;
567                  break;
568  
569              case CELL_TYPE_ERROR :
570                  BoolErrRecord errRec = null;
571  
572                  if (cellType != this.cellType)
573                  {
574                      errRec = new BoolErrRecord();
575                  }
576                  else
577                  {
578                      errRec = ( BoolErrRecord ) record;
579                  }
580                  errRec.setColumn(getCellNum());
581                  if (setValue)
582                  {
583                      errRec.setValue(getErrorCellValue());
584                  }
585                  errRec.setXFIndex(( short ) cellStyle.getIndex());
586                  errRec.setRow(row);
587                  record = errRec;
588                  break;
589          }
590          if (cellType != this.cellType)
591          {
592              int loc = sheet.getLoc();
593  
594              sheet.replaceValueRecord(record);
595              sheet.setLoc(loc);
596          }
597          this.cellType = cellType;
598      }
599  
600      /**
601       * get the cells type (numeric, formula or string)
602       * @see #CELL_TYPE_STRING
603       * @see #CELL_TYPE_NUMERIC
604       * @see #CELL_TYPE_FORMULA
605       * @see #CELL_TYPE_BOOLEAN
606       * @see #CELL_TYPE_ERROR
607       */
608  
609      public int getCellType()
610      {
611          return cellType;
612      }
613  
614      /**
615       * set a numeric value for the cell
616       *
617       * @param value  the numeric value to set this cell to.  For formulas we'll set the
618       *        precalculated value, for numerics we'll set its value. For other types we
619       *        will change the cell to a numeric cell and set its value.
620       */
621      public void setCellValue(double value)
622      {
623          if ((cellType != CELL_TYPE_NUMERIC) && (cellType != CELL_TYPE_FORMULA))
624          {
625              setCellType(CELL_TYPE_NUMERIC, false);
626          }
627          (( NumberRecord ) record).setValue(value);
628          cellValue = value;
629      }
630  
631      /**
632       * set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as
633       * a date.
634       *
635       * @param value  the date value to set this cell to.  For formulas we'll set the
636       *        precalculated value, for numerics we'll set its value. For other types we
637       *        will change the cell to a numeric cell and set its value.
638       */
639      public void setCellValue(Date value)
640      {
641          setCellValue(HSSFDateUtil.getExcelDate(value));
642      }
643  
644      /**
645       * set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as
646       * a date.
647       *
648       * @param value  the date value to set this cell to.  For formulas we'll set the
649       *        precalculated value, for numerics we'll set its value. For othertypes we
650       *        will change the cell to a numeric cell and set its value.
651       */
652      public void setCellValue(Calendar value)
653      {
654          setCellValue(value.getTime());
655      }
656  
657      /**
658       * set a string value for the cell.
659       *
660       * @param value  value to set the cell to.  For formulas we'll set the formula
661       * string, for String cells we'll set its value.  For other types we will
662       * change the cell to a string cell and set its value.
663       * If value is null then we will change the cell to a Blank cell.
664       */
665  
666      public void setCellValue(String value)
667      {
668          if (value == null)
669          {
670              setCellType(CELL_TYPE_BLANK, false);
671          }
672          else
673          {
674              if ((cellType != CELL_TYPE_STRING)
675                      && (cellType != CELL_TYPE_FORMULA))
676              {
677                  setCellType(CELL_TYPE_STRING, false);
678              }
679              int index = 0;
680  
681              if (encoding == ENCODING_COMPRESSED_UNICODE)
682              {
683                  index = book.addSSTString(value);
684              }
685              if (encoding == ENCODING_UTF_16)
686              {
687                  index = book.addSSTString(value, true);
688              }
689              (( LabelSSTRecord ) record).setSSTIndex(index);
690              stringValue = value;
691          }
692      }
693  
694      public void setCellFormula(String formula) {
695          if (formula==null) {
696              setCellType(CELL_TYPE_BLANK,false);
697          } else {
698              
699              setCellType(CELL_TYPE_FORMULA,false);
700              FormulaRecord rec = (FormulaRecord) record;
701              rec.setOptions(( short ) 2);
702              rec.setValue(0);
703              rec.setXFIndex(( short ) 0x0f);
704              FormulaParser fp = new FormulaParser(formula+";");
705              fp.parse();
706              Ptg[] ptg  = fp.getRPNPtg();
707              int   size = 0;
708              //System.out.println("got Ptgs " + ptg.length);
709              for (int k = 0; k < ptg.length; k++) {
710                  size += ptg[ k ].getSize();
711                  rec.pushExpressionToken(ptg[ k ]);
712              }
713              rec.setExpressionLength(( short ) size);
714              //return rec;
715              
716          }
717      }
718      
719      public String getCellFormula() {
720          String retval=null;
721          
722          retval = 
723                FormulaParser.toFormulaString(((FormulaRecord)record).getParsedExpression());
724          
725          return retval;   
726      }
727      
728      
729      /**
730       * get the value of the cell as a number.  For strings we throw an exception.
731       * For blank cells we return a 0.
732       */
733  
734      public double getNumericCellValue()
735      {
736          if (cellType == CELL_TYPE_BLANK)
737          {
738              return 0;
739          }
740          if (cellType == CELL_TYPE_STRING)
741          {
742              throw new NumberFormatException(
743                  "You cannot get a numeric value from a String based cell");
744          }
745          if (cellType == CELL_TYPE_BOOLEAN)
746          {
747              throw new NumberFormatException(
748                  "You cannot get a numeric value from a boolean cell");
749          }
750          if (cellType == CELL_TYPE_ERROR)
751          {
752              throw new NumberFormatException(
753                  "You cannot get a numeric value from an error cell");
754          }
755          return cellValue;
756      }
757  
758      /**
759       * get the value of the cell as a date.  For strings we throw an exception.
760       * For blank cells we return a null.
761       */
762      public Date getDateCellValue()
763      {
764          if (cellType == CELL_TYPE_BLANK)
765          {
766              return null;
767          }
768          if (cellType == CELL_TYPE_STRING)
769          {
770              throw new NumberFormatException(
771                  "You cannot get a date value from a String based cell");
772          }
773          if (cellType == CELL_TYPE_BOOLEAN)
774          {
775              throw new NumberFormatException(
776                  "You cannot get a date value from a boolean cell");
777          }
778          if (cellType == CELL_TYPE_ERROR)
779          {
780              throw new NumberFormatException(
781                  "You cannot get a date value from an error cell");
782          }
783          return HSSFDateUtil.getJavaDate(cellValue);
784      }
785  
786      /**
787       * get the value of the cell as a string - for numeric cells we throw an exception.
788       * For blank cells we return an empty string.
789       */
790  
791      public String getStringCellValue()
792      {
793          if (cellType == CELL_TYPE_BLANK)
794          {
795              return "";
796          }
797          if (cellType == CELL_TYPE_NUMERIC)
798          {
799              throw new NumberFormatException(
800                  "You cannot get a string value from a numeric cell");
801          }
802          if (cellType == CELL_TYPE_BOOLEAN)
803          {
804              throw new NumberFormatException(
805                  "You cannot get a string value from a boolean cell");
806          }
807          if (cellType == CELL_TYPE_ERROR)
808          {
809              throw new NumberFormatException(
810                  "You cannot get a string value from an error cell");
811          }
812          return stringValue;
813      }
814  
815      /**
816       * set a boolean value for the cell
817       *
818       * @param value the boolean value to set this cell to.  For formulas we'll set the
819       *        precalculated value, for booleans we'll set its value. For other types we
820       *        will change the cell to a boolean cell and set its value.
821       */
822  
823      public void setCellValue(boolean value)
824      {
825          if ((cellType != CELL_TYPE_BOOLEAN)
826                  && (cellType != CELL_TYPE_FORMULA))
827          {
828              setCellType(CELL_TYPE_BOOLEAN, false);
829          }
830          (( BoolErrRecord ) record).setValue(value);
831          booleanValue = value;
832      }
833  
834      /**
835       * set a error value for the cell
836       *
837       * @param value the error value to set this cell to.  For formulas we'll set the
838       *        precalculated value ??? IS THIS RIGHT??? , for errors we'll set
839       *        its value. For other types we will change the cell to an error
840       *        cell and set its value.
841       */
842  
843      public void setCellErrorValue(byte value)
844      {
845          if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA))
846          {
847              setCellType(CELL_TYPE_ERROR, false);
848          }
849          (( BoolErrRecord ) record).setValue(value);
850          errorValue = value;
851      }
852  
853      /**
854       * get the value of the cell as a boolean.  For strings, numbers, and errors, we throw an exception.
855       * For blank cells we return a false.
856       */
857  
858      public boolean getBooleanCellValue()
859      {
860          if (cellType == CELL_TYPE_BOOLEAN)
861          {
862              return booleanValue;
863          }
864          if (cellType == CELL_TYPE_BLANK)
865          {
866              return false;
867          }
868          throw new NumberFormatException(
869              "You cannot get a boolean value from a non-boolean cell");
870      }
871  
872      /**
873       * get the value of the cell as an error code.  For strings, numbers, and booleans, we throw an exception.
874       * For blank cells we return a 0.
875       */
876  
877      public byte getErrorCellValue()
878      {
879          if (cellType == CELL_TYPE_ERROR)
880          {
881              return errorValue;
882          }
883          if (cellType == CELL_TYPE_BLANK)
884          {
885              return ( byte ) 0;
886          }
887          throw new NumberFormatException(
888              "You cannot get an error value from a non-error cell");
889      }
890  
891      /**
892       * set the style for the cell.  The style should be an HSSFCellStyle created/retreived from
893       * the HSSFWorkbook.
894       *
895       * @param style  reference contained in the workbook
896       * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createCellStyle()
897       * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
898       */
899  
900      public void setCellStyle(HSSFCellStyle style)
901      {
902          cellStyle = style;
903          record.setXFIndex(style.getIndex());
904      }
905  
906      /**
907       * get the style for the cell.  This is a reference to a cell style contained in the workbook
908       * object.
909       * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
910       */
911  
912      public HSSFCellStyle getCellStyle()
913      {
914          return cellStyle;
915      }
916  
917      /**
918       * used for internationalization, currently 0 for compressed unicode or 1 for 16-bit
919       *
920       * @see #ENCODING_COMPRESSED_UNICODE
921       * @see #ENCODING_UTF_16
922       *
923       * @return 1 or 0 for compressed or uncompressed (used only with String type)
924       */
925  
926      public short getEncoding()
927      {
928          return encoding;
929      }
930  
931      /**
932       * set the encoding to either 8 or 16 bit. (US/UK use 8-bit, rest of the western world use 16bit)
933       *
934       * @see #ENCODING_COMPRESSED_UNICODE
935       * @see #ENCODING_UTF_16
936       *
937       * @param encoding either ENCODING_COMPRESSED_UNICODE (0) or ENCODING_UTF_16 (1)
938       */
939  
940      public void setEncoding(short encoding)
941      {
942          this.encoding = encoding;
943      }
944  
945      /**
946       * Should only be used by HSSFSheet and friends.  Returns the low level CellValueRecordInterface record
947       *
948       * @return CellValueRecordInterface representing the cell via the low level api.
949       */
950  
951      protected CellValueRecordInterface getCellValueRecord()
952      {
953          return record;
954      }
955  }
956  ??????????????????????getSSTString??????????????????????????????????????LabelSSTRecord???????????????????????????????????????????????????????cval??????????????????CELL_TYPE_BLANK??????????????????CELL_TYPE_FORMULA?????????????????cellValue????????????????????????????????FormulaRecord????????????????????????????????????????????????cval??????????????????CELL_TYPE_BOOLEAN?????????????????booleanValue???????????????????????????????????BoolErrRecord???????????????????????????????????????????????????cval??????????????????CELL_TYPE_ERROR?????????????????errorValue?????????????????????????????????BoolErrRecord?????????????????????????????????????????????????cval?????????ExtendedFormatRecord???????????????????????????????????book????????????????????????????????????????getExFormatAt??????????????????????????????????????????????????????cval???????????????????????????????????????????????????????????getXFIndex?????????setCellStyle??????????????????????????HSSFCellStyle??????????????????????????????????????????????????cval???????????????????????????????????????????????????????getXFIndex?????????????????????????????????????????????????????????????????????xf??????????????????????????????????????????????????????????????????????????????????????HSSFCell??????????????????????????????????????????????????????????????????????????????????????????????????????????determineType???????????????????????????????CellValueRecordInterface?????????Record???????????????????????????Record????????????????????????????????????cval?????????????????????????record?????????????????sid??????????????????NumberRecord???????????????????????????????sid?????????????????retval??????????????????????????HSSFCell???????????????????????????????????CELL_TYPE_NUMERIC??????????????????BlankRecord??????????????????????????????sid?????????????????retval??????????????????????????HSSFCell???????????????????????????????????CELL_TYPE_BLANK??????????????????LabelSSTRecord?????????????????????????????????sid?????????????????retval??????????????????????????HSSFCell???????????????????????????????????CELL_TYPE_STRING??????????????????FormulaRecord????????????????????????????????sid?????????????????retval??????????????????????????HSSFCell???????????????????????????????????CELL_TYPE_FORMULA??????????????????BoolErrRecord????????????????????????????????sid?????????????????BoolErrRecord?????????????????????????????????????????????????BoolErrRecord?????????????????????????????????????????????????????????????????record?????????????????retval???????????????????????????boolErrRecord?????????????????????????????????????????isBoolean????????????????????????????HSSFCell?????????????????????????????????????CELL_TYPE_BOOLEAN????????????????????????????HSSFCell?????????????????????????????????????CELL_TYPE_ERROR????????????????retval????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellNum?????????cellNum???????????????????num?????????record????????????????setColumn??????????????????????????num???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getCellNum???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellType?????????setCellType?????????????????????cellType??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellType??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????cellType????????????????????????CELL_TYPE_ERROR?????????????????cellType??????????????????CELL_TYPE_FORMULA?????????????????FormulaRecord?????????????????????cellType?????????????????????frec????????????????????????????????FormulaRecord?????????????????????frec??????????????????????????????FormulaRecord??????????????????????????????????????????????record?????????????????frec??????????????????????setColumn????????????????????????????????getCellNum?????????????????????setValue?????????????????????frec??????????????????????????setValue???????????????????????????????????getNumericCellValue?????????????????frec??????????????????????setXFIndex???????????????????????????????????????????cellStyle?????????????????????????????????????????????????????getIndex?????????????????frec??????????????????????setRow?????????????????????????????row?????????????????record??????????????????????????frec??????????????????CELL_TYPE_NUMERIC?????????????????NumberRecord?????????????????????cellType?????????????????????nrec????????????????????????????????NumberRecord?????????????????????nrec??????????????????????????????NumberRecord?????????????????????????????????????????????record?????????????????nrec??????????????????????setColumn????????????????????????????????getCellNum?????????????????????setValue?????????????????????nrec??????????????????????????setValue???????????????????????????????????getNumericCellValue?????????????????nrec??????????????????????setXFIndex???????????????????????????????????????????cellStyle?????????????????????????????????????????????????????getIndex?????????????????nrec??????????????????????setRow?????????????????????????????row?????????????????record??????????????????????????nrec??????????????????CELL_TYPE_STRING?????????????????LabelSSTRecord?????????????????????cellType?????????????????????lrec????????????????????????????????LabelSSTRecord?????????????????????lrec??????????????????????????????LabelSSTRecord???????????????????????????????????????????????record?????????????????lrec??????????????????????setColumn????????????????????????????????getCellNum?????????????????lrec??????????????????????setRow?????????????????????????????row?????????????????lrec??????????????????????setXFIndex???????????????????????????????????????????cellStyle?????????????????????????????????????????????????????getIndex?????????????????????setValue??????????????????????????getStringCellValue??????????????????????????????????getStringCellValue?????????????????????????????encoding?????????????????????????????????????????ENCODING_COMPRESSED_UNICODE?????????????????????????????sst???????????????????????????????????book????????????????????????????????????????addSSTString?????????????????????????????????????????????????????getStringCellValue?????????????????????????????encoding?????????????????????????????????????????ENCODING_UTF_16?????????????????????????????sst???????????????????????????????????book????????????????????????????????????????addSSTString?????????????????????????????????????????????????????getStringCellValue?????????????????????????lrec??????????????????????????????setSSTIndex??????????????????????????????????????????sst?????????????????record??????????????????????????lrec??????????????????CELL_TYPE_BLANK?????????????????BlankRecord?????????????????????cellType?????????????????????brec????????????????????????????????BlankRecord?????????????????????brec??????????????????????????????BlankRecord????????????????????????????????????????????record?????????????????brec??????????????????????setColumn????????????????????????????????getCellNum????????????????????????????????????????????????????????????????????????????????????????????????????????cellStyle?????????????????????brec??????????????????????????setXFIndex???????????????????????????????????????????????cellStyle?????????????????????????????????????????????????????????getIndex?????????????????????brec??????????????????????????setXFIndex?????????????????brec??????????????????????setRow?????????????????????????????row?????????????????record??????????????????????????brec??????????????????CELL_TYPE_BOOLEAN?????????????????BoolErrRecord?????????????????????cellType?????????????????????boolRec???????????????????????????????????BoolErrRecord?????????????????????boolRec?????????????????????????????????BoolErrRecord?????????????????????????????????????????????????record?????????????????boolRec?????????????????????????setColumn???????????????????????????????????getCellNum?????????????????????setValue?????????????????????boolRec?????????????????????????????setValue??????????????????????????????????????getBooleanCellValue?????????????????boolRec?????????????????????????setXFIndex??????????????????????????????????????????????cellStyle????????????????????????????????????????????????????????getIndex?????????????????boolRec?????????????????????????setRow????????????????????????????????row?????????????????record??????????????????????????boolRec??????????????????CELL_TYPE_ERROR?????????????????BoolErrRecord?????????????????????cellType?????????????????????errRec??????????????????????????????????BoolErrRecord?????????????????????errRec????????????????????????????????BoolErrRecord????????????????????????????????????????????????record?????????????????errRec????????????????????????setColumn??????????????????????????????????getCellNum?????????????????????setValue?????????????????????errRec????????????????????????????setValue?????????????????????????????????????getErrorCellValue?????????????????errRec????????????????????????setXFIndex?????????????????????????????????????????????cellStyle???????????????????????????????????????????????????????getIndex?????????????????errRec????????????????????????setRow???????????????????????????????row?????????????????record??????????????????????????errRec?????????????cellType???????????????????????sheet?????????????????????????????getLoc?????????????sheet???????????????????replaceValueRecord??????????????????????????????????????record?????????????sheet???????????????????setLoc??????????????????????????loc?????????????????????????cellType???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getCellType????????????????cellType????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellValue??????????????cellType??????????????????????????CELL_TYPE_NUMERIC?????????????????????????????????????????????????cellType?????????????????????????????????????????????????????????????CELL_TYPE_FORMULA?????????????setCellType?????????????????????????CELL_TYPE_NUMERIC????????????NumberRecord???????????????????????????record????????????????????????????????????????????value?????????cellValue?????????????????????value???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellValue?????????setCellValue??????????????????????HSSFDateUtil???????????????????????????????????getExcelDate????????????????????????????????????????????????value??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellValue?????????setCellValue??????????????????????value??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellValue?????????????value?????????????setCellType?????????????????????????CELL_TYPE_BLANK??????????????????cellType??????????????????????????????CELL_TYPE_STRING?????????????????????????cellType?????????????????????????????????????CELL_TYPE_FORMULA?????????????????setCellType?????????????????????????????CELL_TYPE_STRING?????????????????encoding?????????????????????????????ENCODING_COMPRESSED_UNICODE?????????????????index?????????????????????????book??????????????????????????????addSSTString???????????????????????????????????????????value?????????????????encoding?????????????????????????????ENCODING_UTF_16?????????????????index?????????????????????????book??????????????????????????????addSSTString???????????????????????????????????????????value????????????????LabelSSTRecord?????????????????????????????????record?????????????????????????????????????????????????????index?????????????stringValue???????????????????????????value?????????????????setCellFormula?????????????formula?????????????setCellType?????????????????????????CELL_TYPE_BLANK?????????????setCellType?????????????????????????CELL_TYPE_FORMULA?????????????FormulaRecord??????????????????????????????????FormulaRecord?????????????????????????????????????????????????record?????????????rec?????????????????setOptions?????????????rec?????????????????setValue?????????????rec?????????????????setXFIndex?????????????FormulaParser????????????????????????????????????FormulaParser??????????????????????????????????????????????????formula?????????????fp????????????????parse?????????????Ptg??????????????????????????fp?????????????????????????????getRPNPtg?????????????????????????????????????????????????????????????????????????????????????????k?????????????????????????????????ptg?????????????????????????????????????????????k?????????????????size?????????????????????????ptg??????????????????????????????k??????????????????????????????????getSize?????????????????rec?????????????????????pushExpressionToken?????????????????????????????????????????ptg??????????????????????????????????????????????k?????????????rec?????????????????setExpressionLength???????????????????????????????????????????????size?????????????????????????????????????????????getCellFormula?????????retval???????????????FormulaParser?????????????????????????????toFormulaString???????????????????????????????????????????????FormulaRecord?????????????????????????????????????????????????????????????record????????????????retval???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getNumericCellValue?????????????cellType?????????????????????????CELL_TYPE_BLANK?????????????cellType?????????????????????????CELL_TYPE_STRING?????????????cellType?????????????????????????CELL_TYPE_BOOLEAN?????????????cellType?????????????????????????CELL_TYPE_ERROR????????????????cellValue??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getDateCellValue?????????????cellType?????????????????????????CELL_TYPE_BLANK?????????????cellType?????????????????????????CELL_TYPE_STRING?????????????cellType?????????????????????????CELL_TYPE_BOOLEAN?????????????cellType?????????????????????????CELL_TYPE_ERROR????????????????HSSFDateUtil?????????????????????????????getJavaDate?????????????????????????????????????????cellValue?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getStringCellValue?????????????cellType?????????????????????????CELL_TYPE_BLANK?????????????cellType?????????????????????????CELL_TYPE_NUMERIC?????????????cellType?????????????????????????CELL_TYPE_BOOLEAN?????????????cellType?????????????????????????CELL_TYPE_ERROR????????????????stringValue???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellValue??????????????cellType??????????????????????????CELL_TYPE_BOOLEAN?????????????????????cellType?????????????????????????????????CELL_TYPE_FORMULA?????????????setCellType?????????????????????????CELL_TYPE_BOOLEAN????????????BoolErrRecord????????????????????????????record?????????????????????????????????????????????value?????????booleanValue????????????????????????value????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellErrorValue??????????????cellType??????????????????????????CELL_TYPE_ERROR???????????????????????????????????????????????cellType???????????????????????????????????????????????????????????CELL_TYPE_FORMULA?????????????setCellType?????????????????????????CELL_TYPE_ERROR????????????BoolErrRecord????????????????????????????record?????????????????????????????????????????????value?????????errorValue??????????????????????value???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getBooleanCellValue?????????????cellType?????????????????????????CELL_TYPE_BOOLEAN????????????????????booleanValue?????????????cellType?????????????????????????CELL_TYPE_BLANK??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getErrorCellValue?????????????cellType?????????????????????????CELL_TYPE_ERROR????????????????????errorValue?????????????cellType?????????????????????????CELL_TYPE_BLANK????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setCellStyle??????????????????????????????HSSFCellStyle?????????cellStyle?????????????????????style?????????record????????????????setXFIndex???????????????????????????style?????????????????????????????????getIndex??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????HSSFCellStyle??????????????????????????getCellStyle????????????????cellStyle?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getEncoding????????????????encoding????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setEncoding?????????????????????????encoding???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????CellValueRecordInterface????????????????????????????????????????getCellValueRecord