Inspired by bug #44958 - Record level support for Data Tables. (No formula parser...
[poi.git] / src / documentation / content / xdocs / hssf / eval.xml
blob32279cc4a383e60e7182163484e56874d96f5d44
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3    ====================================================================
4    Licensed to the Apache Software Foundation (ASF) under one or more
5    contributor license agreements.  See the NOTICE file distributed with
6    this work for additional information regarding copyright ownership.
7    The ASF licenses this file to You under the Apache License, Version 2.0
8    (the "License"); you may not use this file except in compliance with
9    the License.  You may obtain a copy of the License at
11        http://www.apache.org/licenses/LICENSE-2.0
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18    ====================================================================
19 -->
20 <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
22 <document>
23     <header>
24         <title>Formula Evaluation</title>
25         <authors>
26                         <person email="amoweb@yahoo.com" name="Amol Deshmukh" id="AD"/>
27         </authors>
28     </header>
29     <body>
30                 <section><title>Introduction</title>
31                         <p>The POI formula evaluation code enables you to calculate the result of 
32                                 formulas in Excels sheets read-in, or created in POI. This document explains
33                                 how to use the API to evaluate your formulas. 
34                         </p>
35                         <note>In versions of POI before 3.0.3, this code lived in the
36                                 scratchpad area of the POI SVN repository. If using an such an older
37                                 version of POI, ensure that you have the scratchpad jar or the 
38                                 scratchpad build area in your classpath before experimenting with this
39                                 code. Users of all versions of POI may wish to make use of a recent 
40                                 SVN checkout, as new functions are currently being added fairly frequently.
41                         </note>
42                 </section>
44                 <anchor id="Status"/>
45                 <section><title>Status</title>
46                         <p>     The code currently provides implementations for all the arithmatic operators.
47                                 It also provides implementations for approx. 100 built in 
48                                 functions in Excel. The framework however makes is easy to add 
49                                 implementation of new functions. See the <link href="eval-devguide.html"> Formula
50                                 evaluation development guide</link> for details. </p>
51                         <p> Note that user-defined functions are not supported, and is not likely to done
52                                 any time soon... at least, not till there is a VB implementation in Java!
53                         </p>
54                 </section>
55                 <section><title>User API How-TO</title>
56                         <p>The following code demonstrates how to use the HSSFFormulaEvaluator 
57                                 in the context of other POI excel reading code.
58                         </p>
59                         <p>There are several ways in which you can use the HSSFFormulaEvalutator API.</p>
61                         <anchor id="Evaluate"/>
62                         <section><title>Using HSSFFormulaEvaluator.<strong>evaluate</strong>(HSSFCell cell)</title>
63                                 <p>This evaluates a given cell, and returns the new value,
64                                 without affecting the cell</p>
65                                 <source>
66 FileInputStream fis = new FileInputStream("c:/temp/test.xls");
67 HSSFWorkbook wb = new HSSFWorkbook(fis);
68 HSSFSheet sheet = wb.getSheetAt(0);
69 HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
71 // suppose your formula is in B3
72 CellReference cellReference = new CellReference("B3"); 
73 HSSFRow row = sheet.getRow(cellReference.getRow());
74 HSSFCell cell = row.getCell(cellReference.getCol()); 
76 evaluator.setCurrentRow(row);
77 HSSFFormulaEvaluator.CellValue cellValue = evaluator.evaluate(cell);
79 switch (cellValue.getCellType()) {
80         case HSSFCell.CELL_TYPE_BOOLEAN:
81         System.out.println(cellValue.getBooleanValue());
82         break;
83         case HSSFCell.CELL_TYPE_NUMERIC:
84         System.out.println(cellValue.getNumberValue());
85         break;
86         case HSSFCell.CELL_TYPE_STRING:
87         System.out.println(cellValue.getStringValue());
88         break;
89         case HSSFCell.CELL_TYPE_BLANK:
90         break;
91         case HSSFCell.CELL_TYPE_ERROR:
92         break;
94         // CELL_TYPE_FORMULA will never happen
95         case HSSFCell.CELL_TYPE_FORMULA: 
96         break;
97 }                               
98                                 </source>
99                                 <p>Thus using the retrieved value (of type 
100                                         HSSFFormulaEvaluator.CellValue - a nested class) returned 
101                                         by HSSFFormulaEvaluator is similar to using a HSSFCell object 
102                                         containing the value of the formula evaluation. CellValue is 
103                                         a simple value object and does not maintain reference 
104                                         to the original cell.
105                                 </p>
106                         </section>
108                         <anchor id="EvaluateFormulaCell"/>
109                         <section><title>Using HSSFFormulaEvaluator.<strong>evaluateFormulaCell</strong>(HSSFCell cell)</title>
110                                 <p><strong>evaluateFormulaCell</strong>(HSSFCell cell) 
111                                 will check to see if the supplied cell is a formula cell. 
112                                 If it isn't, then no changes will be made to it. If it is, 
113                                 then the formula is evaluated. The value for the formula
114                                 is saved alongside it, to be displayed in excel. The
115                                 formula remains in the cell, just with a new value</p>
116                                 <p>The return of the function is the type of the
117                                 formula result, such as HSSFCell.CELL_TYPE_BOOLEAN</p>
118                                 <source>
119 FileInputStream fis = new FileInputStream("/somepath/test.xls");
120 HSSFWorkbook wb = new HSSFWorkbook(fis);
121 HSSFSheet sheet = wb.getSheetAt(0);
122 HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
124 // suppose your formula is in B3
125 CellReference cellReference = new CellReference("B3"); 
126 HSSFRow row = sheet.getRow(cellReference.getRow());
127 HSSFCell cell = row.getCell(cellReference.getCol()); 
128 evaluator.setCurrentRow(row);
130 if (cell!=null) {
131         switch (<strong>evaluator.evaluateFormulaCell</strong>(cell)) {
132                 case HSSFCell.CELL_TYPE_BOOLEAN:
133                     System.out.println(cell.getBooleanCellValue());
134                     break;
135                 case HSSFCell.CELL_TYPE_NUMERIC:
136                     System.out.println(cell.getNumberCellValue());
137                     break;
138                 case HSSFCell.CELL_TYPE_STRING:
139                     System.out.println(cell.getStringCellValue());
140                     break;
141                 case HSSFCell.CELL_TYPE_BLANK:
142                     break;
143                 case HSSFCell.CELL_TYPE_ERROR:
144                     System.out.println(cell.getErrorCellValue());
145                     break;
146                 
147                 // CELL_TYPE_FORMULA will never occur
148                 case HSSFCell.CELL_TYPE_FORMULA: 
149                     break;
150         }
152                                 </source>
153                         </section>
155                         <anchor id="EvaluateInCell"/>
156                         <section><title>Using HSSFFormulaEvaluator.<strong>evaluateInCell</strong>(HSSFCell cell)</title>
157                                 <p><strong>evaluateInCell</strong>(HSSFCell cell) will check to
158                                 see if the supplied cell is a formula cell. If it isn't,
159                                 then no changes will be made to it. If it is, then the
160                                 formula is evaluated, and the new value saved into the cell,
161                                 in place of the old formula.</p>
162                                 <source>
163 FileInputStream fis = new FileInputStream("/somepath/test.xls");
164 HSSFWorkbook wb = new HSSFWorkbook(fis);
165 HSSFSheet sheet = wb.getSheetAt(0);
166 HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
168 // suppose your formula is in B3
169 CellReference cellReference = new CellReference("B3"); 
170 HSSFRow row = sheet.getRow(cellReference.getRow());
171 HSSFCell cell = row.getCell(cellReference.getCol()); 
172 evaluator.setCurrentRow(row);
174 if (cell!=null) {
175         switch (<strong>evaluator.evaluateInCell</strong>(cell).getCellType()) {
176                 case HSSFCell.CELL_TYPE_BOOLEAN:
177                     System.out.println(cell.getBooleanCellValue());
178                     break;
179                 case HSSFCell.CELL_TYPE_NUMERIC:
180                     System.out.println(cell.getNumberCellValue());
181                     break;
182                 case HSSFCell.CELL_TYPE_STRING:
183                     System.out.println(cell.getStringCellValue());
184                     break;
185                 case HSSFCell.CELL_TYPE_BLANK:
186                     break;
187                 case HSSFCell.CELL_TYPE_ERROR:
188                     System.out.println(cell.getErrorCellValue());
189                     break;
190                 
191                 // CELL_TYPE_FORMULA will never occur
192                 case HSSFCell.CELL_TYPE_FORMULA: 
193                     break;
194         }
196                                 </source>
197                         </section>
199                         <anchor id="EvaluateAll"/>
200                         <section><title>Re-calculating all formulas in a Workbook</title>
201                                 <source>
202 FileInputStream fis = new FileInputStream("/somepath/test.xls");
203 HSSFWorkbook wb = new HSSFWorkbook(fis);
204 for(int sheetNum = 0; sheetNum &lt; wb.getNumberOfSheets(); sheetNum++) {
205         HSSFSheet sheet = wb.getSheetAt(sheetNum);
206         HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
208         for(Iterator rit = sheet.rowIterator(); rit.hasNext();) {
209                 HSSFRow r = (HSSFRow)rit.next();
210                 evaluator.setCurrentRow(r);
212                 for(Iterator cit = r.cellIterator(); cit.hasNext();) {
213                         HSSFCell c = (HSSFCell)cit.next();
214                         if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
215                                 evaluator.evaluateFormulaCell(c);
216                         }
217                 }
218         }
220 wb.write(new FileOutputStream("/somepath/changed.xls"));
221                                 </source>
222                         </section>
223                 </section>
224                 
225                 <anchor id="Performance"/>
226                 <section><title>Performance Notes</title>
227                         <ul>
228                                 <li>Generally you should have to create only one HSSFFormulaEvaluator 
229                                         instance per sheet, but there really is no overhead in creating 
230                                         multiple HSSFFormulaEvaluators per sheet other than that of the 
231                                         HSSFFormulaEvaluator object creation. 
232                                 </li>
233                                 <li>Also note that HSSFFormulaEvaluator maintains a reference to 
234                                         the sheet and workbook, so ensure that the evaluator instance 
235                                         is available for garbage collection when you are done with it 
236                                         (in other words don't maintain long lived reference to 
237                                         HSSFFormulaEvaluator if you don't really need to - unless 
238                                         all references to the sheet and workbook are removed, these 
239                                         don't get garbage collected and continue to occupy potentially 
240                                         large amounts of memory). 
241                                 </li>   
242                                 <li>CellValue instances however do not maintain reference to the 
243                                         HSSFCell or the sheet or workbook, so these can be long-lived 
244                                         objects without any adverse effect on performance.
245                                 </li>
246                         </ul>
247                 </section>
248         </body>
249 </document>