Recalculating formulas in spreadsheet using Apache POI - java

I'm trying to use POI XSSF to evaluate some Excel formulas.
The values do not have to be saved, and I may have to calculate many formulas, so I'm trying to do it all in the same cell.
The problem is that the cell value seems to get stuck on the first formula entered even after I recalculate
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
XSSFCell formulaCell = row.createCell(6);
formulaCell.setCellFormula("Date(2011,10,6)");
CellValue cellValue = evaluator.evaluate(formulaCell);
System.out.println(cellValue.getNumberValue());
formulaCell.setCellFormula("Date(1911,3,4)");
cellValue = evaluator.evaluate(formulaCell);
System.out.println(cellValue.getNumberValue());
This outputs 40822.0
40822.0 (excel equivalent of 10/6/2011) both times instead of reevaluating to the new formula.

If you use the formulaEvaluator more than once, you need this line in between uses, or else it uses the same result each time.
formulaEvaluator.clearAllCachedResultValues()

The FormulaEvaluator caches cell calculated values to speed up processing. If you perform cell updates after creating the evaluator, then you need to tell it!
See the FormulaEvaluator documentation for more details. For you case, try:
formulaCell.setCellFormula("Date(1911,3,4)");
evaluator.notifySetFormula(formulaCell);
cellValue = evaluator.evaluate(formulaCell);
System.out.println(cellValue.getNumberValue());

You can use following steps to get your work done. These are two solutions out of which you can make use of any one function. It evaluates the complete workbook so whatever formula you use would get evaluated. Hope this helps.
1) evaluator.evaluateAll();
2) XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);

Related

What is a method to read an excel cell with the currency format and coded with a formula using java?

I have a currency format cell which is numeric and its coded with a formula. I can read the formula, no problem. I tried with cell.getNumericCellValue(), but its reading it as 0.00. I've tried converting it to a string using setCellType and reading it with cell.getStringCellType(). I've also tried using DataFromatter() and applying formatCellValue(cell) and it reads the formula. I've also tried using FormulaEvaluator.
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
cell.setCellFormula(formaCellValue.substring(1));
evaluator.evaluateFormulaCell(cell);
This is the error message I got for that:
The specified formula '=ROUND(G65*E65,2)' starts with an equals sign which is not allowed.
Is there any method I haven't tried yet? Or can I convert the cell format to a general cell and try getting the value? If so, how could I do that?
FormulaEvaluator evaluator =
workbook.getCreationHelper().createFormulaEvaluator();
double value = evaluator.evaluate(cell).getNumberValue();
System.out.println(value);
cell.setCellType(CellType.TYPE_NUMERIC);
double value = cell.getNumericCellValue();
System.out.println(value);

Apache Poi cell not returning the correct value

I have a excel file with a cell that generates the number 3.69 (based on calculations from proceeding numbers)
However when pulling that number in java using
if (brightCell.getNumericCellValue()) > 0 )
{
double brightness = brightCell.getNumericCellValue();
return brightness;
}
I've also tried:
if (Double.parseDouble(brightCell.getStringCellValue()) > 0 )
{
double brightness = Double.parseDouble(brightCell.getStringCellValue());
return brightness;
}
brightCell is instantiated with :
brightCell = spreadsheet.getRow(new CellReference(brightString).getRow()).getCell(new CellReference(brightString).getCol());
brightString is String brightString = "BV29"
But with both solutions, brightness receives the value, 3.2133....
So thanks to #Igor I managed to figure it out but it led to more issues.
So the solution was creating an evaluator
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
evaluator.setIgnoreMissingWorkbooks(true); //if you need it
when you finish setting the required cells and want to evaluate.
evaluator.EvaluateAll();
The problem for me is I'm doing this multiple times and my 1st resut is correct but upon the second iteration it becomes skewed, and more skewed.
What I'm doing is setting various cells (via java) then before I retrieve the value for a cell (that contains a formula) I run EvaluateAll. Now, I'm not sure if I should be evaluating after EVERY change or after I make all my changes to the excel sheet (via java).
I can't evaluate a specific cell at a time because there's over 38 sheets with multitudes of formulas. So EvaluateAll is the best option for me
EDIT 26/10/2018*
So the issue was not clearing the cache after making inputs. The solution was after each input as specified in the javaDoc that:
Should be called whenever there are changes to input cells in the evaluated workbook.
Failure to call this method after changing cell values will cause incorrect behaviour
of the evaluate~ methods of this class
therefore after making an input on a cell you should call evaluator.clearAllCachedResultValues();

Using POI Set Cell Style Based on Cell Formula Result

I need some help on setting the cell style base on the cell value.
The code used to populate cell.
String totalvariationweightv1 = "J" + (x+1);
String totalvariationweightv2 = "L" + (x+1);
cell85014.setCellType(Cell.CELL_TYPE_FORMULA);
cell85014.setCellFormula("SUM(((" + totalvariationweightv2 + "-" + totalvariationweightv1 + ")/" + totalvariationweightv1 + ")*100)");
Then I need to color the field if it exceeds a certain value. Right now I just have alternating colors:
cell85014.setCellStyle((x%2)==0?stylefloatGray:stylefloat);
I cannot figure out how to get the cell value. Using getNumericValue returns 0.
Apache POI stores the formula, but it doesn't evaluate it automatically.
The Excel file format (both .xls and .xlsx) stores a "cached" result for every formula along with the formula itself. This means that when the file is opened, it can be quickly displayed, without needing to spend a long time calculating all of the formula results. It also means that when reading a file through Apache POI, the result is quickly available to you too!
After making changes with Apache POI to either Formula Cells themselves, or those that they depend on, you should normally perform a Formula Evaluation to have these "cached" results updated. This is normally done after all changes have been performed, but before you write the file out.
You must tell Apache POI to evaluate the formula separately.
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
// Set your cell formula here
switch (evaluator.evaluateFormulaCell(cell85014)) {
case Cell.CELL_TYPE_NUMERIC:
double x = cell85014.getNumericCellValue();
// Set cell style here, based on numeric value,
// as you already are doing in your code.
// Watch out for floating point inaccuracies!
break;
default:
System.err.println("Unexpected result type!");
break;
}

Identify bullet points in MS Excel using Apache POI

I am reading columns in MS Excel using Apache POI but the code is not able to identify bullet point. I am trying this:
String cellValue = cell.getStringCellValue();
if(cellValue.contains("•")){}
but this is not working. the cellvalue is giving some garbage value in case of bullet point and this is why it is not able to compare in my if condition.
Can anyone please suggest solution ?
You need to use cell.getRichStringCellValue().getString() and then check for \u2022 which is unicode for "•"

Writing a formula to a cell with OpenXLS

I'm using Java and OpenXLS to write out an Excel spreadsheet. I want to set a formula for a cell but I haven't got a clue how to do it. Can anybody help me, please? :)
(Can't tag this with "openxls" because I'm a new user...)
I don't know about OpenXLS, but it's easy to do with Andy Khan's JExcel. I'd recommend trying it. I think it's far superior to POI; I'm betting that it's better than OpenXLS as well.
OpenXLS support very well formulas. Look at this example.
I put a value in the columns A and B of a sheet named "testSheet". In the column C of the same sheet I put the result of SUM (A+B).Don't forget to initialise the column C else you will have a CellNotFoundException
WorkBookHandle workbook = new WorkBookHandle();
workbook.createWorkSheet("testSheet");
WorkSheetHandle sheet = workbook.getWorkSheet("testSheet");
for (int i=1 ;i<=10; i++)
{
sheet.add(10*i, "A"+i);
sheet.add(15*i, "B"+i);
CellHandle cx = sheet.add(0,"C"+i);
cx.setFormula("=SUM(A"+i+":B"+i+")");
}
I hope that that this example will help other people.
Ultimately it turned out that OpenXLS doesn't support formula cells. They are included in the paid for version, though...
You can set the formula String directly on the cell in the Worksheet:
CellHandle cell = ws.add( "=SUM(A1:A3)", "A5" );
This adds the SUM(A1:A3) formula in cell A5. Any Cell set with a String value that is prefixed with '=' is considered a Formula.
Updates and maintenance are now happening on github (search for openxls).

Categories

Resources