How can Apache POI use formulas in streaming mode? - java

I am using Apache POI 3.17 (current). When I use HSSFCell.setFormula() to insert a formula like "A1+17" it works. When I do the same in streaming mode, using SXSSFCell.setFormula() the formula appears (with a leading "=") in the input line but the displayed result in the cell is always 0.
I tried with the cell types NUMERIC and FORMULA. Here is my minimal not working example:
final SXSSFWorkbook wb = new SXSSFWorkbook();
final SXSSFSheet sheet = wb.createSheet("Test-S");
final SXSSFRow row = sheet.createRow(0);
final SXSSFCell cell1 = row.createCell(0);
cell1.setCellType(CellType.NUMERIC);
cell1.setCellValue(124);
final SXSSFCell formulaCell1 = row.createCell(1);
formulaCell1.setCellType(CellType.FORMULA);
formulaCell1.setCellFormula("A1 + 17");
final SXSSFCell formulaCell2 = row.createCell(2);
formulaCell2.setCellType(CellType.NUMERIC);
formulaCell2.setCellFormula("A1+18");
FileOutputStream os = new FileOutputStream("/tmp/test-s.xlsx");
wb.write(os);
wb.close();
os.close();
The three cells display as 124/0/0, although in the input line the formulae are displayed correctly.
Any hints are appreciated.

It works for me with Excel 2016, I get the correct results in the cells when I open the sample file. Probably older versions of Excel handle this slightly differently, please try to force evaluation of formulas with the following two things
// evaluate all formulas and store cached results
wb.getCreationHelper().createFormulaEvaluator().evaluateAll();
// suggest to Excel to recalculate the formulas itself as well
sheet.setForceFormulaRecalculation(true);
Hopefully one of those two will make it work for you as well.

The answers does not answer the question why this problem with OpenOffice/Libreoffice only occurs if SXSSFCell is used as a formula cell. When using XSSFCell as a formula cell it does not occur.
The answer is that SXSSFCell always uses a cell value, even if the formula was not evaluated at all. And the worst thing is that it uses the value 0 (zero) if if the formula was not evaluated at all. This is a fundamental misusing of the value 0 in mathematics. The value 0 explicitly does not mean that there is not a value or that there is a unknown value. It means that there is the value 0 and nothing else. So the value 0 should not be used as the cached formula result of a not evaluated formula. Instead no value should be used until the formula is evaluated. Exact as XSSFCell does.
So the really correct answer must be that apache poi should correct their SXSSFCell code.
Workaround until this:
import java.io.FileOutputStream;
import org.apache.poi.xssf.streaming.*;
import org.apache.poi.ss.usermodel.CellType;
import java.lang.reflect.Field;
import java.util.TreeMap;
public class CreateExcelSXSSFFormula {
public static void main(String[] args) throws Exception {
SXSSFWorkbook wb = new SXSSFWorkbook();
SXSSFSheet sheet = wb.createSheet("Test-S");
SXSSFRow row = sheet.createRow(0);
SXSSFCell cell = row.createCell(0);
cell.setCellValue(124);
SXSSFFormulaonlyCell formulacell = new SXSSFFormulaonlyCell(row, 1);
formulacell.setCellFormula("A1+17");
cell = row.createCell(2);
cell.setCellFormula("A1+17");
formulacell = new SXSSFFormulaonlyCell(row, 3);
formulacell.setCellFormula("A1+18");
cell = row.createCell(4);
cell.setCellFormula("A1+18");
wb.write(new FileOutputStream("test-s.xlsx"));
wb.close();
wb.dispose();
}
private static class SXSSFFormulaonlyCell extends SXSSFCell {
SXSSFFormulaonlyCell(SXSSFRow row, int cellidx) throws Exception {
super(row, CellType.BLANK);
Field _cells = SXSSFRow.class.getDeclaredField("_cells");
_cells.setAccessible(true);
#SuppressWarnings("unchecked") //we know the problem and expect runtime error if it possibly occurs
TreeMap<Integer, SXSSFCell> cells = (TreeMap<Integer, SXSSFCell>)_cells.get(row);
cells.put(cellidx, this);
}
#Override
public CellType getCachedFormulaResultTypeEnum() {
return CellType.BLANK;
}
}
}

Of course I should have mentioned that I use LibreOffice. I have now found that LibreOffice intentionally does not recalculate formulae from an Excel-created sheet, and it considers POI sheets as Excel-created.
See https://ask.libreoffice.org/en/question/12165/calc-auto-recalc-does-not-work/ .
Changing the LibreOffice settings (Tools – Options – LibreOffice Calc – formula – Recalculation on file load) helps.

Related

Apache POI - Not implemented error with CONCAT function

I'm trying to edit a excel document that contains formulas, the editing works fine but the formulas don't update.
I'm trying to use the following code to get it to evaluate the formulas, however i get an error
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
for (Row r : sheet) {
for (Cell c : r) {
evaluator.evaluateFormulaCell(c);
}
}
Exception in thread "AWT-EventQueue-0" org.apache.poi.ss.formula.eval.NotImplementedException: Error evaluating cell Sheet1!C17
at org.apache.poi.ss.formula.WorkbookEvaluator.addExceptionInfo(WorkbookEvaluator.java:344)
at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateAny(WorkbookEvaluator.java:285)
at org.apache.poi.ss.formula.WorkbookEvaluator.evaluate(WorkbookEvaluator.java:216)
at org.apache.poi.xssf.usermodel.BaseXSSFFormulaEvaluator.evaluateFormulaCellValue(BaseXSSFFormulaEvaluator.java:56)
at org.apache.poi.ss.formula.BaseFormulaEvaluator.evaluateFormulaCell(BaseFormulaEvaluator.java:185)
at Timetable.ExcelAPI.calculateFormula(ExcelAPI.java:139)
Cell C17 has the following formula.
=IF(C3="","",CONCAT($A17,$B17,C3,$B17,$A$16))
I've also tried
=IF(C3="","",CONCATENATE($A17,$B17,C3,$B17,$A$16))
If i programmatically create the formula it works
cell.setCellFormula("IF(C3=\"\",\"\",CONCAT($A17,$B17,C" + (start + 1) + ",$B17,$A$16))");
Since Excel function support of apache poi is at Excel 2007 standard, CONCATENATE is implemented but CONCAT is not. Furthermore functions which are introduced after Excel 2007 are prefixed with _xlfn..
So your full stacktrace should contain:
...
Caused by: org.apache.poi.ss.formula.eval.NotImplementedFunctionException: _xlfn.CONCAT
...
A work around could be replacing "_xlfn.CONCAT" by "CONCATENATE" in formulas before evaluating.
Following code works for me and evaluates CONCATENATE as well as CONCAT formulas.
import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
class ReadExcel {
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelExampleConcatenate.xlsx"));
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
DataFormatter dataFormatter = new DataFormatter();
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == CellType.FORMULA && cell.getCellFormula().contains("_xlfn.CONCAT")) {
cell.setCellFormula(cell.getCellFormula().replace("_xlfn.CONCAT", "CONCATENATE"));
}
String value = dataFormatter.formatCellValue(cell, evaluator);
System.out.println(value);
}
}
workbook.close();
}
}
Good news - the CONCAT function is now supported! Bad news - not in your version...
If you upgrade (once available) to Apache POI 5.0.1 or later, the CONCAT function is now supported, see https://bz.apache.org/bugzilla/show_bug.cgi?id=65185
If you're impatient and want to backport the missing function, it's http://svn.apache.org/viewvc?view=revision&revision=1887656
Resolved it by changing the call to the function to simply
workbook.setForceFormulaRecalculation(true);

Java POI FormulaEvaluator giving unexpected floating point value

I am using Java POI library to read an Excel file and then display it in HTML table. The Excel file is very simple with 1 row and 3 columns:
A1 cell= 21.7
B1 cell= 20.0
C1 cell is a formula cell with the formula =(A1-B1)/B1 and it has a custom format of "Percentage" with 0 decimal places. Excel displays its value as 9%. This is because 1.7/20 on a calculator gives result as 0.085; when it is converted to "Percentage" format it becomes 8.5% and because format says include 0 decimal places, it gets rounded up to 9%, so that's what Excel displays. All good.
However, POI displays the value as 8% instead. I observe that 1.7/20 is calculated to be 0.084999999. Because of the Percentage format as applied above it converts to 8.4999999% and because of 0 decimal places, it gets rounded down to 8%.
How can I have POI return me 9% instead of 8%? Here is the code snippet:
String myFormat="0%";
CreationHelper helper = wbWrapper.getWb().getCreationHelper();
CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT,helper.createDataFormat().getFormat(myFormat));
String val = dataFormatter.formatCellValue(cell, evaluator);
Here evaluator is an instance of org.apache.poi.ss.usermodel.FormulaEvaluator and dataFormatter is an instance of org.apache.poi.ss.usermodel.DataFormatter
When I print the variable "val" it is returning 8% instead of what is displayed in Excel (9%).
Your observations are correct. The problem occurs because of the general floating point problems. It can simply be shown:
...
System.out.println(1.7/20.0); //0.08499999999999999
System.out.println((21.7-20.0)/20.0); //0.08499999999999996
...
As you see, the division of double value 1.7 by double value 20.0 results in 0.08499999999999999. This would be fine since this value would be taken as 0.085 using DecimalFormat. But the more complex equation (21.7-20.0)/20.0 results in 0.08499999999999996. And this clearly is lower than 0.085 .
Excel tries solving those problems by an additional rule for floating point values. It always uses only 15 significant decimal digits of an floating point value. So Excel does something like :
...
BigDecimal bd = new BigDecimal((21.7-20.0)/20.0);
System.out.println(bd.round(new MathContext(15)).doubleValue()); //0.085
...
Neither apache poi's FormulaEvaluator nor it's DataFormatter behaves like Excel in this point. That's why the difference.
One could have an own MyDataFormatter where the only difference to /org/apache/poi/ss/usermodel/DataFormatter.java is:
...
private String getFormattedNumberString(Cell cell, ConditionalFormattingEvaluator cfEvaluator) {
if (cell == null) {
return null;
}
Format numberFormat = getFormat(cell, cfEvaluator);
double d = cell.getNumericCellValue();
java.math.BigDecimal bd = new java.math.BigDecimal(d);
d = bd.round(new java.math.MathContext(15)).doubleValue();
if (numberFormat == null) {
return String.valueOf(d);
}
String formatted = numberFormat.format(Double.valueOf(d));
return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation
}
...
Then using that MyDataFormatter instead of DataFormatter would be more compatible to Excel's behavior.
Example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class CreateExcelEvaluateFormula {
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook();
CreationHelper creationHelper = workbook.getCreationHelper();
FormulaEvaluator formulaEvaluator = creationHelper.createFormulaEvaluator();
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(0);
Cell cell = row.createCell(0); cell.setCellValue(21.7);
cell = row.createCell(1); cell.setCellValue(20.0);
cell = row.createCell(2); cell.setCellFormula("(A1-B1)/B1");
formulaEvaluator.evaluateFormulaCell(cell);
double d = cell.getNumericCellValue();
System.out.println(d); //0.08499999999999996
MyDataFormatter dataFormatter = new MyDataFormatter();
String myFormat="0%";
CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT, creationHelper.createDataFormat().getFormat(myFormat));
String val = dataFormatter.formatCellValue(cell, formulaEvaluator);
System.out.println(val); //9%
FileOutputStream out = new FileOutputStream("Excel.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
}

Apache-poi template leading zeros disappear on editing cells

I'm creating a .xlsx template using apache-poi, the user have to insert an id that has fixed length.
i've already tried the setDataFormat(workbook.createDataFormat().getFormat("#")) trick, but when the cell is edited it seems to forget that, and leading zeros disappear.
//this is the code snippet i found here on stackoverflow and tried out
DataFormat fmt = workbook.createDataFormat();
CellStyle textStyle = workbook.createCellStyle();
textStyle.setDataFormat(fmt.getFormat("#"));
worksheet.setDefaultColumnStyle(0, textStyle);
It would be great finding a true solution, because adding leading zeros to get the expected length can cause errors. Ex: user means 0000111 but forgets a 1 , new id will be 0000011 and unfortunately ids aren't sequential.
Thanks for your time, and forgive me for my bad english XD
Cannot reproduce your issue.
Following code creates a Excel sheet having Ids in column A which are not losing their text format and leading zeros even if edited in Excels GUI.
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
class CreateExcelNumberFormatText {
public static void main(String[] args) throws Exception {
try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {
DataFormat format = workbook.createDataFormat();
CellStyle textStyle = workbook.createCellStyle();
textStyle.setDataFormat(format.getFormat("#"));
Sheet sheet = workbook.createSheet();
sheet.setDefaultColumnStyle(0, textStyle);
Cell cell = sheet.createRow(0).createCell(0);
cell.setCellStyle(textStyle);
cell.setCellValue("Id");
cell = sheet.createRow(1).createCell(0);
cell.setCellStyle(textStyle);
cell.setCellValue("0000111");
cell = sheet.createRow(2).createCell(0);
cell.setCellStyle(textStyle);
cell.setCellValue("0001111");
workbook.write(fileout);
}
}
}
What you probably not expected is that apache poi does not applying the column style to new created cells in that column. This you needs doing in code else the cell style will be General. Setting the column style is nevertheless necessary since else Excels GUI will not use the text style while adding cell contents there.
My code is complete, tested and works for me. Simply editing the cells in Excel cannot lead to lost of parts of cell contents (the leading zeros) because of using the number format # = Text.
Of course, if someone changes the column number format from Text to General, then 0000111 will be the number 111 after editing. But this is cannot be prevented when the sheet is editable by the user.
Maybe one could set CellStyle.setQuotePrefixed additionally. As:
...
textStyle.setDataFormat(format.getFormat("#"));
textStyle.setQuotePrefixed(true);
...
Then all content will be prefixed with a quote prefix apostrophe ' additionally. But this too can be changed by a user editing the sheet.
This was the solution for me :
cell = row.createCell(col, CellType.STRING);
cell.setCellValue(val);

How to handle an empty numeric cell in POI

Is there any particular reason POI creates a numeric cell when in fact, it's actually empty? What happens is that by the time I get to that cell I obviously get an runtime error as I can't get the string value (it's a numeric cell, after all) and I can't get the numeric value either (can't get a number from an empty string) so my 2 questions would be:
How does POI got there?
Is there any way I can handle this scenario without having to explicitly go to my excel file?
UPDATE I:
After reading / parsing my excel file, POI generates the following XML for this particular cell:
<x:c r="AA2" t="n">
<x:v/>
</x:c>
My method is something like this:
final FileInputStream inputStream = new FileInputStream(new File("PATH/TO/FILE.xml"));
final XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
final XSSFSheet sheet = workbook.getSheet("SHEET_NAME");
final int columnCount = sheet.getRow(0).getLastCellNum();
for (int rowNumber = 0; rowNumber <= sheet.getLastRowNum(); rowNumber++)
{
final XSSFRow row = sheet.getRow(rowNumber);
for (int column = 0; column < columnCount; column++)
{
// By now my cell would throw an exception if I attempt cell.getStringCellValue() or cell.getNumericCellValue() as cell.getCellType() returns "0" / NUMERIC
final XSSFCell cell = row.getCell(column);
...
}
}
I was thinking about adding an additional validation to determine whether the cell is empty by using the getRawValue() method, but not sure if there's a better way to handle this as it was obviously wrongly parsed.
UPDATE II
I've been able to reproduce this scenario by doing adding this as part of a unit test (I still don't understand why POI would fall into this scenario though):
final XLSXSheetConverterImpl xlsxSheetConverter = new XLSXSheetConverterImpl();
xlsxSheetConverter.setSheetName(SHEET_NAME);
xlsxSheetConverter.setFilePrefix(FILE_PREFIX);
XSSFWorkbook workbook = new XSSFWorkbook();
final XSSFSheet sheet = workbook.createSheet(SHEET_NAME);
final XSSFRow row = sheet.createRow(0);
XSSFCell cell = row.createCell(0);
final CTCellImpl ctCell = (CTCellImpl) cell.getCTCell();
ctCell.setT(STCellType.N);
ctCell.setV("");
Thanks in advance!
This is a known bug in older POI versions, see: https://bz.apache.org/bugzilla/show_bug.cgi?id=56702
It's been fixed since 3.11 version
Thank you all for your help!!

Java POI : How to read Excel cell value and not the formula computing it?

I am using Apache POI API to getting values from an Excel file.
Everything is working great except with cells containing formulas. In fact, the cell.getStringCellValue() is returning the formula used in the cell and not the value of the cell.
I tried to use evaluateFormulaCell() method but it's not working because I am using GETPIVOTDATA Excel formula and this formula is not implemented in the API:
Exception in thread "main" org.apache.poi.ss.formula.eval.NotImplementedException: Error evaluating cell Landscape!K11
at org.apache.poi.ss.formula.WorkbookEvaluator.addExceptionInfo(WorkbookEvaluator.java:321)
at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateAny(WorkbookEvaluator.java:288)
at org.apache.poi.ss.formula.WorkbookEvaluator.evaluate(WorkbookEvaluator.java:221)
at org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.evaluateFormulaCellValue(HSSFFormulaEvaluator.java:320)
at org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.evaluateFormulaCell(HSSFFormulaEvaluator.java:213)
at fromExcelToJava.ExcelSheetReader.unAutreTest(ExcelSheetReader.java:193)
at fromExcelToJava.ExcelSheetReader.main(ExcelSheetReader.java:224)
Caused by: org.apache.poi.ss.formula.eval.NotImplementedException: GETPIVOTDATA
at org.apache.poi.hssf.record.formula.functions.NotImplementedFunction.evaluate(NotImplementedFunction.java:42)
For formula cells, excel stores two things. One is the Formula itself, the other is the "cached" value (the last value that the forumla was evaluated as)
If you want to get the last cached value (which may no longer be correct, but as long as Excel saved the file and you haven't changed it it should be), you'll want something like:
for(Cell cell : row) {
if(cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
System.out.println("Formula is " + cell.getCellFormula());
switch(cell.getCachedFormulaResultType()) {
case Cell.CELL_TYPE_NUMERIC:
System.out.println("Last evaluated as: " + cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
System.out.println("Last evaluated as \"" + cell.getRichStringCellValue() + "\"");
break;
}
}
}
Previously posted solutions did not work for me. cell.getRawValue() returned the same formula as stated in the cell. The following function worked for me:
public void readFormula() throws IOException {
FileInputStream fis = new FileInputStream("Path of your file");
Workbook wb = new XSSFWorkbook(fis);
Sheet sheet = wb.getSheetAt(0);
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
CellReference cellReference = new CellReference("C2"); // pass the cell which contains the formula
Row row = sheet.getRow(cellReference.getRow());
Cell cell = row.getCell(cellReference.getCol());
CellValue cellValue = evaluator.evaluate(cell);
switch (cellValue.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
System.out.println(cellValue.getBooleanValue());
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.println(cellValue.getNumberValue());
break;
case Cell.CELL_TYPE_STRING:
System.out.println(cellValue.getStringValue());
break;
case Cell.CELL_TYPE_BLANK:
break;
case Cell.CELL_TYPE_ERROR:
break;
// CELL_TYPE_FORMULA will never happen
case Cell.CELL_TYPE_FORMULA:
break;
}
}
There is an alternative command where you can get the raw value of a cell where formula is put on. It's returns type is String. Use:
cell.getRawValue();
If the need is to read values from Excel sheets and having them as strings then, for example to present them somewhere or to use them in text file formats, then using DataFormatter will be the best.
DataFormatter is able to get a string from each cell value, whether the cell value itself is string, boolean, number, error or date. This string then looks the same as Excel will show it in the cells in it's GUI.
Only problem are formula cells. Up to apache poi 5.1.0 a FormulaEvaluator is needed to evaluate the formulas while using DataFormatter. This fails when apache poi is not able evaluating the formula. From 5.2.0 on the DataFormatter can be set to use cached values for formula cells. Then no formula evaluation is needed if Excel had evaluated the formulas before.
Complete example:
import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
class ReadExcel {
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelExample.xlsx"));
// up to apache poi 5.1.0 a FormulaEvaluator is needed to evaluate the formulas while using DataFormatter
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
DataFormatter dataFormatter = new DataFormatter(new java.util.Locale("en", "US"));
// from 5.2.0 on the DataFormatter can set to use cached values for formula cells
dataFormatter.setUseCachedValuesForFormulaCells(true);
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
//String value = dataFormatter.formatCellValue(cell, evaluator); // up to apache poi 5.1.0
String value = dataFormatter.formatCellValue(cell); // from apache poi 5.2.0 on
System.out.println(value);
}
}
workbook.close();
}
}
If you want to extract a raw-ish value from a HSSF cell, you can use something like this code fragment:
CellBase base = (CellBase) cell;
CellType cellType = cell.getCellType();
base.setCellType(CellType.STRING);
String result = cell.getStringCellValue();
base.setCellType(cellType);
At least for strings that are completely composed of digits (and automatically converted to numbers by Excel), this returns the original string (e.g. "12345") instead of a fractional value (e.g. "12345.0"). Note that setCellType is available in interface Cell(as of v. 4.1) but deprecated and announced to be eliminated in v 5.x, whereas this method is still available in class CellBase. Obviously, it would be nicer either to have getRawValue in the Cell interface or at least to be able use getStringCellValue on non STRING cell types. Unfortunately, all replacements of setCellType mentioned in the description won't cover this use case (maybe a member of the POI dev team reads this answer).
SelThroughJava's answer was very helpful I had to modify a bit to my code to be worked .
I used https://mvnrepository.com/artifact/org.apache.poi/poi and https://mvnrepository.com/artifact/org.testng/testng as dependencies .
Full code is given below with exact imports.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.sl.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReadExcelFormulaValue {
private static final CellType NUMERIC = null;
public static void main(String[] args) {
try {
readFormula();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void readFormula() throws IOException {
FileInputStream fis = new FileInputStream("C:eclipse-workspace\\sam-webdbriver-diaries\\resources\\tUser_WS.xls");
org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(fis);
org.apache.poi.ss.usermodel.Sheet sheet = workbook.getSheetAt(0);
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
CellReference cellReference = new CellReference("G2"); // pass the cell which contains the formula
Row row = sheet.getRow(cellReference.getRow());
Cell cell = row.getCell(cellReference.getCol());
CellValue cellValue = evaluator.evaluate(cell);
System.out.println("Cell type month is "+cellValue.getCellTypeEnum());
System.out.println("getNumberValue month is "+cellValue.getNumberValue());
// System.out.println("getStringValue "+cellValue.getStringValue());
cellReference = new CellReference("H2"); // pass the cell which contains the formula
row = sheet.getRow(cellReference.getRow());
cell = row.getCell(cellReference.getCol());
cellValue = evaluator.evaluate(cell);
System.out.println("getNumberValue DAY is "+cellValue.getNumberValue());
}
}

Categories