There are certain result that run in my program and it will be display in excel. Unfortunately the problem i facing was the cell can't set other value if there is null value detected. Error message i get is java null pointer.
Date invalid_dt=servPerfTracking.getInvalid_d();
cell=row.createCell(10);
if(cell.getCellType()==cell.CELL_TYPE_BLANK){
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue("Apple");
log.debug("invalid date is null");
}else if(cell.getCellType()==cell.CELL_TYPE_STRING){
cell=row.createCell(10);
cell.setCellValue(invalid_dt);
cell.setCellStyle(dataCellStyle);
log.debug("invalid date is not equal to null");
}
What you are actually doing
First, you are creating a new and empty cell. After that, you are checking the type of that cell.
By definition, the type of newly created cells is CELL_TYPE_BLANK.
What you should do
Use the method row.getCell(int columnNumber) to receive the actual cell of the current row for the specified column number.
Example
Date invalid_dt = servPerfTracking.getInvalid_d();
cell = row.getCell(10, Row.RETURN_NULL_AS_BLANK);
if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
cell.setCellValue("Apple");
log.debug("invalid date is null");
} else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
cell.setCellValue(invalid_dt);
cell.setCellStyle(dataCellStyle);
log.debug("invalid date is not equal to null");
}
Tip: You don't need to call cell.setCellType(Cell.CELL_TYPE_STRING) because it will be implicitly set by the method cell.setCellValue("Apple").
void setCellType(int cellType)
Set the cells type (numeric, formula or string).
If the cell currently contains a value, the value will be converted to match the new type, if possible.
Actually what i did for resolve it was:
String invalid_dt="";
if(servPerfTracking.getInvalid_d()!=null)
invalid_dt=servPerfTracking.getInvalid_d().toString();
cell = row.createCell(10);
cell.setCellValue(invalid_dt);
cell.setCellStyle(dataCellStyle);
Related
I'm trying to create an excel document. What I need is to have a column with type number. The problem, which I have is that not every cell in this column has a value( some of them should be empty).
I have one method, which I call in order to create the cells. I have problem when from the methods parameters get "null", because the setCellValue(double value) can't take null as parameter. This is why I decided to check if it is null to put the cell type: empty.
enter image description here
enter image description here
At the end what worked for me is: I just put something to the cell if the value is not null. This worked for me.
private void createCell(String cellStyle, String cellValue){
cell = row.createCell(cellNumber++);
cell.setCellStyle(styles.get(cellStyle));
if (cellStyle.equals("numberWithDelimiters")) {
if(cellValue!=null){
cell.setCellValue(Integer.parseInt(cellValue));
}
}else if(cellStyle.equals("date")){
Date date=new Date(Long.parseLong(cellValue));
date.setHours(0);
cell.setCellValue(date);
}else{
cell.setCellValue(cellValue);
}
}
According to the documentation
XSSFCell cell = row.createCell(1);
cell.setCellStyle(Cell.CELL_TYPE_BLANK);
cell.setCellType(Cell.CELL_TYPE_NUMERIC );
#Mohit sharma answer is deprecated, for new POI API use:
cell.setCellType(CellType.BLANK);
I am extremely new to using Apache POI (and still new to Java too, infact!) and have come across an exception that I cannot determine how to fix.
Obviously you cannot store 2 different datatypes in an array, so I selected every column with data and converted the cell format to "Text" in Excel.
I then try to store this data in an array with the following:
String cellData[][] = new String[rows][cols];
System.out.println(rows+" entries found with "+cols+" columns of data");
//iterate over every row and store cell data;
for(int i=0; i<rows; i++){
row = worksheet.getRow(i);
if(row != null){
for(int j=0;j<cols;j++){
cell = row.getCell(j);
if(cell != null){
try{
cellData[i][j] = cell.getStringCellValue();
}catch(IllegalStateException e){
System.out.println("Cell data is not a string(text)");
}
}
}
}
}
The output from this is countless rows of "Cell data is not a string(text)", where am I going wrong here? Forgive me for any oversights I am also new to Stackoverflow and want to become a valued member of the community here too :) Thanks for your advice!
EDIT: Added e.printStackTrace() as requested.
at exceltesting.ExcelTesting.main(ExcelTesting.java:80)
java.lang.IllegalStateException: Cannot get a text value from a numeric cell
at org.apache.poi.hssf.usermodel.HSSFCell.typeMismatch(HSSFCell.java:648)
at org.apache.poi.hssf.usermodel.HSSFCell.getRichStringCellValue(HSSFCell.java:725)
at org.apache.poi.hssf.usermodel.HSSFCell.getStringCellValue(HSSFCell.java:708)
Interestingly enough, when I change it from cell.getStringCellValue() to cell.getNumericCellValue() the IllegalStateException then changes to "Cannot get a numerical value from a text cell"... I think the excel document, despite converting the cells to text is not actually changing to string data and passing them as their inherent data type? Thanks again
It seems that some of the cells are of Numeric type and some of them are of String Type. You need to handle Numeric Cell Types and String Cell types separately. I have not checked on my end, but sure... the following will work.
Cell cell = row.getCell(j);
CellValue cellValue = evaluator.evaluate(cell);
switch (cellValue.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
cellData[i][j] = String.valueOf(cellValue.getNumberValue());
break;
case Cell.CELL_TYPE_STRING:
cellData[i][j] = cell.getStringCellValue();
break
}
I am trying to get the Cell from the Row by a Cell reference and I have a problem. For example I have:
row.getCell(CellReference.convertColStringToIndex("B"));
That works fine if the Column index is 1, but if Column was deleted so the B Column index became 2 and the method: CellReference.convertColStringToIndex("B") is still converting it to 1 in which case I can't get my Column, I am getting null.
So the question is how can I get the Column from the Row depending on Cell identifier which is a letter?
Take a look at my answer to a previous question:
You probably want to use the CellReference utility class to help you out. It offers conversion between Excel style letter+number references, and POI style 0-based rows+columns. When using it, you can 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 (if it's defined, else null)
I have a program reading excel sheet from a java program.
I am iterating over cells as below:
Iterator cells = row.cellIterator();
String temp;
StringBuilder sb;
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
while (cells.hasNext()) {
Cell cell = (Cell) cells.next();
temp = null;
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
temp = cell.getRichStringCellValue().getString();
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
temp = sdf.format(cell.getDateCellValue());
} else {
temp = df.format(new BigDecimal(cell.getNumericCellValue()));
}
break;
default:
}
if (temp == null || temp.equalsIgnoreCase("null")) {
sb.append("").append(";");
} else {
sb.append(temp).append(";");
}
}
As seen, I am trying to create a string builder containing values from excel row in semicolon separated way.
Issue is, if a column value is empty, I want it as an empty value in the string builder with two consecutive semicolons.
However, the call
Cell cell = (Cell) cells.next();
simply ignores the empty cells and jumps over to next non empty cell.
So the line
if (temp == null || temp.equalsIgnoreCase("null"))
is never met.
How to get a handle on empty column values as well in the iterator ?
This is virtually a duplicate of this question, and so my answer to that question basically applies exactly to you too.
The Cell Iterator only iterates over cells that are defined in the file. If the cell has never been used in Excel, it probably won't appear in the file (Excel isn't always consistent...), so POI won't see it
If you want to make sure you hit every cell, you should lookup by index instead, and either check for null cells (indicating the cell has never existed in the file), or set a MissingCellPolicy to control how you want null and blank cells to be treated
So, if you really do want to get every cell, do something like:
Row r = sheet.getRow(myRowNum);
int lastColumn = Math.max(r.getLastCellNum(), MY_MINIMUM_COLUMN_COUNT);
for (int cn=0; cn<lastColumn; cn++) {
Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
if (c == null) {
// The spreadsheet is empty in this cell
} else {
// Do something useful with the cell's contents
}
}
You can do this
int previous=0;
while(cell.hasNext())
{
Cell cell = (Cell) cells.next();
int current=cell.getColumnIndex();
int numberofsemicolons=previous-current;
for(numberofsemicolons)
{
sb.append("").append(";");
}
previous=current;
}
or you can do
int numberofcells=row.getFirstCellNum()-row.getLastCellNum();
for(i=0;i<=numberofcells;i++)
{
Cell cell = (Cell) cells.next();
int current=cell.getColumnIndex();
while(i<current)
{
sb.append("").append(";");
i++
}
}
Answer posted by #Gagravarr works perfectly for me but MissingCellPolicy is an enum now, so while getting the cell value instead of using
Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
I have used
Cell c =r.getCell(cn,Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
I am trying to read cell values excel sheet using Apache POI. One of my sheet contains percentage type as the cell type. When I read that cell using POI using cell.getNumbericValue(), its returning me the double value. If cell contains 11.24%, it is returning me 0.1124.
My problem is, I want to read the % symbol also from the cell i.e., I want to read the exact data as it is in cell as 11.24%. So, I tried it using the cell.toString(), even then it is returning me the same value as above.
Can anyone please suggest me, how to get rid of this problem.
Thanks in advance
Nandu
You can detect if a cell is formatted as a percentage by testing the cell data format string like this:
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
if (cell.getCellStyle().getDataFormatString().contains("%")) {
// Detect Percent Values
Double value = cell.getNumericCellValue() * 100;
System.out.println("Percent value found = " + value.toString() +"%");
} else {
Double value = cell.getNumericCellValue();
System.out.println("Non percent value found = " + value.toString());
}
}
This should enable you to distinguish between percentage formatted values and ordinary numeric values.
11.24% is 0.1124, which is why that's what gets stored in the file, and that's what you get when you ask for the numeric value
POI provides a utility for formatting numeric strings based on the format rules applied to the cell, which is DataFormatter. If you use that to format the cell, you'll get back a string with the contents of the cell largely as seen in Excel.
Try this:
String typeCell =cell.getCellStyle().getDataFormatString();
It gives:
"General" value for non formated cells,
"0%" for percentage formats
dd/mm/yy for date , depends of locale
I manage to parse all types in cells (Numbers, Percentage, Date, Text, Currency) I just have to check what value for which cell type it will give me back.
Because I also have to much trouble with HSSFCell.CELL_TYPE_STRING or HSSFCell.CELL_TYPE_NUMERIC.
The answer of #WeeShetland should be the accepted answer.
Instead of cell.getCellStyle().getDataFormatString().contains("%") you can use
// class level
private static final int PERCENTAGE_FORMAT = BuiltinFormats.getBuiltinFormat("0%");
...
// in some method
if (cell.getCellStyle().getDataFormat() == PERCENTAGE_FORMAT) {
...