actually i want to fetch a particular data from excel sheet (.xls and .xlsx) like i have a column name email in my excel sheet and i want to fetch only that column. This is my code which is already i wrote but this is fetching all the details.Sorry for my grammar.
package readfile;
import java.io.File;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
public class reademail {
public static void main(String[] args) throws Exception
{
File f=new File("C:\\Users\\LQRP0023\\Desktop\\try.xls");
Workbook wb=Workbook.getWorkbook(f);
Sheet s=wb.getSheet(0);
int row=s.getRows();
int col=s.getColumns();
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
Cell c=s.getCell(j,i);
System.out.print(c.getContents());
}
System.out.println("");
// TODO Auto-generated method stub
} }}
You probably want to use the CellReference utility class to help you out.
You can then do something like:
Sheet sheet = workbook.getSheet("MyInterestingSheet");
CellReference ref = new CellReference("B12");
Row r = sheet.getRow(ref.getRow());
if (r != null) {
Cell c = r.getCell(ref.getCol());
}
That will let you find the cell at a given Excel-style reference
You need to check the Cell type and call the appropriate method to get the value, e.g.:
switch(cell.getCellType()){
case Cell.CELL_TYPE_STRING:
String stringValue = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_NUMERIC:
Number numericValue = cell.getNumericCellValue();
break;
}
For cell with Date, you can use HSSFDateUtil class to check the date formatted cell and get the value, e.g.:
if(HSSFDateUtil.isCellDateFormatted(cell)){
Date dateValue = cell.getDateCellValue();
}
Related
I'm writing a program to read an xslx file using Apache POI in java, and create a search algorithm to search for s string in the records. I've written the code to print all the records but I can't seem to find how to create the search algorithm. It's meant to show records with "zgheib" only. I would really appreciate a hand. This is my code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class test {
public static void main(String[] args) throws IOException {
try
{
FileInputStream file = new FileInputStream(new File("C:\\Users\\Junaid\\Documents\\IntelliJ Projects\\ReadExcel_Bashar\\src\\assignment.xlsx"));
//Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
//Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheetAt(0);
//Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
//For each row, iterate through all the columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
//Check the cell type and format accordingly
switch (cell.getCellType())
{
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "\t");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "\t");
break;
}
}
System.out.println("");
}
file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
If the need is to get only rows where cell values contain a search string, then this can be achieved by traversing all rows and cells in the sheet and get the cell values. If the cell value contains the search string, then add the row to a list of rows List<Row>. Since all cell values must be converted to string as the search value is a string, DataFormatter can be used. The formatCellValue methods of DataFormatter get all cell values as formatted strings. To support formula cells too, DataFormatter must be used together with FormulaEvaluator.
The following example provides a method
List<Row> getRows(Sheet sheet, DataFormatter formatter, FormulaEvaluator evaluator, String searchValue) {
List<Row> result = new ArrayList<Row>();
String cellValue = "";
for (Row row : sheet) {
for (Cell cell : row) {
cellValue = formatter.formatCellValue(cell, evaluator);
if (cellValue.contains(searchValue)) {
result.add(row);
break;
}
}
}
return result;
}
This method traverses the given sheet and gets all cell values using DataFormatter and FormulaEvaluator. If found cell value contains the search value, the row is added to the list, else not. So the result is a List<Row> which only contains rows where cells contain the search string.
Complete example:
import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
import java.util.List;
import java.util.ArrayList;
class ReadExcelRows {
//get only rows where cell values contain search string
static List<Row> getRows(Sheet sheet, DataFormatter formatter, FormulaEvaluator evaluator, String searchValue) {
List<Row> result = new ArrayList<Row>();
String cellValue = "";
for (Row row : sheet) {
for (Cell cell : row) {
cellValue = formatter.formatCellValue(cell, evaluator);
if (cellValue.contains(searchValue)) {
result.add(row);
break;
}
}
}
return result;
}
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("./inputFile.xlsx"));
//Workbook workbook = WorkbookFactory.create(new FileInputStream("./inputFile.xls"));
DataFormatter formatter = new DataFormatter();
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
Sheet sheet = workbook.getSheetAt(0);
List<Row> filteredRows = getRows(sheet, formatter, evaluator, "zgheib");
for (Row row : filteredRows) {
for (Cell cell : row) {
System.out.print(cell.getAddress()+ ":" + formatter.formatCellValue(cell, evaluator));
System.out.print(" ");
}
System.out.println();
}
workbook.close();
}
}
See the picture below, I am trying to write a program that can "scan" a given row with no limit of from which cell to which cell, then, find all the "strings" that are identical the same. Is it possible to do that? Thank you.
To give an example so that this will not be very confusing, for ex.: On row H, you see there are customer's names, there are "Coresystem", "Huawei", "VIVO", etc... Now the problem is, what if the names are not grouped together, they are all split up, like, On H5, it will be "Huawei" and On H9, it will be "VIVO", etc, it's like, unlike the picture provided below, on row H all the names are split up, and I want apache POI to find all the customers that have the same name, for ex.: If user enter "coReSysteM", it should be able to find all the .equalsIgnoreCase of all Coresystem on row H (btw, the user should be able to enter the customer's name that they want to enter and the row they want to search for), and display from A5, B5, C5, D5, E5, F5, G5, H5 to A14, B14, C14, D14, E14, F14, G14, H5, is it possible?
I was thinking about setting a formula to find all the customer, for example: =CountIf
These are the code that I am currently trying to do, but then I am stuck with it:
package excel_reader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelReader2d {
ExcelReader link = new ExcelReader();
Scanner scan = new Scanner(System.in);
// instance data
private static int numberGrid[][] = null;
private static String stringGrid[][] = null;
// constructor
public ExcelReader2d(String desLink) {
}
// methods
public void ExeScan() throws FileNotFoundException, IOException {
Scanner scan = new Scanner(System.in);
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("C:\\Users\\Sonic\\Desktop\\20191223 IMPORTS.xlsx"));
XSSFSheet sheet = workbook.getSheetAt(0);
final int rowStart = Math.min(15, sheet.getFirstRowNum()), rowEnd = Math.max(1400, sheet.getLastRowNum());
System.out.print("Enter the rows that you want to search for: (for ex. the rows that stores customer's name) ");
int searchRows = scan.nextInt();
System.out.print("Enter the customer's name that you are looking for: ");
String name = scan.nextLine();
//int rowNum;
// Search given row
XSSFRow row = sheet.getRow(searchRows);
try {
for (int j = 4; j < rowEnd; j++) {
Row r = sheet.getRow(j);
if (name.equalsIgnoreCase(name)) {
row.getCell(j).getStringCellValue();
}
// skip to next iterate if that specific cell is empty
if (r == null)
continue;
}
} catch (Exception e){
System.out.println("Something went wrong.");
}
}
}
ps. I know that this will be very confusing, but please feel free to ask for any kind of questions to help you get rid of the confusion and help me either because this has been a problem for me. Thank you very much and I will super appreciated for your help. Currently using apache poi, vscode, java.
I would iterate over the rows in the sheet and get the string content of cell 7 (H) from each row. If that string fulfills the requirement equalsIgnoreCase the searched value, that row is one of the result rows, else not.
One could collect the result rows in a List<Row>. Then this List contains the result rows after that.
Example:
ExcelWorkbook.xlsx:
Code:
import org.apache.poi.ss.usermodel.*;
import java.util.List;
import java.util.ArrayList;
import java.io.FileInputStream;
public class ExcelReadRowsByColumnValue {
public static void main(String[] args) throws Exception {
String filePath = "./ExcelWorkbook.xlsx";
String toSearch = "coresystem";
int searchColumn = 7; // column H
List<Row> results = new ArrayList<Row>();
DataFormatter dataFormatter = new DataFormatter();
Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) { // iterate over all rows in the sheet
Cell cellInSearchColumn = row.getCell(searchColumn); // get the cell in seach column (H)
if (cellInSearchColumn != null) { // if that cell is present
String cellValue = dataFormatter.formatCellValue(cellInSearchColumn, formulaEvaluator); // get string cell value
if (toSearch.equalsIgnoreCase(cellValue)) { // if cell value equals the searched value
results.add(row); // add that row to the results
}
}
}
// print the results
System.out.println("Found results:");
for (Row row : results) {
int rowNumber = row.getRowNum()+1;
System.out.print("Row " + rowNumber + ":\t");
for (Cell cell : row) {
String cellValue = dataFormatter.formatCellValue(cell, formulaEvaluator);
System.out.print(cellValue + "\t");
}
System.out.println();
}
workbook.close();
}
}
Result:
I have defined a list of valuses my_list in one excel sheet as follow:
In another excel sheet, I reference for some cells to that list sothat this list is shown as dropdown in the cell as follows:
Using poi, I go throw excel sheet rows/columns and read cells for cell.
I get value of cells using method:
cell.getStringCellValue()
My question is how to get the name of the list my_list from the cell?
This problem contains multiple different problems.
First we need get sheet's data validations and then for each data validation get Excel cell ranges the data validation applies to. If the cell is in one of that cell ranges and if data validation is a list constraint then do further proceedings. Else return a default value.
If we have a explicit list like "item1, item2, item3, ..." then return this.
Else if we have a formula creating the list and is formula1 a area reference to a range in same sheet, then get all cells in that cell range and put their values in an array and return this.
Else if we have a formula creating the list and is formula1 a reference to a defined name in Excel, then get the Excel cell range the name refers to. Get all cells in that cell range and put their values in an array and return this.
Complete Example. The ExcelWorkbook contains the data validation in first sheet cell D1.
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.FileInputStream;
import java.util.List;
public class ExcelGetDataValidationList {
static String[] getDataFromAreaReference(AreaReference areaReference, Sheet sheet) {
DataFormatter dataFormatter = new DataFormatter();
Workbook workbook = sheet.getWorkbook();
CellReference[] cellReferences = areaReference.getAllReferencedCells(); // get all cells in that cell range
String[] listValues = new String[cellReferences.length]; // and put their values in an array
for (int i = 0 ; i < cellReferences.length; i++) {
CellReference cellReference = cellReferences[i];
if (cellReference.getSheetName() == null) {
listValues[i] = dataFormatter.formatCellValue(
sheet.getRow(cellReference.getRow()).getCell(cellReference.getCol())
);
} else {
listValues[i] = dataFormatter.formatCellValue(
workbook.getSheet(cellReference.getSheetName()).getRow(cellReference.getRow()).getCell(cellReference.getCol())
);
}
}
return listValues;
}
static String[] getDataValidationListValues(Sheet sheet, Cell cell) {
List<? extends DataValidation> dataValidations = sheet.getDataValidations(); // get sheet's data validations
for (DataValidation dataValidation : dataValidations) {
CellRangeAddressList addressList = dataValidation.getRegions(); // get Excel cell ranges the data validation applies to
CellRangeAddress[] addresses = addressList.getCellRangeAddresses();
for (CellRangeAddress address : addresses) {
if (address.isInRange(cell)) { // if the cell is in that cell range
DataValidationConstraint constraint = dataValidation.getValidationConstraint();
if (constraint.getValidationType() == DataValidationConstraint.ValidationType.LIST) { // if it is a list constraint
String[] explicitListValues = constraint.getExplicitListValues(); // if we have a explicit list like "item1, item2, item3, ..."
if (explicitListValues != null) return explicitListValues; // then return this
String formula1 = constraint.getFormula1(); // else if we have a formula creating the list
System.out.println(formula1);
Workbook workbook = sheet.getWorkbook();
AreaReference areaReference = null;
try { // is formula1 a area reference?
areaReference = new AreaReference(formula1,
(workbook instanceof XSSFWorkbook)?SpreadsheetVersion.EXCEL2007:SpreadsheetVersion.EXCEL97
);
String[] listValues = getDataFromAreaReference(areaReference, sheet); //get data from that area reference
return listValues; // and return this
} catch (Exception ex) {
//ex.printStackTrace();
// do nothing as creating AreaReference had failed
}
List<? extends Name> names = workbook.getNames(formula1); // is formula1 a reference to a defined name in Excel?
for (Name name : names) {
String refersToFormula = name.getRefersToFormula(); // get the Excel cell range the name refers to
areaReference = new AreaReference(refersToFormula,
(workbook instanceof XSSFWorkbook)?SpreadsheetVersion.EXCEL2007:SpreadsheetVersion.EXCEL97
);
String[] listValues = getDataFromAreaReference(areaReference, sheet); //get data from that area reference
return listValues; // and return this
}
}
}
}
}
return new String[]{}; // per default return an empy array
}
public static void main(String[] args) throws Exception {
//String filePath = "ExcelWorkbook.xls";
String filePath = "ExcelWorkbook.xlsx";
Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));
Sheet sheet = workbook.getSheetAt(0);
Row row = sheet.getRow(0); if (row == null) row = sheet.createRow(0); // row 1
Cell cell = row.getCell(3); if (cell == null) cell = row.createCell(3); // cell D1
System.out.println(cell.getAddress() + ":" + cell);
String[] dataValidationListValues = getDataValidationListValues(sheet, cell);
for (String dataValidationListValue : dataValidationListValues) {
System.out.println(dataValidationListValue);
}
workbook.close();
}
}
Note: Current Excel versions allow data validation list reference to be a direct area reference to another sheet without using a named range. But this is nothing what apache poi can get. Apache poi is on Excel 2007 level only.
The my_list your mean is Define Name in excel, honestly i don't know is apache-poi can do it or not. But this is may a clue, you can get the my_list formula using .getRefersToFormula();, please try the bellow code :
String defineNameFromExcel = "my_list";
List define = new ArrayList<>();
define = myExcel.getAllNames();
Iterator<List> definedNameIter = define.iterator();
while(definedNameIter.hasNext()) {
Name name = (Name) definedNameIter.next();
if(name.getNameName().equals(defineNameFromExcel)) {
String sheetName = name.getSheetName();
String range = name.getRefersToFormula();
range = range.substring(range.lastIndexOf("!"));
System.out.println(sheetName);
System.out.println(range);
}
}
It will get sheet name and range, with the information may you can extract for get the value you want, hope this helps.
Reference
I have created this code to read the contents of excel files using Apache POI. I am using eclipse as editor but when i ran the code i have problem in the line that I have in bold. What's the problem?
The content of excel is the following:
Emp ID Name Salary
1.0 john 2000000.0
2.0 dean 4200000.0
3.0 sam 2800000.0
4.0 cass 600000.0
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
public class ExcelRead {
public static void main(String[] args) throws Exception {
File excel = new File ("C:\\Users\\Efi\\Documents\\test.xls");
FileInputStream fis = new FileInputStream(excel);
HSSFWorkbook wb = new HSSFWorkbook(fis);
HSSFSheet ws = wb.getSheet("Input");
int rowNum = ws.getLastRowNum()+1;
int colNum = ws.getRow(0).getLastCellNum();
String[][] data = new String[rowNum][colNum];
for (int i=0; i<rowNum; i++){
HSSFRow row = ws.getRow(i);
for (int j=0; j<colNum; j++){
HSSFCell cell = row.getCell(j);
String value = cellToString(cell);
data[i][j] = value;
System.out.println("The value is" + value);
}
}
}
public static String cellToString (HSSFCell cell){
int type;
Object result;
type = cell.getCellType();
switch(type) {
case 0://numeric value in excel
result = cell.getNumericCellValue();
break;
case 1: //string value in excel
result = cell.getStringCellValue();
break;
case 2: //boolean value in excel
result = cell.getBooleanCellValue ();
break;
default:
***throw new RunTimeException("There are not support for this type of
cell");***
}
return result.toString();
}
}
There are additional cell types besides the ones you are capturing in your switch statement. You have cases for 0 (CELL_TYPE_NUMERIC), 1 (CELL_TYPE_STRING), and 2, but 2 is CELL_TYPE_FORMULA. Here are the additional possible values:
3: CELL_TYPE_BLANK
4: CELL_TYPE_BOOLEAN
5: CELL_TYPE_ERROR
Use the Cell constants for the cell type in your switch statement instead of integer literals, and use all 6 of them to capture all possible cases.
And as #Vash has already suggested, include the actual cell type in your RuntimeException message.
Check this library that I've created for reading both XLSX, XLS and CSV files pretty easily. It uses Apache POI for processing excel files and converts excel rows into a list of Java beans based on your configuration.
Here is an example:
RowConverter<Country> converter = (row) -> new Country(row[0], row[1]);
ExcelReader<Country> reader = ExcelReader.builder(Country.class)
.converter(converter)
.withHeader()
.csvDelimiter(';')
.sheets(1)
.build();
List<Country> list;
list = reader.read("src/test/resources/CountryCodes.xlsx");
list = reader.read("src/test/resources/CountryCodes.xls");
list = reader.read("src/test/resources/CountryCodes.csv");
With following excel and bean files:
public static class Country {
public String shortCode;
public String name;
public Country(String shortCode, String name) {
this.shortCode = shortCode;
this.name = name;
}
}
Excel:
Code Country
ad Andorra
ae United Arab Emirates
af Afghanistan
ag Antigua and Barbuda
...
Using XSSFWorkbook and XSSFSheet did not help me read .xls, but I used this code and it helps me read the .xls and xlsx files:
public static void readExcelFile(File file) throws IOException, InvalidFormatException {
Workbook workbook = WorkbookFactory.create(new File(file.toString()));
Integer sheet = workbook.getNumberOfSheets();
DataFormatter dataFormatter = new DataFormatter();
for (int i = 0; i < sheet; i++) {
Sheet s = workbook.getSheetAt(i);
Iterator<Row> rowIterator = s.rowIterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
printCellValue(cell);
// both work perfect
// printCellValue(cell);
/*String cellValue = dataFormatter.formatCellValue(cell);
System.out.print(cellValue + "\t");*/
}
System.out.println();
}
}
}
public static void printCellValue(Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getRichStringCellValue().getString());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
System.out.print(cell.getDateCellValue());
} else {
System.out.print(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_FORMULA:
System.out.print(cell.getCellFormula());
break;
case Cell.CELL_TYPE_BLANK:
System.out.print(" ");
break;
default:
System.out.print("");
}
System.out.print("\t");
}
You should amend that RuntimeException with information about what type is not supported with your switch statement. Then you will be able to add support for it, so no exception will be thrown.
So to see the picture of what your program is doing instead of
throw new RunTimeException("There are not support for this type of cell");
you should add
throw new RunTimeException("There are not support for type with id ["+type+"] of cell");
This will only, inform you what do you miss. How to handle this situation is up to you.
I realize the question is a little confusing, but I didn't know how else to word it. Anyway, here is the original code:
private void readFile(String excelFileName) throws FileNotFoundException, IOException {
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(excelFileName));
if (workbook.getNumberOfSheets() > 1){
System.out.println("Please make sure there is only one sheet in the excel workbook.");
}
XSSFSheet sheet = workbook.getSheetAt(0);
int numOfPhysRows = sheet.getPhysicalNumberOfRows();
XSSFRow row;
XSSFCell num;
for(int y = 1;y < numOfPhysRows;y++){ //start at the 2nd row since 1st should be category names
row = sheet.getRow(y);
poNum = row.getCell(1);
item = new Item(Integer.parseInt(poNum.getStringCellValue());
itemList.add(item);
y++;
}
}
private int poiConvertFromStringtoInt(XSSFCell cell){
int x = Integer.parseInt(Double.toString(cell.getNumericCellValue()));
return x;
}
I am getting the following error:
Exception in thread "main" java.lang.IllegalStateException: Cannot get a numeric value from a text cell
at org.apache.poi.xssf.usermodel.XSSFCell.typeMismatch(XSSFCell.java:781)
at org.apache.poi.xssf.usermodel.XSSFCell.getNumericCellValue(XSSFCell.java:199)
Even if I change it to get either a string using XSSFCell.getStringCellValue() or even XFFSCell.getRichTextValue, I get the reverse of the above error message (and I am making sure to ultimately make it an int using Integer.parseInt(XSSFCell.getStringCellValue()).
The error then reads:
Exception in thread "main" java.lang.IllegalStateException: Cannot get a text value from a numeric cell
at org.apache.poi.xssf.usermodel.XSSFCell.typeMismatch(XSSFCell.java:781)
at org.apache.poi.xssf.usermodel.XSSFCell.getNumericCellValue(XSSFCell.java:199)
I know for a fact that the excel spreadsheet column is in fact a string. I can't change the excel sheet as it is uploaded else where always using the same format and formatting each column first takes up to much processing time.
Any suggestions?
[Solution] Here is the solution code I came up with from #Wivani's help:
private long poiGetCellValue(XSSFCell cell){
long x;
if(cell.getCellType() == 0)
x = (long)cell.getNumericCellValue();
else if(cell.getCellType() == 1)
x = Long.parseLong(cell.getStringCellValue());
else
x = -1;
return x;
}
Use This as reference
switch (cell.getCellType()) {
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;
case Cell.CELL_TYPE_BOOLEAN:
System.out.println(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
System.out.println(cell.getCellFormula());
break;
default:
System.out.println();
}
You can get value as String using the format defined for this cell :
final DataFormatter df = new DataFormatter();
final XSSFCell cell = row.getCell(cellIndex);
String valueAsString = df.formatCellValue(cell);
Thanks to this answer.
Just use cell.setCellType(1); before reading cell value and get it as String always, after that you can use it in your own format(type).
Ravi
Use the below code to read any data type from xcels using poi.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Iterator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
*
* #author nirmal
*/
public class ReadWriteExcel {
public static void main(String ar[]) {
ReadWriteExcel rw = new ReadWriteExcel();
rw.readDataFromExcel();
}
Object[][] data = null;
public File getFile() throws FileNotFoundException {
File here = new File("test/com/javaant/ssg/tests/test/data.xlsx");
return new File(here.getAbsolutePath());
}
public Object[][] readDataFromExcel() {
final DataFormatter df = new DataFormatter();
try {
FileInputStream file = new FileInputStream(getFile());
//Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
//Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheetAt(0);
//Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
int rownum = 0;
int colnum = 0;
Row r=rowIterator.next();
int rowcount=sheet.getLastRowNum();
int colcount=r.getPhysicalNumberOfCells();
data = new Object[rowcount][colcount];
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
//For each row, iterate through all the columns
Iterator<Cell> cellIterator = row.cellIterator();
colnum = 0;
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
//Check the cell type and format accordingly
data[rownum][colnum] = df.formatCellValue(cell);
System.out.print(df.formatCellValue(cell));
colnum++;
System.out.println("-");
}
rownum++;
System.out.println("");
}
file.close();
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
}
I got also this bug with POI version 3.12final.
I think that the bug is registered there : https://bz.apache.org/bugzilla/show_bug.cgi?id=56702 and I put a comment there with my analysis.
Here is the workaround I used : The exception was risen by HSSFCell.getNumericCellValue which was called by DateUtil.isCellDateFormatted. DateUtil.isCellDateFormatted does 2 things :
1) check the value type of the cell by calling HSSFCell.getNumericCellValue and then DateUtil.isValidExcelDate(), which is almost pointless here I think.
2) check if the format of the cell is a date format
I copied the code of topic 2) above in a new function 'myIsADateFormat' and used it instead of DateUtil.isCellDateFormatted (that is quite dirty to copy library code, but it works...) :
private boolean myIsADateFormat(Cell cell){
CellStyle style = cell.getCellStyle();
if(style == null) return false;
int formatNo = style.getDataFormat();
String formatString = style.getDataFormatString();
boolean result = DateUtil.isADateFormat(formatNo, formatString);
return result;
}
If you need to check the value type first, you can use this too :
CellValue cellValue = evaluator.evaluate(cell);
int cellValueType = cellValue.getCellType();
if(cellValueType == Cell.CELL_TYPE_NUMERIC){
if(myIsADateFormat(cell){
....
}
}
Documentation clearly says not to setCellType to 1 instead use the DataFormatter like how Thierry has explained:
https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html#setCellType(int)
Ravi's solution works :
Just use cell.setCellType(1); before reading cell value and get it as String always, after that you can use it in your own format(type).