Date cell mask doesn't come correctly - java

I'm reading an .xlsx file with Apache POI that has a cell with the following value: Jan/17.
But when I do check the cell variable with
String pattern = cell.getCellStyle().getDataFormatString()
pattern return wrong mask: mmm-yy and wrong value Jan-17.
I tried to use DataFormatter, but return the same error
I tried to use CellDateFormatter, but return the same error too
Replace the character "-" to "/" is not an option because it can be used "-" in file.

This is not an error but is how Microsoft Excel localizes the date formats. Excel files always store formats in en_US locale. That is mmm-yy for this format. It is the Excel built-in format with ID 17 (0x11, "mmm-yy"). See BuiltinFormats. It gets applied when user inputs only month and year in a cell. For example: 1/17, which is month 1 in year 17.
In my German Excel this looks like so using German Windows locale:
The Excel GUI then interprets that format different dependent on the Excel and/or Windows locale settings. For example, if I change the Windows locale settings to Portuguese (Brasil) in Control Panel - Time and Region:
then it looks like so:
Note, nothing has changed in Excel file. Only Windows locale settings have changed.
Unfortunately Apache POI DataFormatter fails to interpret locale settings exactly like Excel does.
Following code interprets the Excel built-in format with ID 17 (0x11, "mmm-yy") as mmm-yy = Jan-17 using en_US locale. This is correct. But it interprets it as mmm.-yy = Jan.-17 using de_DE locale. This is wrong, should be mmm yy = Jan 17 like in Excel. And using pt_BR locale it interprets it as mmm.-yy= jan.-17. This is wrong too, should be mmm/yy = jan/17 like in Excel.
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("./ExcelExampleIn.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"));
//DataFormatter dataFormatter = new DataFormatter(new java.util.Locale("de", "DE"));
DataFormatter dataFormatter = new DataFormatter(new java.util.Locale("pt", "BR"));
// 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 pattern = cell.getCellStyle().getDataFormatString();
System.out.println(pattern);
//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();
}
}
To overcome this incorrectness in Apache POI, one could add a special data format for the mmm-yy to the DataFormatter dependent on used locale. This can be achieved using public void addFormat(java.lang.String excelFormatStr, java.text.Format format).
Complete example again:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.LocaleUtil;
import java.io.FileInputStream;
class ReadExcel {
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelExampleIn.xlsx"));
// up to apache poi 5.1.0 a FormulaEvaluator is needed to evaluate the formulas while using DataFormatter
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
//LocaleUtil.setUserLocale(new java.util.Locale("en", "US"));
//LocaleUtil.setUserLocale(new java.util.Locale("de", "DE"));
LocaleUtil.setUserLocale(new java.util.Locale("pt", "BR"));
DataFormatter dataFormatter = new DataFormatter(); // uses user locale set
// from 5.2.0 on the DataFormatter can set to use cached values for formula cells
dataFormatter.setUseCachedValuesForFormulaCells(true);
if (LocaleUtil.getUserLocale().equals(new java.util.Locale("de", "DE"))) {
dataFormatter.addFormat("mmm-yy", new java.text.SimpleDateFormat("MMM yy", new java.util.Locale("en", "US")));
} else if (LocaleUtil.getUserLocale().equals(new java.util.Locale("en", "US"))) {
dataFormatter.addFormat("mmm-yy", new java.text.SimpleDateFormat("MMM-yy", new java.util.Locale("en", "US")));
} else if (LocaleUtil.getUserLocale().equals(new java.util.Locale("pt", "BR"))) {
dataFormatter.addFormat("mmm-yy", new java.text.SimpleDateFormat("MMM/yy", new java.util.Locale("en", "US")));
}
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
String pattern = cell.getCellStyle().getDataFormatString();
System.out.println(pattern);
//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();
}
}
Note, the java.text.SimpleDateFormat always gets created usig en_US locale. Else, month abbreviations may be followed by a dot. For example: Jan. 17 or Jan./17.

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);

Apache POI Customformat(#.##0,00) does not work

We are using the apache poi 4.1.2 in our project. I am using the Excel 2013. I'm trying to format the number with Apache poi but this Format(#.##0,00) is not working. My requirement is if the cDecimalSepString is DOT(.), the number should be in Format(#,##0.00). if the cDecimalSepString is Comma(,), the number format should be in Format(#.##0,00). Format(#,##0.00) works for me, but the Format(#.##0,00) is not working. My Excel default Decimal separator(.) and thousand separator is Comma(,). When the if the cDecimalSepString is Comma(,) If I generate the Excel with Format(#,##0.00) and Change my Excel Decimal separator(,) and thousand separator is Comma(.), then it works. so my question is we always need to use this Format(#.##0,00) when generate the Excel fie with Apache POI?
CellStyle numStyle = null;
if (cDecimalSepString != null && cDecimalSepString.equals("."))
{
numStyle = workbook.createCellStyle();
short format = (short)BuiltinFormats.getBuiltinFormat("#,##0.00");
numStyle.setDataFormat(format);
}
else
{
DataFormat dataFormat = workbook.createDataFormat();
numStyle = workbook.createCellStyle();
numStyle.setDataFormat(dataFormat.getFormat("#.##0,00"));
}
string value= "1000.43";
double dValue = Double.parseDouble(value);
Cell cell = workbook.createSheet().createRow(0).createCell(0);
cell.setCellValue(dValue);
cell.setCellStyle(numStyle);
solution will be always export the number in the Format(#,##0.00) and the generated Excel file will display the number as per the Excel default settings on the user Machine.

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();
}
}

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());
}
}

How to get the formatted value of a number for a cell in Apache POI?

I wanted to get the value of a Numeric cell as a simple string.
Suppose there the type of cell is numeric with value 90%.
Now I cannot use cell.getStringCellValue() as it will throw exception.
I also cannot use cell.getNumericCellValue() as it will return me .9 and not 90%.
I want to store in db which is of type varchar2, so I want the value in string only.
I cannot change the cell type in xls as its the end user job, I have to handle this in code itself.
Also formatter does't work well as there could be different cell types in the xls...dd:mm,dd:mm:ss,formula etc.
All I want is that whatever the cell type is I need to get its value as simple String.
You can force the value to be returned as a String using the methods below
HSSFDataFormatter hdf = new HSSFDataFormatter();
System.out.println (hdf.formatCellValue(mycell));
will return "90%"
The API for this method is at http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/DataFormatter.html#formatCellValue%28org.apache.poi.ss.usermodel.Cell%29
This works directly even with an HSSFCell
it worked for me even when my Cell is an HSSFCell
i've also tried this cast - which works.
HSSFCell cell1 = (HSSFCell) row1.getCell(2);
HSSFDataFormatter hdf = new HSSFDataFormatter();
System.out.println ("formatted "+ hdf.formatCellValue(cell1));
Try
cell.getRichStringCellValue ().getString();
Have a look at this example
Here is Doc
The following code is using current apache poi versions of 2021. Now DataFormatter can be used for XSSF (Office Open XML *.xlsx) as well as for HSSF (BIFF *.xls) formats. It should be used together with FormulaEvaluator to get values from formula cells too.
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("Excel.xlsx"));
//Workbook workbook = WorkbookFactory.create(new FileInputStream("Excel.xls"));
DataFormatter dataFormatter = new DataFormatter(java.util.Locale.US);
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
String cellValue = "";
for (Sheet sheet: workbook) {
System.out.println(sheet.getSheetName());
for (Row row : sheet) {
for (Cell cell : row) {
cellValue = dataFormatter.formatCellValue(cell, formulaEvaluator);
System.out.println(cell.getAddress() + ":" + cellValue);
// do something with cellValue
}
}
}
workbook.close();
}
}

Categories