I want create a excel with Apache POI in java and I must insert in a cell a formula: A3=B3+C3.
Is possible to insert another formula in A3 that color the cell if his value is> 0?
I use Apache POI 2.5.1
You will need a conditional formatting.
From this document:
// Define a Conditional Formatting rule, which triggers formatting
// when cell's value is greater or equal than 100.0 and
// applies patternFormatting defined below.
HSSFConditionalFormattingRule rule = sheet.createConditionalFormattingRule(
ComparisonOperator.GE,
"100.0", // 1st formula
null // 2nd formula is not used for comparison operator GE
);
// Create pattern with red background
HSSFPatternFormatting patternFmt = rule.cretePatternFormatting();
patternFormatting.setFillBackgroundColor(HSSFColor.RED.index);
// Define a region containing first column
Region [] regions =
{
new Region(1,(short)1,-1,(short)1)
};
// Apply Conditional Formatting rule defined above to the regions
sheet.addConditionalFormatting(regions, rule);
which creates a cell with a red background for values >= 100. Which is almost what you want :-)
Related
I have a use case where I need to apply two different conditional formatting rules. In rule1, I will be painting an entire row with a certain color. In rule2, if the text contains certain keywords or if it meets certain requirements, I need to repaint this particular cell with a different color (error highlighting). On building the workbook, always rule1 is taking precedence but I want rule2 as priority no 1.
ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("COUNTIF($F$2:$F$11,F2)>1");
FontFormatting font = rule1.createFontFormatting();
font.setFontStyle(false, true);
font.setFontColorIndex(IndexedColors.BLUE.index);
CellRangeAddress[] regions = {
CellRangeAddress.valueOf("F2:F11")
};
sheetCF.addConditionalFormatting(regions, rule1);
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();
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;
}
I'm trying to have numbers display as percentages in my cell. So far the calculations seems to all be working but I cannot get the numbers displayed to be formatted as percentages I've tried two different ways so far.
CellValue cv = evaluator.evaluate(cell);
DecimalFormat df = new DecimalFormat("###.##%");
cell.setCellValue(df.format(Math.abs(cell.getNumericCellValue())));
This way basically evaluates the cell and then gives it a java decimalFormat and uses java to create the formatting and the just places the result into the cell. The second method uses a CellStyle to try and attempt it and it looks like this
CellStyle stylePercent = wb.createCellStyle();
stylePercent.setDataFormat(wb.createDataFormat().getFormat("0.000%"));
where I then places the values into the sheet and then apply the style to the cell.
Neither of these have worked for me always leaving the value of 0.5 as 0.5 instead of 50% or even giving it 0.5%, it always just remains the same as without the styling.
This is also how I am applying the style and my formula as well.
cell.setCellFormula(""+cellValue+"/(SUM(D"+(row.getRowNum()+1)+" + F"+(row.getRowNum()+1)+" + H"+(row.getRowNum()+1)+"+ J"+(row.getRowNum()+1)+" + L"+(row.getRowNum()+1)+"+ N"+(row.getRowNum()+1)+"+ P"+(row.getRowNum()+1)+"+ R"+(row.getRowNum()+1)+"+ T"+(row.getRowNum()+1)+"+ V"+(row.getRowNum()+1)+"+ X"+(row.getRowNum()+1)+")+ Z"+(row.getRowNum()+1)+")");
cell.setCellStyle(stylePercent);
I have two numbers one above the other, but the first one must have an Strikethrough, I'm using a table and cell to put both numbers in the table, is there a way to make what I need?
Create a font with the style STRIKETHRU.
Font f = new Font(Font.FontFamily.HELVETICA, 12, Font.STRIKETHRU);
I am adding an extra answer for the sake of completeness.
Please take a look at the SimpleTable6 example:
In the first row, we strike through a number using a STRIKETHRU font as explained by Paulo:
Font font = new Font(FontFamily.HELVETICA, 12f, Font.STRIKETHRU);
table.addCell(new Phrase("0123456789", font));
In this case, iText has made a couple of decisions for you: where do I put the line? How thick is the line?
If you want to make these decisions yourself, you can use the setUnderline() method:
chunk1.setUnderline(1.5f, -1);
table.addCell(new Phrase(chunk1));
Chunk chunk2 = new Chunk("0123456789");
chunk2.setUnderline(1.5f, 3.5f);
table.addCell(new Phrase(chunk2));
If you pass a negative value for the y-offset parameter, the Chunk will be underlined (see first column). You can also use this method to strike through text by passing a positive y-offset.
As you can see, we also defined the thickness of the line (1.5f). There is another setUnderline() method that also allows you to pass the following parameters:
color - the color of the line or null to follow the text color
thickness - the absolute thickness of the line
thicknessMul - the thickness multiplication factor with the font size
yPosition - the absolute y position relative to the baseline
yPositionMul - the position multiplication factor with the font size
cap - the end line cap. Allowed values are PdfContentByte.LINE_CAP_BUTT, PdfContentByte.LINE_CAP_ROUND and PdfContentByte.LINE_CAP_PROJECTING_SQUARE
See http://api.itextpdf.com/itext/com/itextpdf/text/Chunk.html