hi we've been reading xls and xlsx file using apache poi ing our java program, the problem is we are getting null pointer exception with two reasons.. the first 1 is the blank cell which we already solved and the other one is when we are choosing a certain column that doesn't have any record..
our program ask for the path of the excel file then the specific sheet number of the file and the specific column number of the sheet you want to read.. here is the code for reading xls file
public void readXLSFile()throws IOException{
InputStream ExcelFileToRead = new FileInputStream(path);
HSSFWorkbook wb = new HSSFWorkbook(ExcelFileToRead);
HSSFSheet sheet=wb.getSheetAt(sheetname);
HSSFRow row;
HSSFCell cell;
Iterator rows = sheet.rowIterator();
list1.clear();
while (rows.hasNext())
{
headers.clear();
row=(HSSFRow) rows.next();
// Iterator cells = row.cellIterator();
headers.add("contents");
cnt = cnt+1;
cell = row.getCell(cols);
if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING)
{
//System.out.println(cell.getStringCellValue()+"(string)");
list.add(cell.getStringCellValue());
d.add(cell.getStringCellValue());
list1.add(new KeyValuePair(cell.getStringCellValue(),""));
}
else if(cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC)
{
//System.out.println(cell.getNumericCellValue()+"(numeric)");
double num = cell.getNumericCellValue();
String num2 = String.valueOf(num);
list.add(num2);
d.add(num2);
list1.add(new KeyValuePair(num2,""));
}
else if(cell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN)
{
//System.out.println(cell.getBooleanCellValue()+"(boolean)");
String bool = String.valueOf(cell.getBooleanCellValue());
list.add(bool);
d.add(bool);
list1.add(new KeyValuePair(bool,""));
}
else
{
//U Can Handel Boolean, Formula, Errors
}
//System.out.println();
}
arrey = list.toArray(new String[list.size()]);
data.add(d);
// System.out.println(data);
model = new DefaultTableModel();
table_1.setModel(model);
table_1.setModel(model);
model.setColumnIdentifiers(new String[] {"row","contents"});
for (KeyValuePair p : list1){
int nor=table_1.getRowCount();
int n2 = nor +1;
n1 = Integer.toString(n2);
// model.addColumn(new String [] {n1});
model.addRow(new String[] {n1,p.key, p.value});
}
// model.addColumn(new String[] {n1});
}
the variable sheetname is for the excel file's sheet number
HSSFSheet sheet=wb.getSheetAt(sheetname);
and the variable cols is for the specific column you want to read
cell = row.getCell(cols);
we can read the first column of every sheet and also the second column of the second sheet but when i edited my test file the program now can only read the first column of every sheet.. the error is null pointer exception..wish you could help thanks in advance
The issue is that you never test if the cell is null!
if (cell == null)
{
System.out.println("Cell is Empty in Column:" + cols);
} else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING)
{
//code
}
As a general matter, you should be careful while handling Cell.getCellType() function, since an empty cell could be either null or be a CELL_TYPE_BLANK.
This my way to avoid Cell NullPoiterException.
Can you try it. Good luck!
/**
* Get string value of {#link Cell} object
*
* #param cell
* {#link Cell} object
* #return String value of {#link Cell} object
*/
private static String getCellValueString(Cell cell) {
String value="";
if(cell!=null) {
switch(cell.getCellType()){
case Cell.CELL_TYPE_BOOLEAN:
value=String.valueOf(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
value=BigDecimal.valueOf(
cell.getNumericCellValue()).toPlainString();
break;
case Cell.CELL_TYPE_STRING:
value=String.valueOf(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
value=String.valueOf(cell.getCellFormula());
break;
case Cell.CELL_TYPE_BLANK:
value="";
break;
}
} else {
logger.error("Cell is null");
}
return value.trim();
}
Related
I have an excel format like this:
And I have 2 functions to fill data.
This one is to fill the details
public XSSFWorkbook getDetail(List<ResultDTO> ResultDTOList, XSSFWorkbook workBook,
String sheetName) throws DaoException {
XSSFSheet sheet = workBook.getSheet(sheetName);
// first row at 9
rowIdx = 9;
int count = 0;
for (ResultDTO dto : ResultDTOList) {
colIdx = 0;
count++;
// get row
row = sheet.getRow(rowIdx);
if (row == null) {
row = sheet.createRow(rowIdx);
}
row.setHeightInPoints(16.5F);
// No
callCreateCell(row, colIdx++).setCellValue(count);
// ItemNo
callCreateCell(row, colIdx++).setCellValue(castRichTextString(dto.getItemNo()));
// ArtistName
callCreateCell(row, colIdx++).setCellValue(castRichTextString(dto.getArtistName()));
colIdx++;
// ItemTitle
callCreateCell(row, colIdx++).setCellValue(castRichTextString(dto.getItemTitle()));
colIdx++;
// Size
callCreateCell(row, colIdx++).setCellValue(dto.getSize());
colIdx++;
// Classification
callCreateCell(row, colIdx++).setCellValue(dto.getClassification());
colIdx++;
// Detail
callCreateCell(row, colIdx++).setCellValue(StringUtil.cutNewLineCharacter(dto.getPayDetail()));
// Technique
callCreateCell(row, colIdx++).setCellValue(dto.getTechnique());
// Uriage
callCreateCell(row, colIdx++).setCellValue(dto.getUriageWithoutTaxPrice());
row = null;
rowIdx++;
rowIdx++;
}
return workBook;
}
and this one to fill the sum
public HSSFWorkbook getSum(UriageForm uriageForm, HSSFWorkbook workBook, String sheetName) {
HSSFSheet sheet = workBook.getSheet(sheetName);
CellStyle style1 = workBook.createCellStyle();
style1.setAlignment(CellStyle.ALIGN_RIGHT);
//set font size 14
Font font1 = workBook.createFont();
font1.setFontHeightInPoints((short)14);
style1.setFont(font1);
style1.setBorderLeft(CellStyle.BORDER_THIN);
style1.setBorderBottom(CellStyle.BORDER_MEDIUM);
Row row = sheet.getRow(20);
//SUM1
Cell cell2 = row.getCell(8);
cell2.setCellValue(uriageForm.getPrintNestedSize());
cell2.setCellStyle(style1);
//SUM2
Cell cell3 = row.getCell(9);
cell3.setCellValue(uriageForm.getPrintTxtShouhi());
cell3.setCellStyle(style1);
//SUM3
Cell cell4 = row.getCell(10);
cell4.setCellValue(uriageForm.getPrintTxtSum());
cell4.setCellStyle(style1);
//SUM4
Cell cell5 = row.getCell(12);
cell5.setCellValue(uriageForm.getPrintTxtSumAll());
cell5.setCellStyle(style1);
return workBook;
}
The problem is that if i have got more than 5 records data will be filled override into 20th row and my format is broken. My expected result is that if there's more than 5 records so it will add 2 rows (as format) for each added one and my SUM is always be the last 2 rows of sheet.
I'm thinking of remove the SUM gender into another sheet and copy it into the last until the details are done. But I get some questions:
Which function to help me copy rows from one sheet to another?
I have format just for 5 records so how can I insert 2 rows for each added record from 6th that keeps format like the old? (eg: copy format of row 10&11 to every added record)
I'm sorry if it's a little confusing. This is my very first time with Java and POI so I'm really looking forward to some helps from you! Thank you!
Add the copyRow function
private void copyRow(XSSFWorkbook workbook, XSSFSheet worksheet, int sourceRowNum, int destinationRowNum) {
XSSFRow newRow = worksheet.getRow(destinationRowNum);
XSSFRow sourceRow = worksheet.getRow(sourceRowNum);
if (newRow != null) {
worksheet.shiftRows(destinationRowNum, worksheet.getLastRowNum(), 1);
newRow = worksheet.createRow(destinationRowNum);
} else {
newRow = worksheet.createRow(destinationRowNum);
}
// copy process
for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
Cell oldCell = sourceRow.getCell(i);
Cell newCell = newRow.createCell(i);
// if source cell is blank -> stop
if (oldCell == null) {
newCell = null;
continue;
}
//copy style
CellStyle newCellStyle = workbook.createCellStyle();
newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
newCell.setCellStyle(newCellStyle);
//copy cell type
newCell.setCellType(oldCell.getCellType());
//copy cell value
switch (oldCell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
newCell.setCellValue(oldCell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN:
newCell.setCellValue(oldCell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_ERROR:
newCell.setCellErrorValue(oldCell.getErrorCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
newCell.setCellFormula(oldCell.getCellFormula());
break;
case Cell.CELL_TYPE_NUMERIC:
newCell.setCellValue(oldCell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
newCell.setCellValue(oldCell.getRichStringCellValue());
break;
}
}
//copy column merge
for (int i = 0; i < worksheet.getNumMergedRegions(); i++) {
CellRangeAddress cellRangeAddress = worksheet.getMergedRegion(i);
if (cellRangeAddress.getFirstRow() == sourceRow.getRowNum()) {
CellRangeAddress newCellRangeAddress = new CellRangeAddress(newRow.getRowNum(),
(newRow.getRowNum() + (cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())),
cellRangeAddress.getFirstColumn(), cellRangeAddress.getLastColumn());
worksheet.addMergedRegion(newCellRangeAddress);
}
}
}
In the getDetail function, add this below code:
int listSize = resultUriageWorkDTOList.size();
//add 2 rows for each record from 5th record
for (int i = 1; i <= (listSize - 5); i++) {
this.copyRow(workBook, sheet, 10, 12);
this.copyRow(workBook, sheet, 11, 13);
sheet.addMergedRegion(new CellRangeAddress(11,12,4,5));
}
Source: https://www.sukerou.com/2019/03/poi-apache-poi-tips.html
This is method for reading excel:
#SuppressWarnings("deprecation")
public static void readFromExcel(String file) throws IOException {
workbook = new XSSFWorkbook(file);
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
evaluator.evaluateAll();
XSSFSheet myExcelSheet = workbook.getSheetAt(2);
Iterator<Row> itr = myExcelSheet.iterator();
while (itr.hasNext()) {
Row row = itr.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_FORMULA:
System.out.print("formula:" + cell.getCellFormula() + "\t\t\t");
String value = evaluator.evaluate(cell).getStringValue();
System.out.print(value + "\t\t\t");
break;
case HSSFCell.CELL_TYPE_NUMERIC: // field that represents
// numeric cell type
// getting the value of the cell as a number
System.out.print(cell.getDateCellValue() + "\t\t\t");
break;
case HSSFCell.CELL_TYPE_STRING: // field that represents string
// cell type
// getting the value of the cell as a string
System.out.print(cell.getStringCellValue() + "\t\t\t");
break;
}
}
System.out.println();
}
}
I'm getting below output:
Date ME Balance
formula:'Tab1'!C1 null formula:EOMONTH(A2,0) null formula:'Tab1'!$D$3*1000 null
it's reading formula of the cell but not value.I have tried all methods for FormulaEvaluator. Can anyone please assist on this? I have attached the sample sheet image.SampleScenario.xlsx Tab1.xlsx Tab2.xlsx
I am reading an excel file. I want to get row and column number of empty cell if there is any like :
A B C D E
Jen John Alex 03-11-95 {BLANK}
Here i want row and column index for blank cell, I tried a lot of things but was not successful
List<Student> listStudent = new ArrayList<>();
FileInputStream inputStream = new FileInputStream(file);
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = workbook.getSheetAt(0);
Iterator<Row> iterator = firstSheet.iterator();
while (iterator.hasNext()) {
Row nextRow = iterator.next();
Iterator<Cell> cellIterator = nextRow.cellIterator();
Student student = new Student();
while (cellIterator.hasNext()) {
Cell nextCell = cellIterator.next();
int columnIndex = nextCell.getColumnIndex();
if (!firstName.contains("not_in_file") && columnIndex == Integer.parseInt(firstName)) {
student.setFirstName((String) getCellValue(nextCell));
} else if (!familyName.contains("not_in_file") && columnIndex == Integer.parseInt(familyName)) {
student.setFamilyName((String) getCellValue(nextCell));
} else if (!preferName.contains("not_in_file") && columnIndex == Integer.parseInt(preferName)) {
student.setPreferName((String) getCellValue(nextCell));
} else if (!dob.contains("not_in_file") && columnIndex == Integer.parseInt(dob)) {
student.setDob((String) getCellValue(nextCell));
} else if (!guardianName.contains("not_in_file") && columnIndex == Integer.parseInt(guardianName)) {
student.setGuardianName((String) getCellValue(nextCell));
}
}
listStudent.add(student);
}
System.out.println(" listStudent : " + listStudent);
workbook.close();
inputStream.close();
private Object getCellValue(Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
return cell.getStringCellValue();
case Cell.CELL_TYPE_BOOLEAN:
return cell.getBooleanCellValue();
case Cell.CELL_TYPE_NUMERIC:
return cell.getNumericCellValue();
}
return null;
}
There is a Cell-constant for that. You can add the Cell.CELL_TYPE_BLANK case to your getCellValue method.
private Object getCellValue(Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
return "";
case Cell.CELL_TYPE_STRING:
return cell.getStringCellValue();
case Cell.CELL_TYPE_BOOLEAN:
return cell.getBooleanCellValue();
case Cell.CELL_TYPE_NUMERIC:
return cell.getNumericCellValue();
}
return null;
}
What Gagravarr is saying is quite simple, Blank or never used.
Blank cell means an initialized cell, having no value, The Blank cell will give you value as blank.
While never used cell means, not initialized will give you null so may throw exception. You need to understand the difference.
Try to debug using condition like
if(cell!=null)
System.out.println(cell.getStringCellValue());
If this is not throwing null pointer means, the cell you are trying to use is actually never used, so null.
But for safety about cell types, you should use Christian's Solution as well.
I have an application which reads xls sheet using apache poi. When the cell has numeric value, i read it by row.getCell(i).getNumericValue(). But it returns floating point digit. like if the cell value is 1, it returns 1.0. Can i convert it to int ? Any helpwould be appreciated. I tried Integer.parseInt(value)- but it throws NumberFormat exception.Any help is appreciated.Here is the pseudo code:
FileInputStream file = new FileInputStream(new File("C:\\test.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(file);
HSSFSheet 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:
String value= String.valueOf(cell.getNumericCellValue());
int intVal = Integer.parseInt(value)-->>throws Exception
Numbers in Excel are (except for a few edge cases) stored as floating point numbers. Floating point numbers in Java, when formatted as a string, are printed with a trailing decimal point, as you're seeing
Assuming what you really wanted was "give me a string that looks like what Excel shows for this cell", then do not call cell.toString(). This will not give you what you want in most cases
Instead, you need to use the DataFormatter class, which provides methods which read the Excel format rules applied to a cell, then re-creates (as best it can) those in Java
Your code should be:
Workbook wb = WorkbookFactory.create(new File("c:/test.xls");
DataFormatter fmt = new DataFormatter();
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
Cell cell = row.getcell(0, Row.RETURN_BLANK_AS_NULL);
if(cell!=null) {
String value = fmt.formatCellValue(cell);
if (! value.trim().isEmpty()) {
System.out.println("Cell as string is " + value);
}
}
}
You may notice I've also fixed a bunch of other stuff as well....!
// to extract the exact numerical value either integer/double
DataFormatter fmt = new DataFormatter();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
//DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
fetchedRow.add(dateFormat.format(date));
} else {
fetchedRow.add(fmt.formatCellValue(cell));
}
rowEmpty = false;
break;
case STRING:
fetchedRow.add(cell.toString());
rowEmpty = false;
break;
case BOOLEAN:
fetchedRow.add(cell.toString());
rowEmpty = false;
break;
case FORMULA:
fetchedRow.add(Double.toString(cell.getNumericCellValue()));
rowEmpty = false;
break;
case BLANK:
fetchedRow.add("");
break;
}
}
if (!rowEmpty) {
allRows.add(fetchedRow.toArray(new String[0]));
count++;
}
if (count >= limit) {
break;
}
}
return allRows;
}
eaxmple to read limitted no.of rows on and use DataFormatter to give exact numeric value either integer/ double value. This will work.
Someone might find this hack useful:
cell.setCellType(CellType.STRING);
int value = Integer.parseInt(cell.getStringCellValue());
Remember you alter the cell type here, so be sure this does not cause any side effect. In a single-threaded app you can just read the type before and restore it after.
You can read int value as string apache poi using simple steps
First count rows in sheets using below method
private int getRowCount(Sheet currentSheet) {
int rowCount = 0;
Iterator<Row> rowIterator = currentSheet.iterator();
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
if(row == null || row.getCell(0) == null || row.getCell(0).getStringCellValue().trim().equals("") || row.getCell(0).toString().trim().equals("")
|| row.getCell(0).getCellType()==Cell.CELL_TYPE_BLANK){
break;
}
else
rowCount=rowCount + 1;
}
return rowCount;
}
Then use below code in your method
Workbook workbook = WorkbookFactory.create(new File("c:/test.xls");
Sheet marksSheet = (Sheet) workbook.getSheet("Sheet1");
int zoneLastCount = 0;
if(marksSheet !=null ) {
zoneLastCount = getRowCount(marksSheet);
}
int zone = zoneLastCount-1;
int column=1
for(int i = 0; i < zone; i++) {
Row currentrow = marksSheet.getRow(i);
double year = Double.parseDouble(currentrow.getCell(columnno).toString());
int year1 = (int)year;
String str = String.valueOf(year1);
}
You can just type cast float to int like :
String value = String.valueOf((int)cell.getNumericCellValue());
Cell cell = row.getCell(cellCpt);
String cellContent = "";
if (cell != null) {
cell.setCellType(CellType.STRING);
cellContent = fmt.formatCellValue(cell);
}
Try doing the following (to obtain a long):
long value = (long) currentCell.getNumericValue();
Below implementation worked for me:
private Object getValue(Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
return cell.getStringCellValue();
case Cell.CELL_TYPE_NUMERIC:
return String.valueOf((int) cell.getNumericCellValue());
case Cell.CELL_TYPE_BOOLEAN:
return cell.getBooleanCellValue();
case Cell.CELL_TYPE_ERROR:
return cell.getErrorCellValue();
case Cell.CELL_TYPE_FORMULA:
return cell.getCellFormula();
case Cell.CELL_TYPE_BLANK:
return null;
}
return null;
}
I'm trying to find a blank value in excel (xlsx) sheet and replace with some string like "ENTER VALUE" using my program with Apache POI library as below
I'm able to read and identify blank/null values in excel sheet but couldnt insert any value into those cells
public static void main(String args[]) throws IOException, InvalidFormatException
{
FileInputStream inputFile = new FileInputStream("//Users//suk//Documents/tes//testexcel.xlsx");
//now initializing the Workbook with this inputFie
// Create workbook using WorkbookFactory util method
Workbook wb = WorkbookFactory.create(inputFile);
// creating helper for writing cells
CreationHelper createHelper = wb.getCreationHelper();
// setting the workbook to handle null
wb.setMissingCellPolicy(Row.CREATE_NULL_AS_BLANK);
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
int lastCellNo =row.getLastCellNum();
int firstCellNo=row.getFirstCellNum();
int rowNo =row.getRowNum();
System.out.println(" row number = "+rowNo);
System.out.println(" last cell no = "+lastCellNo);
for(int i=firstCellNo;i<lastCellNo;i++){
System.out.println("************");
Cell cell = row.getCell(i);
int colIndex =cell.getColumnIndex();
if(cell==null)
{
System.out.println(" The Cell:"+colIndex+" for row "+row.getRowNum()+" is NULL");
}
System.out.println(" column index = "+colIndex);
int cellType = cell.getCellType();
System.out.println(" cell type ="+cellType);
// writing a switch case statement
switch(cellType)
{
case 0:
{
double numValue = cell.getNumericCellValue();
//System.out.println(numValue);
break;
}
case 1:
{
String cellString = cell.getStringCellValue();
System.out.println("----String value = "+cellString+"---String length ="+cellString.length());
// here checking null consition
/* if(cellString == null || cellString.equalsIgnoreCase("") || cellString.length()<=0 || cellString.equalsIgnoreCase(" "))
{
// here creating the cell value after last cell
} */
break;
}
case 4:
{
boolean bolValue =cell.getBooleanCellValue();
//System.out.println(bolValue);
break;
}
// for case of blank cell
case 3:
{
//int lastCellPlus =lastCellNo+1;
//System.out.println("last+1 column ="+lastCellPlus);
//row.createCell(lastCellPlus).setCellValue(" NULL VALUE..PLEASE ENTER VALUE ");
System.out.println(" cell details = "+cell.getColumnIndex()+" row details ="+row.getRowNum());
cell.setCellValue(createHelper.createRichTextString("ENTER VALUE"));
System.out.println(" Sucessfully written error");
break;
}
default:
System.out.println(" unknown format");
break;
}// switch
} // row and cell iterator
}
}
}
Below is the bit of code by which im identifying its Blank/Null value and trying to insert String but its not writing to that cell
case 3:
{
//int lastCellPlus =lastCellNo+1;
//System.out.println("last+1 column ="+lastCellPlus);
//row.createCell(lastCellPlus).setCellValue(" NULL VALUE..PLEASE ENTER VALUE ");
System.out.println(" cell details = "+cell.getColumnIndex()+" row details ="+row.getRowNum());
cell.setCellValue(createHelper.createRichTextString("ENTER VALUE"));
System.out.println(" Sucessfully written error");
break;
}
if(row.getCell(0))==null || getCellValue(row.getCell(0)).trim().isEmpty()){
cell.setCellValue("ENTER VALUE");
}
private String getCellValue(Cell cell) {
if (cell == null) {
return null;
}
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
return cell.getStringCellValue();
} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
return cell.getNumericCellValue() + "";
} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
return cell.getBooleanCellValue() + "";
}else if(cell.getCellType() == Cell.CELL_TYPE_BLANK){
return cell.getStringCellValue();
}else if(cell.getCellType() == Cell.CELL_TYPE_ERROR){
return cell.getErrorCellValue() + "";
}
else {
return null;
}
}
This should work fine:
Sheet s = wb.getSheetAt(0);
for (int rn=0; rn<s.getLastRowNum(); rn++) {
Row r = s.getRow(rn);
if (r == null) {
// No values exist in this row
r = s.createRow(rn);
}
int minColumnsPerRow=10; // Fix for your needs
for (int cn=0; cn<minColumnsPerRow; cn++) {
Cell c = r.getCell(cn);
if (c == null || c.getCellType() == Cell.CELL_TYPE_BLANK) {
// This cell is empty
if (c == null) {
c = r.createCell(cn, Cell.CELL_TYPE_STRING);
}
cell.setCellValue(createHelper.createRichTextString("ENTER VALUE"));
}
}
}
Remember that cells can be blank or null (never used), and rows can be null (never used)