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 CellValueRecordInterface record;
161  
162      /**
163       * Creates new Cell - Should only be called by HSSFRow.  This creates a cell
164       * from scratch.
165       * <p>
166       * When the cell is initially created it is set to CELL_TYPE_BLANK. Cell types
167       * can be changed/overwritten by calling setCellValue with the appropriate
168       * type as a parameter although conversions from one type to another may be
169       * prohibited.
170       *
171       * @param book - Workbook record of the workbook containing this cell
172       * @param sheet - Sheet record of the sheet containing this cell
173       * @param row   - the row of this cell
174       * @param col   - the column for this cell
175       *
176       * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short)
177       */
178  
179      protected HSSFCell(Workbook book, Sheet sheet, short row, short col)
180      {
181          cellNum      = col;
182          this.row     = row;
183          cellStyle    = null;
184          cellValue    = 0;
185          stringValue  = null;
186          booleanValue = false;
187          errorValue   = ( byte ) 0;
188          this.book    = book;
189          this.sheet   = sheet;
190  
191          // Relying on the fact that by default the cellType is set to 0 which
192          // is different to CELL_TYPE_BLANK hence the following method call correctly
193          // creates a new blank cell.
194          setCellType(CELL_TYPE_BLANK, false);
195          ExtendedFormatRecord xf = book.getExFormatAt(0xf);
196  
197          setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
198      }
199  
200      /**
201       * Creates new Cell - Should only be called by HSSFRow.  This creates a cell
202       * from scratch.
203       *
204       * @param book - Workbook record of the workbook containing this cell
205       * @param sheet - Sheet record of the sheet containing this cell
206       * @param row   - the row of this cell
207       * @param col   - the column for this cell
208       * @param type  - CELL_TYPE_NUMERIC, CELL_TYPE_STRING, CELL_TYPE_FORMULA, CELL_TYPE_BLANK,
209       *                CELL_TYPE_BOOLEAN, CELL_TYPE_ERROR
210       *                Type of cell
211       * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short,int)
212       * @deprecated As of 22-Jan-2002 use @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short)
213       * and use setCellValue to specify the type lazily.
214       */
215  
216      protected HSSFCell(Workbook book, Sheet sheet, short row, short col,
217                         int type)
218      {
219          cellNum      = col;
220          this.row     = row;
221          cellType     = type;
222          cellStyle    = null;
223          cellValue    = 0;
224          stringValue  = null;
225          booleanValue = false;
226          errorValue   = ( byte ) 0;
227          this.book    = book;
228          this.sheet   = sheet;
229          switch (type)
230          {
231  
232              case CELL_TYPE_NUMERIC :
233                  record = new NumberRecord();
234                  (( NumberRecord ) record).setColumn(col);
235                  (( NumberRecord ) record).setRow(row);
236                  (( NumberRecord ) record).setValue(( short ) 0);
237                  (( NumberRecord ) record).setXFIndex(( short ) 0);
238                  break;
239  
240              case CELL_TYPE_STRING :
241                  record = new LabelSSTRecord();
242                  (( LabelSSTRecord ) record).setColumn(col);
243                  (( LabelSSTRecord ) record).setRow(row);
244                  (( LabelSSTRecord ) record).setXFIndex(( short ) 0);
245                  break;
246  
247              case CELL_TYPE_BLANK :
248                  record = new BlankRecord();
249                  (( BlankRecord ) record).setColumn(col);
250                  (( BlankRecord ) record).setRow(row);
251                  (( BlankRecord ) record).setXFIndex(( short ) 0);
252                  break;
253  
254              case CELL_TYPE_FORMULA :
255                  record = new FormulaRecord();
256                  (( FormulaRecord ) record).setColumn(col);
257                  (( FormulaRecord ) record).setRow(row);
258                  (( FormulaRecord ) record).setXFIndex(( short ) 0);
259              case CELL_TYPE_BOOLEAN :
260                  record = new BoolErrRecord();
261                  (( BoolErrRecord ) record).setColumn(col);
262                  (( BoolErrRecord ) record).setRow(row);
263                  (( BoolErrRecord ) record).setXFIndex(( short ) 0);
264                  (( BoolErrRecord ) record).setValue(false);
265                  break;
266  
267              case CELL_TYPE_ERROR :
268                  record = new BoolErrRecord();
269                  (( BoolErrRecord ) record).setColumn(col);
270                  (( BoolErrRecord ) record).setRow(row);
271                  (( BoolErrRecord ) record).setXFIndex(( short ) 0);
272                  (( BoolErrRecord ) record).setValue(( byte ) 0);
273                  break;
274          }
275          ExtendedFormatRecord xf = book.getExFormatAt(0xf);
276  
277          setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
278      }
279  
280      /**
281       * Creates an HSSFCell from a CellValueRecordInterface.  HSSFSheet uses this when
282       * reading in cells from an existing sheet.
283       *
284       * @param book - Workbook record of the workbook containing this cell
285       * @param sheet - Sheet record of the sheet containing this cell
286       * @param cval - the Cell Value Record we wish to represent
287       */
288  
289      protected HSSFCell(Workbook book, Sheet sheet, short row,
290                         CellValueRecordInterface cval)
291      {
292          cellNum     = cval.getColumn();
293          record      = cval;
294          this.row    = row;
295          cellType    = determineType(cval);
296          cellStyle   = null;
297          stringValue = null;
298          this.book   = book;
299          this.sheet  = sheet;
300          switch (cellType)
301          {
302  
303              case CELL_TYPE_NUMERIC :
304                  cellValue = (( NumberRecord ) cval).getValue();
305                  break;
306  
307              case CELL_TYPE_STRING :
308                  stringValue =
309                      book
310                      .getSSTString((( LabelSSTRecord ) cval).getSSTIndex());
311                  break;
312  
313              case CELL_TYPE_BLANK :
314                  break;
315  
316              case CELL_TYPE_FORMULA :
317                  cellValue = (( FormulaRecord ) cval).getValue();
318                  break;
319  
320              case CELL_TYPE_BOOLEAN :
321                  booleanValue = (( BoolErrRecord ) cval).getBooleanValue();
322                  break;
323  
324              case CELL_TYPE_ERROR :
325                  errorValue = (( BoolErrRecord ) cval).getErrorValue();
326                  break;
327          }
328          ExtendedFormatRecord xf = book.getExFormatAt(cval.getXFIndex());
329  
330          setCellStyle(new HSSFCellStyle(( short ) cval.getXFIndex(), xf));
331      }
332  
333      /**
334       * private constructor to prevent blank construction
335       */
336      private HSSFCell()
337      {
338      }
339  
340      /**
341       * used internally -- given a cell value record, figure out its type
342       */
343      private int determineType(CellValueRecordInterface cval)
344      {
345          Record record = ( Record ) cval;
346          int    sid    = record.getSid();
347          int    retval = 0;
348  
349          switch (sid)
350          {
351  
352              case NumberRecord.sid :
353                  retval = HSSFCell.CELL_TYPE_NUMERIC;
354                  break;
355  
356              case BlankRecord.sid :
357                  retval = HSSFCell.CELL_TYPE_BLANK;
358                  break;
359  
360              case LabelSSTRecord.sid :
361                  retval = HSSFCell.CELL_TYPE_STRING;
362                  break;
363  
364              case FormulaRecord.sid :
365                  retval = HSSFCell.CELL_TYPE_FORMULA;
366                  break;
367  
368              case BoolErrRecord.sid :
369                  BoolErrRecord boolErrRecord = ( BoolErrRecord ) record;
370  
371                  retval = (boolErrRecord.isBoolean())
372                           ? HSSFCell.CELL_TYPE_BOOLEAN
373                           : HSSFCell.CELL_TYPE_ERROR;
374                  break;
375          }
376          return retval;
377      }
378  
379      /**
380       * set the cell's number within the row (0 based)
381       * @param num  short the cell number
382       */
383  
384      public void setCellNum(short num)
385      {
386          cellNum = num;
387          record.setColumn(num);
388      }
389  
390      /**
391       *  get the cell's number within the row
392       * @return short reperesenting the column number (logical!)
393       */
394  
395      public short getCellNum()
396      {
397          return cellNum;
398      }
399  
400      /**
401       * set the cells type (numeric, formula or string) -- DONT USE FORMULAS IN THIS RELEASE
402       * WE'LL THROW YOU A RUNTIME EXCEPTION IF YOU DO
403       * @see #CELL_TYPE_NUMERIC
404       * @see #CELL_TYPE_STRING
405       * @see #CELL_TYPE_FORMULA
406       * @see #CELL_TYPE_BLANK
407       * @see #CELL_TYPE_BOOLEAN
408       * @see #CELL_TYPE_ERROR
409       */
410  
411      public void setCellType(int cellType)
412      {
413          setCellType(cellType, true);
414      }
415  
416      /**
417       * sets the cell type. The setValue flag indicates whether to bother about
418       *  trying to preserve the current value in the new record if one is created.
419       *  <p>
420       *  The @see #setCellValue method will call this method with false in setValue
421       *  since it will overwrite the cell value later
422       *
423       */
424  
425      private void setCellType(int cellType, boolean setValue)
426      {
427  
428          // if (cellType == CELL_TYPE_FORMULA)
429          // {
430          // throw new RuntimeException(
431          // "Formulas have not been implemented in this release");
432          // }
433          if (cellType > CELL_TYPE_ERROR)
434          {
435              throw new RuntimeException("I have no idea what type that is!");
436          }
437          switch (cellType)
438          {
439  
440              case CELL_TYPE_FORMULA :
441                  FormulaRecord frec = null;
442  
443                  if (cellType != this.cellType)
444                  {
445                      frec = new FormulaRecord();
446                  }
447                  else
448                  {
449                      frec = ( FormulaRecord ) record;
450                  }
451                  frec.setColumn(getCellNum());
452                  if (setValue)
453                  {
454                      frec.setValue(getNumericCellValue());
455                  }
456                  frec.setXFIndex(( short ) cellStyle.getIndex());
457                  frec.setRow(row);
458                  record = frec;
459                  break;
460  
461              case CELL_TYPE_NUMERIC :
462                  NumberRecord nrec = null;
463  
464                  if (cellType != this.cellType)
465                  {
466                      nrec = new NumberRecord();
467                  }
468                  else
469                  {
470                      nrec = ( NumberRecord ) record;
471                  }
472                  nrec.setColumn(getCellNum());
473                  if (setValue)
474                  {
475                      nrec.setValue(getNumericCellValue());
476                  }
477                  nrec.setXFIndex(( short ) cellStyle.getIndex());
478                  nrec.setRow(row);
479                  record = nrec;
480                  break;
481  
482              case CELL_TYPE_STRING :
483                  LabelSSTRecord lrec = null;
484  
485                  if (cellType != this.cellType)
486                  {
487                      lrec = new LabelSSTRecord();
488                  }
489                  else
490                  {
491                      lrec = ( LabelSSTRecord ) record;
492                  }
493                  lrec.setColumn(getCellNum());
494                  lrec.setRow(row);
495                  lrec.setXFIndex(( short ) cellStyle.getIndex());
496                  if (setValue)
497                  {
498                      if ((getStringCellValue() != null)
499                              && (!getStringCellValue().equals("")))
500                      {
501                          int sst = 0;
502  
503                          if (encoding == ENCODING_COMPRESSED_UNICODE)
504                          {
505                              sst = book.addSSTString(getStringCellValue());
506                          }
507                          if (encoding == ENCODING_UTF_16)
508                          {
509                              sst = book.addSSTString(getStringCellValue(),
510                                                      true);
511                          }
512                          lrec.setSSTIndex(sst);
513                      }
514                  }
515                  record = lrec;
516                  break;
517  
518              case CELL_TYPE_BLANK :
519                  BlankRecord brec = null;
520  
521                  if (cellType != this.cellType)
522                  {
523                      brec = new BlankRecord();
524                  }
525                  else
526                  {
527                      brec = ( BlankRecord ) record;
528                  }
529                  brec.setColumn(getCellNum());
530  
531                  // During construction the cellStyle may be null for a Blank cell.
532                  if (cellStyle != null)
533                  {
534                      brec.setXFIndex(( short ) cellStyle.getIndex());
535                  }
536                  else
537                  {
538                      brec.setXFIndex(( short ) 0);
539                  }
540                  brec.setRow(row);
541                  record = brec;
542                  break;
543  
544              case CELL_TYPE_BOOLEAN :
545                  BoolErrRecord boolRec = null;
546  
547                  if (cellType != this.cellType)
548                  {
549                      boolRec = new BoolErrRecord();
550                  }
551                  else
552                  {
553                      boolRec = ( BoolErrRecord ) record;
554                  }
555                  boolRec.setColumn(getCellNum());
556                  if (setValue)
557                  {
558                      boolRec.setValue(getBooleanCellValue());
559                  }
560                  boolRec.setXFIndex(( short ) cellStyle.getIndex());
561                  boolRec.setRow(row);
562                  record = boolRec;
563                  break;
564  
565              case CELL_TYPE_ERROR :
566                  BoolErrRecord errRec = null;
567  
568                  if (cellType != this.cellType)
569                  {
570                      errRec = new BoolErrRecord();
571                  }
572                  else
573                  {
574                      errRec = ( BoolErrRecord ) record;
575                  }
576                  errRec.setColumn(getCellNum());
577                  if (setValue)
578                  {
579                      errRec.setValue(getErrorCellValue());
580                  }
581                  errRec.setXFIndex(( short ) cellStyle.getIndex());
582                  errRec.setRow(row);
583                  record = errRec;
584                  break;
585          }
586          if (cellType != this.cellType)
587          {
588              int loc = sheet.getLoc();
589  
590              sheet.replaceValueRecord(record);
591              sheet.setLoc(loc);
592          }
593          this.cellType = cellType;
594      }
595  
596      /**
597       * get the cells type (numeric, formula or string)
598       * @see #CELL_TYPE_STRING
599       * @see #CELL_TYPE_NUMERIC
600       * @see #CELL_TYPE_FORMULA
601       * @see #CELL_TYPE_BOOLEAN
602       * @see #CELL_TYPE_ERROR
603       */
604  
605      public int getCellType()
606      {
607          return cellType;
608      }
609  
610      /**
611       * set a numeric value for the cell
612       *
613       * @param value  the numeric value to set this cell to.  For formulas we'll set the
614       *        precalculated value, for numerics we'll set its value. For other types we
615       *        will change the cell to a numeric cell and set its value.
616       */
617      public void setCellValue(double value)
618      {
619          if ((cellType != CELL_TYPE_NUMERIC) && (cellType != CELL_TYPE_FORMULA))
620          {
621              setCellType(CELL_TYPE_NUMERIC, false);
622          }
623          (( NumberRecord ) record).setValue(value);
624          cellValue = value;
625      }
626  
627      /**
628       * set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as
629       * a date.
630       *
631       * @param value  the date value to set this cell to.  For formulas we'll set the
632       *        precalculated value, for numerics we'll set its value. For other types we
633       *        will change the cell to a numeric cell and set its value.
634       */
635      public void setCellValue(Date value)
636      {
637          setCellValue(HSSFDateUtil.getExcelDate(value));
638      }
639  
640      /**
641       * set a date value for the cell. Excel treats dates as numeric so you will need to format the cell as
642       * a date.
643       *
644       * @param value  the date value to set this cell to.  For formulas we'll set the
645       *        precalculated value, for numerics we'll set its value. For othertypes we
646       *        will change the cell to a numeric cell and set its value.
647       */
648      public void setCellValue(Calendar value)
649      {
650          setCellValue(value.getTime());
651      }
652  
653      /**
654       * set a string value for the cell.
655       *
656       * @param value  value to set the cell to.  For formulas we'll set the formula
657       * string, for String cells we'll set its value.  For other types we will
658       * change the cell to a string cell and set its value.
659       * If value is null then we will change the cell to a Blank cell.
660       */
661  
662      public void setCellValue(String value)
663      {
664          if (value == null)
665          {
666              setCellType(CELL_TYPE_BLANK, false);
667          }
668          else
669          {
670              if ((cellType != CELL_TYPE_STRING)
671                      && (cellType != CELL_TYPE_FORMULA))
672              {
673                  setCellType(CELL_TYPE_STRING, false);
674              }
675              int index = 0;
676  
677              if (encoding == ENCODING_COMPRESSED_UNICODE)
678              {
679                  index = book.addSSTString(value);
680              }
681              if (encoding == ENCODING_UTF_16)
682              {
683                  index = book.addSSTString(value, true);
684              }
685              (( LabelSSTRecord ) record).setSSTIndex(index);
686              stringValue = value;
687          }
688      }
689  
690      public void setCellFormula(String formula) {
691          if (formula==null) {
692              setCellType(CELL_TYPE_BLANK,false);
693          } else {
694              
695              setCellType(CELL_TYPE_FORMULA,false);
696              FormulaRecord rec = (FormulaRecord) record;
697              rec.setOptions(( short ) 2);
698              rec.setValue(0);
699              rec.setXFIndex(( short ) 0x0f);
700              FormulaParser fp = new FormulaParser(formula+";");
701              fp.parse();
702              Ptg[] ptg  = fp.getRPNPtg();
703              int   size = 0;
704              //System.out.println("got Ptgs " + ptg.length);
705              for (int k = 0; k < ptg.length; k++) {
706                  size += ptg[ k ].getSize();
707                  rec.pushExpressionToken(ptg[ k ]);
708              }
709              rec.setExpressionLength(( short ) size);
710              //return rec;
711              
712          }
713      }
714      
715      public String getCellFormula() {
716          String retval=null;
717          
718          retval = 
719                FormulaParser.toFormulaString(((FormulaRecord)record).getParsedExpression());
720          
721          return retval;   
722      }
723      
724      
725      /**
726       * get the value of the cell as a number.  For strings we throw an exception.
727       * For blank cells we return a 0.
728       */
729  
730      public double getNumericCellValue()
731      {
732          if (cellType == CELL_TYPE_BLANK)
733          {
734              return 0;
735          }
736          if (cellType == CELL_TYPE_STRING)
737          {
738              throw new NumberFormatException(
739                  "You cannot get a numeric value from a String based cell");
740          }
741          if (cellType == CELL_TYPE_BOOLEAN)
742          {
743              throw new NumberFormatException(
744                  "You cannot get a numeric value from a boolean cell");
745          }
746          if (cellType == CELL_TYPE_ERROR)
747          {
748              throw new NumberFormatException(
749                  "You cannot get a numeric value from an error cell");
750          }
751          return cellValue;
752      }
753  
754      /**
755       * get the value of the cell as a date.  For strings we throw an exception.
756       * For blank cells we return a null.
757       */
758      public Date getDateCellValue()
759      {
760          if (cellType == CELL_TYPE_BLANK)
761          {
762              return null;
763          }
764          if (cellType == CELL_TYPE_STRING)
765          {
766              throw new NumberFormatException(
767                  "You cannot get a date value from a String based cell");
768          }
769          if (cellType == CELL_TYPE_BOOLEAN)
770          {
771              throw new NumberFormatException(
772                  "You cannot get a date value from a boolean cell");
773          }
774          if (cellType == CELL_TYPE_ERROR)
775          {
776              throw new NumberFormatException(
777                  "You cannot get a date value from an error cell");
778          }
779          return HSSFDateUtil.getJavaDate(cellValue);
780      }
781  
782      /**
783       * get the value of the cell as a string - for numeric cells we throw an exception.
784       * For blank cells we return an empty string.
785       */
786  
787      public String getStringCellValue()
788      {
789          if (cellType == CELL_TYPE_BLANK)
790          {
791              return "";
792          }
793          if (cellType == CELL_TYPE_NUMERIC)
794          {
795              throw new NumberFormatException(
796                  "You cannot get a string value from a numeric cell");
797          }
798          if (cellType == CELL_TYPE_BOOLEAN)
799          {
800              throw new NumberFormatException(
801                  "You cannot get a string value from a boolean cell");
802          }
803          if (cellType == CELL_TYPE_ERROR)
804          {
805              throw new NumberFormatException(
806                  "You cannot get a string value from an error cell");
807          }
808          return stringValue;
809      }
810  
811      /**
812       * set a boolean value for the cell
813       *
814       * @param value the boolean value to set this cell to.  For formulas we'll set the
815       *        precalculated value, for booleans we'll set its value. For other types we
816       *        will change the cell to a boolean cell and set its value.
817       */
818  
819      public void setCellValue(boolean value)
820      {
821          if ((cellType != CELL_TYPE_BOOLEAN)
822                  && (cellType != CELL_TYPE_FORMULA))
823          {
824              setCellType(CELL_TYPE_BOOLEAN, false);
825          }
826          (( BoolErrRecord ) record).setValue(value);
827          booleanValue = value;
828      }
829  
830      /**
831       * set a error value for the cell
832       *
833       * @param value the error value to set this cell to.  For formulas we'll set the
834       *        precalculated value ??? IS THIS RIGHT??? , for errors we'll set
835       *        its value. For other types we will change the cell to an error
836       *        cell and set its value.
837       */
838  
839      public void setCellErrorValue(byte value)
840      {
841          if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA))
842          {
843              setCellType(CELL_TYPE_ERROR, false);
844          }
845          (( BoolErrRecord ) record).setValue(value);
846          errorValue = value;
847      }
848  
849      /**
850       * get the value of the cell as a boolean.  For strings, numbers, and errors, we throw an exception.
851       * For blank cells we return a false.
852       */
853  
854      public boolean getBooleanCellValue()
855      {
856          if (cellType == CELL_TYPE_BOOLEAN)
857          {
858              return booleanValue;
859          }
860          if (cellType == CELL_TYPE_BLANK)
861          {
862              return false;
863          }
864          throw new NumberFormatException(
865              "You cannot get a boolean value from a non-boolean cell");
866      }
867  
868      /**
869       * get the value of the cell as an error code.  For strings, numbers, and booleans, we throw an exception.
870       * For blank cells we return a 0.
871       */
872  
873      public byte getErrorCellValue()
874      {
875          if (cellType == CELL_TYPE_ERROR)
876          {
877              return errorValue;
878          }
879          if (cellType == CELL_TYPE_BLANK)
880          {
881              return ( byte ) 0;
882          }
883          throw new NumberFormatException(
884              "You cannot get an error value from a non-error cell");
885      }
886  
887      /**
888       * set the style for the cell.  The style should be an HSSFCellStyle created/retreived from
889       * the HSSFWorkbook.
890       *
891       * @param style  reference contained in the workbook
892       * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createCellStyle()
893       * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
894       */
895  
896      public void setCellStyle(HSSFCellStyle style)
897      {
898          cellStyle = style;
899          record.setXFIndex(style.getIndex());
900      }
901  
902      /**
903       * get the style for the cell.  This is a reference to a cell style contained in the workbook
904       * object.
905       * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
906       */
907  
908      public HSSFCellStyle getCellStyle()
909      {
910          return cellStyle;
911      }
912  
913      /**
914       * used for internationalization, currently 0 for compressed unicode or 1 for 16-bit
915       *
916       * @see #ENCODING_COMPRESSED_UNICODE
917       * @see #ENCODING_UTF_16
918       *
919       * @return 1 or 0 for compressed or uncompressed (used only with String type)
920       */
921  
922      public short getEncoding()
923      {
924          return encoding;
925      }
926  
927      /**
928       * set the encoding to either 8 or 16 bit. (US/UK use 8-bit, rest of the western world use 16bit)
929       *
930       * @see #ENCODING_COMPRESSED_UNICODE
931       * @see #ENCODING_UTF_16
932       *
933       * @param encoding either ENCODING_COMPRESSED_UNICODE (0) or ENCODING_UTF_16 (1)
934       */
935  
936      public void setEncoding(short encoding)
937      {
938          this.encoding = encoding;
939      }
940  
941      /**
942       * Should only be used by HSSFSheet and friends.  Returns the low level CellValueRecordInterface record
943       *
944       * @return CellValueRecordInterface representing the cell via the low level api.
945       */
946  
947      protected CellValueRecordInterface getCellValueRecord()
948      {
949          return record;
950      }
951  }
952  ??????????????????????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