Apache POI: non-deprecated way to get cell content? [duplicate] - java

I'm reading an excel-file (file extension xlsx) using org.apache.poi 3.15.
This is my code:
try (FileInputStream fileInputStream = new FileInputStream(file); XSSFWorkbook workbook = new XSSFWorkbook(file)) {
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "(Integer)\t");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "(String)\t");
break;
}
}
System.out.println("");
}
} catch (Exception e) {
e.printStackTrace();
}
I get a warning that cell.getCellType() is deprecated. Can anyone tell me the alternative?

The accepted answer shows the reason for the deprecation but misses to name the alternative:
CellType getCellTypeEnum()
where the CellType is the enum decribing the type of the cell.
The plan is to rename getCellTypeEnum() back to getCellType() in POI 4.0.

You can use:
cell.getCellTypeEnum()
Further to compare the cell type, you have to use CellType as follows:-
if(cell.getCellTypeEnum() == CellType.STRING){
.
.
.
}
You can Refer to the documentation. Its pretty helpful:-
https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html

Use getCellType()
switch (cell.getCellType()) {
case BOOLEAN :
//To-do
break;
case NUMERIC:
//To-do
break;
case STRING:
//To-do
break;
}

FileInputStream fis = new FileInputStream(new File("C:/Test.xlsx"));
//create workbook instance
XSSFWorkbook wb = new XSSFWorkbook(fis);
//create a sheet object to retrieve the sheet
XSSFSheet sheet = wb.getSheetAt(0);
//to evaluate cell type
FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
for(Row row : sheet)
{
for(Cell cell : row)
{
switch(formulaEvaluator.evaluateInCell(cell).getCellTypeEnum())
{
case NUMERIC:
System.out.print(cell.getNumericCellValue() + "\t");
break;
case STRING:
System.out.print(cell.getStringCellValue() + "\t");
break;
default:
break;
}
}
System.out.println();
}
This code will work fine. Use getCellTypeEnum() and to compare use just NUMERIC or STRING.

From the documentation:
int getCellType()
Deprecated. POI 3.15. Will return a CellType enum in the future.
Return the cell type. Will return CellType in version 4.0 of POI. For forwards compatibility, do not hard-code cell type literals in your code.

It looks that 3.15 offers no satisfying solution: either one uses the old style with Cell.CELL_TYPE_*, or we use the method getCellTypeEnum() which is marked as deprecated.
A lot of disturbances for little add value...

For POI 3.17 this worked for me
switch (cellh.getCellTypeEnum()) {
case FORMULA:
if (cellh.getCellFormula().indexOf("LINEST") >= 0) {
value = Double.toString(cellh.getNumericCellValue());
} else {
value = XLS_getDataFromCellValue(evaluator.evaluate(cellh));
}
break;
case NUMERIC:
value = Double.toString(cellh.getNumericCellValue());
break;
case STRING:
value = cellh.getStringCellValue();
break;
case BOOLEAN:
if(cellh.getBooleanCellValue()){
value = "true";
} else {
value = "false";
}
break;
default:
value = "";
break;
}

You can do this:
private String cellToString(HSSFCell cell) {
CellType type;
Object result;
type = cell.getCellType();
switch (type) {
case NUMERIC : //numeric value in excel
result = cell.getNumericCellValue();
break;
case STRING : //String Value in Excel
result = cell.getStringCellValue();
break;
default :
throw new RuntimeException("There is no support for this type of value in Apche POI");
}
return result.toString();
}

Related

How to handle the Unexpected arg eval type (org.apache.poi.ss.formula.eval.MissingArgEval) in apache POI

I am trying to parse an excel file which contains various kind of fomulas.The code i have writen is able to parse almost all kind of formulas but , some of the cells contains reference of another cell like =C20 like this. In this type of cells my code is having
Unexpected arg eval type (org.apache.poi.ss.formula.eval.MissingArgEval)
My code is able to handle below types
=IF(D14=0;" - ";E14/D14), =IF('TreeData-Report'!AB92="H";"";SUM('TreeData-Report'!C92:'TreeData-Report'!E92)) .. etc.
But when it is coming as a single argument like C20,D14 ..etc, it is failing .
And i will post the code where exactly it is failing
while (cellIterator.hasNext() && cellIteratorTotal.hasNext()) {
cellCount++;
Cell currentCell = cellIterator.next();
Cell currentCellTotal = cellIteratorTotal.next();
String cellValue = excelManager.evalCell(currentCell);// from here i am sending the value for validation
String cellValueTotal = excelManager.evalCell(currentCellTotal);
This is the validator class where i am chekcing thetype of the cell value
public String evalCell(Cell cell) {
String cellValue = "";
if (cell.getCellTypeEnum() == CellType.STRING) {
cellValue = cell.getStringCellValue();
} else if (cell.getCellTypeEnum() == CellType.NUMERIC) {
cellValue = formatDoubleNumberToString(cell.getNumericCellValue());
} else if (cell.getCellTypeEnum() == CellType.FORMULA) {
cellValue = evalFormulaCell(cell);
}
return cellValue.trim();
}
public String evalFormulaCell(Cell cell) {
String cellValue = "";
switch (formulaEvaluator.evaluateFormulaCellEnum(cell)) {//Here the code fails if cell contains C20,D14.. etc this type of values
case BOOLEAN:
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case NUMERIC:
cellValue = formatDoubleNumberToString(cell.getNumericCellValue());
break;
case STRING:
cellValue = cell.getStringCellValue();
break;
case BLANK:
cellValue = "";
break;
case ERROR:
cellValue = "Error Occurred with Code :"+String.valueOf(cell.getErrorCellValue());
break;
case _NONE:
cellValue = "";
break;
// CELL_TYPE_FORMULA will never occur
case FORMULA:
cellValue = "";
break;
}
return cellValue;
}
Please help me to handle this kind of errors , and i am very sorry i am am not able to make my post crystal clear.Thanks in advance.I am using poi 3.16 jar.

Alternative to deprecated getCellType

I'm reading an excel-file (file extension xlsx) using org.apache.poi 3.15.
This is my code:
try (FileInputStream fileInputStream = new FileInputStream(file); XSSFWorkbook workbook = new XSSFWorkbook(file)) {
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "(Integer)\t");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "(String)\t");
break;
}
}
System.out.println("");
}
} catch (Exception e) {
e.printStackTrace();
}
I get a warning that cell.getCellType() is deprecated. Can anyone tell me the alternative?
The accepted answer shows the reason for the deprecation but misses to name the alternative:
CellType getCellTypeEnum()
where the CellType is the enum decribing the type of the cell.
The plan is to rename getCellTypeEnum() back to getCellType() in POI 4.0.
You can use:
cell.getCellTypeEnum()
Further to compare the cell type, you have to use CellType as follows:-
if(cell.getCellTypeEnum() == CellType.STRING){
.
.
.
}
You can Refer to the documentation. Its pretty helpful:-
https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html
Use getCellType()
switch (cell.getCellType()) {
case BOOLEAN :
//To-do
break;
case NUMERIC:
//To-do
break;
case STRING:
//To-do
break;
}
FileInputStream fis = new FileInputStream(new File("C:/Test.xlsx"));
//create workbook instance
XSSFWorkbook wb = new XSSFWorkbook(fis);
//create a sheet object to retrieve the sheet
XSSFSheet sheet = wb.getSheetAt(0);
//to evaluate cell type
FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
for(Row row : sheet)
{
for(Cell cell : row)
{
switch(formulaEvaluator.evaluateInCell(cell).getCellTypeEnum())
{
case NUMERIC:
System.out.print(cell.getNumericCellValue() + "\t");
break;
case STRING:
System.out.print(cell.getStringCellValue() + "\t");
break;
default:
break;
}
}
System.out.println();
}
This code will work fine. Use getCellTypeEnum() and to compare use just NUMERIC or STRING.
From the documentation:
int getCellType()
Deprecated. POI 3.15. Will return a CellType enum in the future.
Return the cell type. Will return CellType in version 4.0 of POI. For forwards compatibility, do not hard-code cell type literals in your code.
It looks that 3.15 offers no satisfying solution: either one uses the old style with Cell.CELL_TYPE_*, or we use the method getCellTypeEnum() which is marked as deprecated.
A lot of disturbances for little add value...
For POI 3.17 this worked for me
switch (cellh.getCellTypeEnum()) {
case FORMULA:
if (cellh.getCellFormula().indexOf("LINEST") >= 0) {
value = Double.toString(cellh.getNumericCellValue());
} else {
value = XLS_getDataFromCellValue(evaluator.evaluate(cellh));
}
break;
case NUMERIC:
value = Double.toString(cellh.getNumericCellValue());
break;
case STRING:
value = cellh.getStringCellValue();
break;
case BOOLEAN:
if(cellh.getBooleanCellValue()){
value = "true";
} else {
value = "false";
}
break;
default:
value = "";
break;
}
You can do this:
private String cellToString(HSSFCell cell) {
CellType type;
Object result;
type = cell.getCellType();
switch (type) {
case NUMERIC : //numeric value in excel
result = cell.getNumericCellValue();
break;
case STRING : //String Value in Excel
result = cell.getStringCellValue();
break;
default :
throw new RuntimeException("There is no support for this type of value in Apche POI");
}
return result.toString();
}

Reading cell content as rich text using Apache POI. Handling numeric cells when using cell.getRichStringCellValue () method

I want to read a cell value from an Excel Spreadsheet as a rich text, not String, but an exception is thrown when the cell type is numeric and I am using cell.getRichStringCellValue () method . What would be a good approach to handle this problem?
You need to follow the approach carefully and lovingly laid out in the Apache POI documentation (who'd have thought?!). You'll want to do something like:
import org.apache.poi.ss.usermodel.*;
Workbook wb = WorkbookFactory.create(new File("input.xls"));
Sheet sheet1 = wb.getSheetAt(0);
for (Row row : sheet1) {
for (Cell cell : row) {
CellReference cellRef = new CellReference(row.getRowNum(), cell.getColumnIndex());
System.out.print(cellRef.formatAsString());
System.out.print(" - ");
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
RichTextString contents = cell.getRichStringCellValue();
// TODO Handle contents
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
// TODO Handle Date value
} else {
double number = cell.getNumericCellValue();
// TODO Handle number
}
break;
case Cell.CELL_TYPE_BOOLEAN:
boolean value = cell.getBooleanCellValue();
// TODO Handle
break;
case Cell.CELL_TYPE_FORMULA:
// Either get formula, or check last value, or evaluate
break;
default:
// Shouldn't happen
}
}
}
Then add your own logic for handling the contents now that you have fetched them

xssf How to get anything as String

I try to parse an excel file into XML using apache poi xssf.
Now having a cell and not knowing what is in it I just want to get a String out of it.
But when I use
cell.getStringCellValue()
it throws an exception, what is not very suprising since it is documented this way.
So I build my way around that by checking weather it is a numeric or a text cell. But what to do with formula cells. They may contain numbers like
= A2 + B2
What gives me the sum (e.g. 4) or a reference to another text
= C2
what might refer to a text like "Hans".
How can I know what is really in my cell and how do I get a String out of it?
Excel stores some cells as strings, but most as numbers with special formatting rules applied to them. If you want to get the raw values, use a switch statement based on cell.getCellType() as some of the other answers have shown.
However, if what you want is a string of the cell, showing the same as what Excel would show, based on applying all the formatting rules on the cell + cell types, then Apache POI has a class to do just that - DataFormatter
All you need to do is something like:
Workbook wb = WorkbookFactory.create(new File("myfile.xls"));
DataFormatter df = new DataFormatter();
Sheet s = wb.getSheetAt(0);
Row r1 = s.getRow(0);
Cell cA1 = r1.getCell(0);
String asItLooksInExcel = df.formatCellValue(cA1);
Doesn't matter what the cell type is, DataFormatter will format it as best it can for you, using the rules applied in Excel, and giving you back a nicely formatted string at the end.
The accepeted answer does not work with formula cells (in the result String you get the formula, not the result of the formula).
Here is what worked for me in every case:
final XSSFWorkbook workbook = new XSSFWorkbook(file);
final DataFormatter dataFormatter = new DataFormatter();
final FormulaEvaluator objFormulaEvaluator = new XSSFFormulaEvaluator(workbook);
final Cell cell = ...;
objFormulaEvaluator.evaluate(cell);
final String cellValue = dataFormatter.formatCellValue(cell, objFormulaEvaluator);
You can add check on CELL type as below :
switch(cell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue() + "\t\t");
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "\t\t");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "\t\t");
break;
}
Try this one
case Cell.CELL_TYPE_FORMULA:
switch (cell.getCachedFormulaResultType()) {
case Cell.CELL_TYPE_STRING:
System.out.println(cell.getRichStringCellValue().getString());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
System.out.println(cell.getDateCellValue() + "");
} else {
System.out.println(cell.getNumericCellValue());
}
break;
}
break;

how to store a parsed .xslx file in a dto

Code:parses through the excel file using poi and prints the output in the console and also creates a new excel file to show the output.
XSSFWorkbook workbook = new XSSFWorkbook(fileName);
XSSFSheet sheet = workbook.getSheetAt(0);
XSSFRow row ;
XSSFCell cell;
Iterator<Row> rows = sheet.rowIterator();
while(rows.hasNext())
{
row = (XSSFRow)rows.next();
Iterator<Cell> cells = row.cellIterator();
while(cells.hasNext())
{
cell = (XSSFCell)cells.next();
switch(cell.getCellType())
{
case Cell.CELL_TYPE_BOOLEAN: System.out.println(cell.getBooleanCellValue()+"\t\t");
break;
case Cell.CELL_TYPE_NUMERIC: System.out.println(cell.getNumericCellValue()+ "\t\t");
break;
case Cell.CELL_TYPE_STRING:System.out.println(cell.getStringCellValue()+ "\t\t");
break;
}
}System.out.println("");
}fileName.close();
FileOutputStream out = new FileOutputStream(new File("C://data.xlsx"));
workbook.write(out);
out.close();
Output:
Id
Name
Location
Role
Salary
111.0
Kumar
Chennai
Developer
1000.0
112.0
Larsen
Bangalore
Developer
2000.0
Queries:
1. How to get the output in the same format as in excel?
2. How to store the output in a DTO object?
try this way to add Values DTO
Create one Student DTO with properties like and setter and getters with Id,Name,Location,Role,Salary
while(rows.hasNext())
{
row = (XSSFRow)rows.next();
Iterator<Cell> cells = row.cellIterator();
StudentDTO std = new StudentDTO();
while(cells.hasNext())
{
cell = (XSSFCell)cells.next();
switch(cell.getCellType())
{
case Cell.CELL_TYPE_BOOLEAN: System.out.println(cell.getBooleanCellValue()+"\t\t");
std.setId(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_NUMERIC: System.out.println(cell.getNumericCellValue()+ "\t\t");
std.setName(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:System.out.println(cell.getStringCellValue()+ "\t\t");
std.setLocation(cell.getStringCellValue());
break;
}
}System.out.println("");
}

Categories