fetch excel cell display value using Apache POI - java

Below shows the highlighted cell which display as - (hyphen) but actually has 0 value inside it.
It's a formula cell with following custom formatting.
It's a formula cell but when the result is 0, it displays as -.
My requirement is to fetch - instead of 0.
cell2Update = sheet.getRow(4).getCell(3);
cell2Update.setCellType(Cell.CELL_TYPE_NUMERIC);
System.out.println(cell2Update.getStringCellValue());//Exception
System.out.println(cell2Update.getNumericCellValue());//Display as 0
Please help me with this doubt. I want to display the value which is displayed in Spreadsheet (-).

Do using a DataFormatter as shown in Getting the cell contents. And because the value might be result of a formula. Do using using a DataFormatter together with a FormulaEvaluator:
...
DataFormatter formatter = new DataFormatter();
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
...
cell2Update = sheet.getRow(4).getCell(3);
...
String value = formatter.formatCellValue(cell2Update, evaluator);
System.out.println(value);
...

Related

How to retrieve the Date from Excel with Formula by Apache POI

I have an Excel Sheet where the Date Cell is assigned with the Date Formula in Excel TODAY() + 1. So basically today it's showing as 03/10/2018 by default. I've created a code to read the data from Excel which has the formula in it but when I'm getting the date it's coming differently.
Code :
Cell c = CellUtil.getCell(r, columnIndex);
CellType type = c.getCellType();
if (type == CellType.FORMULA) {
switch (c.getCachedFormulaResultType()) {
case NUMERIC:
if (DateUtil.isCellDateFormatted(c)) {
value = (new SimpleDateFormat("dd-MM-yyyy").format(c.getDateCellValue()));
data.add(value); // Date should display 03-10-2018 but it's showing 23-01-2018
} else {
value = (c.getNumericCellValue()) + "";
data.add(value);
}
break;
case STRING:
value = c.getStringCellValue();
data = new LinkedList <String>(Arrays.asList(value.split(";")));
break;
}
}
I don't know why it's showing date from January with the formula applied TODAY() + 1
Similar to this another function TODAY() + 15 returning the 22-04-2018.
As stated in Formula Evaluation:
"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!"
So all formulas will have cached results stored from the last time they were evaluated. This is either the last time the workbook was opened in Excel, recalculated and saved or from the last time an evaluation was be done outside of Excel.
So if a cell having the formula =TODAY() has a cached result of 22-01-2018 stored, then the workbook was evaluated on January 22, 2018 the last time.
To get always current formula results you need evaluating the formulas first before reading. Simplest way:
...
workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();
...
Or you are using a DataFormatter together with a FormulaEvaluator:
...
DataFormatter formatter = new DataFormatter();
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
...
Cell cell = CellUtil.getCell(...);
...
String value = formatter.formatCellValue(cell, evaluator);
...

POI-XSSF: read formatted value from formula cells cached value

In my excel sheet many cells contain formulas, i don't want to recalculate these formulas when i read the excel with Apache POI.
The way i do that:
if(cell.getCellType() == XSSFCell.CELL_TYPE_FORMULA) {
//System.out.println("Formula is " + cell.getCellFormula());
switch(cell.getCachedFormulaResultType()) {
case XSSFCell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() +" ");
break;
case XSSFCell.CELL_TYPE_STRING:
System.out.print(cell.getRichStringCellValue()+" ");
break;
}
}
This helps me in getting the raw value in the cell.
For example if the cell has value 19.5%, this will give me 0.195456 .
I want to get the formatted value.
One way to get the formatted value is:
DataFormatter formatter = new DataFormatter();
System.out.print(formatter.formatCellValue(cell));
This works well for regular cells, but for cells with formulas, this actually gets the formula string and displays it, i.e., it does not get the cached value and formats it, rather it just returns the formula string.
Is there a way to format a value after retrieving it from CELL_TYPE_FORMULA
It's possible to directly format the cached value of a cell without using an evaluator. It's useful in case of values that cannot be recalculated because of third party plugin or unavailable external Data in the cell formula.
This code can be used to do that:
final DataFormatter dataFormatter = new DataFormatter();
final CellStyle cellStyle = cell.getCellStyle();
final String formtatedValue = dataFormatter.formatRawCellContents(cell.getNumericCellValue(), cellStyle.getDataFormat(), cellStyle.getDataFormatString());
System.out.println(formattedValue);
A formatter is still used but the method formatRawCellContents is called to manually format the cell cached value with its style.
It should work if you pass in a FormulaEvaluator in the call to formatCellValue, i.e.
DataFormatter formatter = new DataFormatter();
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
System.out.print(formatter.formatCellValue(cell, evaluator));

Converting into number format while writing from text file to excel in java

We have one existing application where we read one text file and write into excel using java. Text file will have first row as header and subsequent rows as records which is fetched from database.
Currently while writing into excel, all the columns are getting converted into text format. We want to convert one column(consider column Z) as number.
String [] column = line.split("\\|~");
for (int i = 0; i < column.length; i++) {
Cell tmpCell = row.createCell(i);
tmpCell.setCellValue(new HSSFRichTextString(column[i].trim()));
}
I am new to java, need your help in resolving this issue.
Thanks
Santhosh
You can write to cell like this
cell.setCellValue(12345.00000)
But this alone will not be enough in case where you don't want to truncate. Using style and dataformats, you can avoid truncation. E.g.
CellStyle cellStyle = wb.createCellStyle();
DataFormat df = wb.createDataFormat();
cellStyle.setDataFormat(df.getFormat("0.0")); //you can adjust it as per your requirments
cell.setCellStyle(cellStyle);

Applying specific cell data format using POI

I need to apply specific data format to cell.
XSSFCellStyle cellStyle = workBook.createCellStyle();
XSSFDataFormat format = workBook.createDataFormat();
cellStyle.setDataFormat(format.getFormat("m/d/yy h:mm"));
dataCell.setCellType(1); //String
dataCell.setCellStyle(cellStyle);
The data is being written but the problem is that the format is applied only when I open excel sheet (in Excel application), click inside the cell with my data.
And then pressing Enter key.
Only then the format is applied.
How can I apply the format without clicking on every cell?
Your problem is that you're setting the cell to be a string. For the most part, cell formatting rules only apply to numeric cells. They don't apply to string cells, those don't get formatted (as they're already formatted to a string!)
XSSFCellStyle cellStyle = workBook.createCellStyle();
XSSFDataFormat format = workBook.createDataFormat();
cellStyle.setDataFormat(format.getFormat("m/d/yy h:mm"));
dataCell.setCellStyle(cellStyle);
// Set Cell Type not really needed, the setCellValue does it
dataCell.setCellType(Cell.CELL_TYPE_NUMERIC);
// Set a date value (2012-06-05 08:50)
dataCell.setCellValue(new Date(1338878999635));
When you open that in Excel, it ought to be have as expected
This is how you change the cell format to Date.
var workBook = new XSSFWorkbook();
var sheet = workBook.CreateSheet("Sheet1");
var dateStyle = workBook.CreateCellStyle();
var dataFormat = workBook.CreateDataFormat();
dateStyle.DataFormat = dataFormat.GetFormat("M/D/YYYY");
row.CreateCell(0).SetCellValue(item.ModifiedDate.HasValue ?
item.ModifiedDate.Value.ToShortDateString(): "");
row.Cells[0].CellStyle = dateStyle; // This will change your cell to date
format.

Basic Excel currency format with Apache POI

I'm able to get cells to format as Dates, but I've been unable to get cells to format as currency... Anyone have an example of how to create a style to get this to work? My code below show the styles I'm creating... the styleDateFormat works like a champ while styleCurrencyFormat has no affect on the cell.
private HSSFWorkbook wb;
private HSSFCellStyle styleDateFormat = null;
private HSSFCellStyle styleCurrencyFormat = null;
......
public CouponicsReportBean(){
wb = new HSSFWorkbook();
InitializeFonts();
}
public void InitializeFonts()
{
styleDateFormat = wb.createCellStyle();
styleDateFormat.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy"));
styleCurrencyFormat = wb.createCellStyle();
styleCurrencyFormat.setDataFormat(HSSFDataFormat.getBuiltinFormat("$#,##0.00"));
}
After digging through the documentation a bit more, I found the answer:
http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFDataFormat.html
Just need to find an appropriate pre-set format and supply the code.
styleCurrencyFormat.setDataFormat((short)8); //8 = "($#,##0.00_);[Red]($#,##0.00)"
Here are more examples:
http://www.roseindia.net/java/poi/setDataFormat.shtml
For at least Excel 2010:
Go into Excel. Format a cell they way you want it.
Then go back into the format dialogue. Select custom.
Copy paste the text it has on the top row under Type: into
createHelper.createDataFormat().getFormat("<here>");
Example:
createHelper.createDataFormat().getFormat("_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(#_)"); //is the "Accounting" format.
Make sure you set your populate your cells by using a double.
Using the index may cause problems with different versions of Excel. Note that the new format you create above ends up in the custom dialogue from step two.
Just an update to above reply. short '8' doesn't work for me but the '7' does.
cell.setCellValue(416.17);
cellStyle.setDataFormat((short)7);
cell.setCellStyle(cellStyle);
O/P is $416.00
You can try this code to format your cell with currency mode (with thowsand separator like used in Brazil or Germany. Eg. 12.345,67):
HSSFCellStyle cell = yourWorkBook.createCellStyle();
CreationHelper ch = yourWorkBook.getCreationHelper();
cell.setDataFormat(ch.createDataFormat().getFormat("#,##0.00;\\-#,##0.00"));

Categories

Resources