I'm using Apache POI to work on an Excel file.
Most of the time it works fine, but sometimes, getLastRowNum() returns a wrong number which causes a null pointer Exception when I arrive at the end of the file.
I want to be sure everything works fine, even when there is something wrong with getLastRowNum().
for (int i = FIRST_ROW_TO_GET; i < sheet.getLastRowNum(); i++) {
row = sheet.getRow(i);
System.out.println(row.getCell(9));
}
I tried to use a if row.equals(null) but it doesn't change anything.
Any idea of what I can do?
You can't call row.equals(null) since row is null in this case. You can do the check this way:
for (int i = FIRST_ROW_TO_GET; i < sheet.getLastRowNum(); i++) {
row = sheet.getRow(i);
if (row != null){
System.out.println(row.getCell(9));
}
}
The below method will give the accurate last row number in excel, ignoring the blank cells :
int getRowCount(String sheetName) {
int number = 0;
int index = workbook.getSheetIndex(sheetName);
if (index == -1) {
return 0;
} else {
sheet = workbook.getSheetAt(index);
for(int i = 0; i < sheet.getLastRowNum(); i++) {
if(sheet.getRow(i)==null) {
sheet.shiftRows(i+1, sheet.getLastRowNum(), -1);
i--;
}
number = sheet.getLastRowNum() ;
}
}
return number;
}
Related
I could not find any method to check POI sheet has null rows.
I have tried, Sheet.getLastRowNum(),Sheet.getFirstRowNum(),Sheet.rowIterator(), they all issue NPE.
I am really really confusing right now.
Note: But Sheet object itself is not null though.
int numberOfSheets = wb.getNumberOfSheets();
Sheet sheet;
int maxColumnsCount = 0, headerRowIndex = 0;
Row row;
Member member;
List<Member> members = new ArrayList<>();
for (int i = 0; i < numberOfSheets; i++) {
sheet = wb.getSheetAt(i);
//find the maximum cells in a row, it is assumed that max cells container is only valid data. Otherwise Header or Footer.
//THISE LINE('sheet.getPhysicalNumberOfRows()') GIVE ME NULL POINTER EXCEPTION.
for (int rowIndex = 0; rowIndex < sheet.getPhysicalNumberOfRows(); rowIndex++) {
row = sheet.getRow(rowIndex);
if (maxColumnsCount < row.getPhysicalNumberOfCells()) {
maxColumnsCount = row.getPhysicalNumberOfCells();
headerRowIndex = rowIndex;
} else {
break;
}
}
for (int rowIndex = 0; rowIndex < sheet.getPhysicalNumberOfRows(); rowIndex++) {
row = sheet.getRow(rowIndex);
if (headerRowIndex < rowIndex) {
member = parseMember(row, memberExcelImportType);
member.getTownship().setId(townshipId);
if (StringUtils.isNotEmpty(member.getFullName()))
members.add(member);
}
}
}
Sorry, here's the stack trace.
java.lang.NullPointerException
at org.apache.poi.xssf.usermodel.XSSFSheet.getPhysicalNumberOfRows(XSSFSheet.java:842)
at com.taraaung.tarabar.tarabarlibs.utility.ImportUtilPOI.readExcelFileUsingPOI(ImportUtilPOI.java:45)
at com.taraaung.tarabar.tarabarlibs.utility.ImportUtils.readExcelFile(ImportUtils.java:32)
at com.taraaung.taraserver.server.personExportImportUrl.PersonExportImportHttpServe.doPersonImport(PersonExportImportHttpServe.java:153)
at com.taraaung.taraserver.server.personExportImportUrl.PersonExportImportHttpServe.serve(PersonExportImportHttpServe.java:86)
at com.taraaung.taraserver.server.MyServer$ValidateSession.serve(MyServer.java:2608)
at com.taraaung.taraserver.server.MyServer.serve(MyServer.java:770)
at com.taraaung.taraserver.server.NanoHTTPD$HTTPSession.execute(NanoHTTPD.java:1557)
at com.taraaung.taraserver.server.NanoHTTPD$ClientHandler.run(NanoHTTPD.java:1152)
at java.lang.Thread.run(Thread.java:745)
Umm, just found that the sheet which issues NPE is ChartSheet (i.e, it does not have any kind of rows), then I just check the instance of sheet and skip chart sheets. :D if (sheet instanceof XSSFChartSheet) {
continue;
}
'Thanks for the help'
I don't know how to delete row without leaving an empty row.
I am using Apache POI 3.9 and I am getting an error using the following code:
public List<MeterInfo> addToList(String patternt) throws ParseException, IOException {
List<Object> data = new ArrayList<Object>();
int lastRowNum = sheet.getLastRowNum();
Row row;
for(int i = 0; i < lastRowNum; i++){
row = sheet.getRow(i);
if(patternt.equals(getCurrentString(row))){
data.add(getDataFromRow(row));
sheet.removeRow(row);
sheet.shiftRows(row.getRowNum() + 1, row.getRowNum() + 1, -1);
}
}
saveWorkbook(new File("blabla.xlsx"));
return data;
}
I've found a solution in https://stackoverflow.com/a/3554129/6812826, but I am getting a NullPointerException because I am decreasing lastRowNum by each deleted row.
Here is the new version:
public List<Object> addToList(String pattern) throws ParseException, IOException {
List<Object> data= new ArrayList<Object>();
for (int i = 0; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (pattern.equals(getCurrentString(row))) {
data.add(getMeterInfo(row));
deleteRow(row);
}
}
saveWorkbook(new File("blabla.xlsx"));
return data;
}
private void deleteRow(Row row) {
int lastRowNum = sheet.getLastRowNum();
int rowIndex = row.getRowNum();
if(rowIndex >= 0 && rowIndex < lastRowNum){
sheet.shiftRows(rowIndex + 1, lastRowNum, -1);
}
if(rowIndex == lastRowNum){
Row removingRow = sheet.getRow(rowIndex);
if(removingRow != null){
sheet.removeRow(removingRow);
}
}
}
Try this code, it should work:
for(int i = 0; i < sheet.getLastRowNum(); i++)
{
row = sheet.getRow(i);
if(patternt.equals(getCurrentString(row)))
{
data.add(getDataFromRow(row));
// sheet.removeRow(row); NO NEED FOR THIS LINE
sheet.shiftRows(row.getRowNum() + 1, sheet.getLastRowNum() + 1, -1);
i--;
}
}
You need to decrease i by one every time you delete one row. And get the last row number again by using getLastRowNum().
I wish to read an Excel file and skip the empty rows. My code skips empty cells but it skips empty columns, too. How can I skip empty rows but maintain empty columns? I'm using JXL Java.
for (int i = 0; i < sheet.getRows(); i++) {
for (int j = 0; j < sheet.getColumns(); j++) {
Cell cell = sheet.getCell(j, i);
String con = cell.getContents();
if (con != null && con.length() != 0) {
System.out.print(con);
System.out.print("|");
}
else {
continue;
}
}
}
Try this:
for (int i = 0; i < sheet.getRows(); i++) {
boolean rowEmpty = true;
String currentRow = "";
for (int j = 0; j < sheet.getColumns(); j++) {
Cell cell = sheet.getCell(j, i);
String con=cell.getContents();
if(con !=null && con.length()!=0){
rowEmpty = false;
}
currentRow += con + "|";
}
if(!rowEmpty) {
System.out.println(currentRow);
}
}
What you were doing is:
Loop through rows
Loop through columns
Print cell if it's empty only, skip it otherwise (your continue statement does nothing as it's the last instruction in the loop anyway, and a break statement would just stop reading the row once it reaches an empty cell)
What this does is:
Loop through rows
Loop through columns
Append the cell to the row's string, and if it's non-empty then set rowEmpty to false (as it contains at least one non-empty cell)
Print the row only if it's not empty
In case of C#, This works for me
private bool CheckIfEmptyRow(ISheet worksheet, int rowIndex)
{
var worksheetRow = worksheet.GetRow(rowIndex);
bool isRowEmpty = true;
for (var columnIndex = worksheetRow.FirstCellNum; columnIndex < worksheetRow.LastCellNum; columnIndex++)
{
ICell cell = worksheetRow.GetCell(columnIndex, MissingCellPolicy.RETURN_NULL_AND_BLANK);
if (!string.IsNullOrEmpty(cell.StringCellValue))
{
isRowEmpty = false;
break;
}
}
return isRowEmpty;
}
I am new to Apache-poi and using 3.8 version of poi. While writing value in the Excel,i check for the column names if they matched, i will write some value in that column and finish it, and again i will start writing on header. The problem is if write three column values only last column values are add or saved and first two values are not saved in the column. Can anyone tell what went wrong.
(sorry, in case any mistake)
Code:
int i = 0;
Row row = sheet.createRow(i);
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFillBackgroundColor(HSSFColor.LIGHT_ORANGE.index);
String validate_header = null;
while (iterator.hasNext()) {
if (eiterator.hasNext()) {
validate_header = eiterator.next();
}
Cell cell = row.createCell(i);
String col_heading = iterator.next();
cell.setCellValue(col_heading);
if(col_heading.equalsIgnoreCase("Assigned Date"))
{
Add_value(i, col_heading, row, sheet);
row=sheet.getRow(0);
cell=row.getCell(i);
}
else if(col_heading.startsWith("Review"))
{
int count=-1;
int n=Col_values.get("Defect Summary").size();
for (int j = 0; j < n; j++) {
row = sheet.createRow(count);
cell = row.createCell(i);
String s="External QC Defect ";
cell.setCellValue(s);
count++;
}
row=sheet.getRow(0);
cell=row.getCell(i);
}
sheet.autoSizeColumn(i);
i++;
}
private static Sheet Add_value(int k,String name,Row row, Sheet sheet) {
System.out.println("Inside the add method");
if(name.equalsIgnoreCase("Assigned Date")||name.equalsIgnoreCase("Reported Date") )
{
vector = Col_values.get("TargetDate");
int count = 1;
System.out.println("IF Size of the vector " + vector.size());
for (int j = 0; j < vector.size(); j++) {
row = sheet.createRow(count);
cell = row.createCell(k);
String s = (String) vector.get(j);
System.out.println(s);
cell.setCellValue(s);
count++;
}
}
else
{
vector = Col_values.get("Defect Summary");
int count = 1;
System.out.println("ELSE Size of the vector " + vector.size());
for (int j = 0; j < vector.size(); j++) {
row = sheet.createRow(count);
cell = row.createCell(k);
String s = (String) vector.get(j);
System.out.println(s);
cell.setCellValue(s);
count++;
}
}
return sheet;
}
'
Can u tell what went Wrong?
It seems that Add_value starts creating rows from top. Therefore on the second call the old rows are removed.
Replace
row = sheet.createRow(count);
with
row = k == 0 ? sheet.createRow(count) : sheet.getRow(count);
I'm new to Java, and programming in general. I recently started working with arrays, and came upon an exercise in the book that i thought id give a try. The goal is to read a file using the scanner class assign each number to a different cell in a 2d array. This is what i have for the method. But no matter how i change it, i cant seem to get the desired result. Either i end up getting the last number in every cell, or i get an error. Please help.
int row = 0;
int col = 0;
while (A[row][col] != -1)
{
for (row = 0; row < A.length; row++)
{
for (col = 0; col < A[row].length; col++)
A[row][col] = scan.nextInt();
}
}
The scanning needs to happen in the inner-most loop. At this point, you might want to re-read the chapter you're on and spend a bit longer working on problems before posting to SO.
...
for (int col = 0; col < A[row].length; col++){
A[row][col] = temp;
temp = scan.nextInt();
}
...
You might also find that printing out values is useful while watching programs execute. Add System.out.println(temp) after the point where you read in temp. This would have made the problem obvious. You'll also want to change your while looping construct. As of now, it doesn't make much sense.
Based on your comments ... this should do what you're asking. The problem you're having is that you're not able to break out of your inner loop without having some sort of conditional on the outer one.
Note that I changed A to a; variables should never start with uppercase.
int a[][] = new int[20][20];
int row = 0;
int col = 0;
int current = 0;
for (row = 0; row < a.length, current != -1; row++)
{
for (col = 0; col < a[row].length; col++)
{
try
{
current = scan.nextInt();
if (current == -1)
{
break;
}
else
{
a[row][col] = current;
}
}
catch ( NoSuchElementException e)
{
System.out.println("I hit the end of the file without finding -1!");
current = -1;
break;
}
catch ( ArrayIndexOutOfBoundsException e)
{
System.out.println("I ran out of space in my 2D array!");
current = -1;
break;
}
}
}
I personally wouldn't use the nested loops, and go this route:
int a[][] = new int[20][20];
int row = 0;
int col = 0;
int current = 0;
while (scan.hasNextInt())
{
current = scan.nextInt();
if (current == -1)
{
break;
}
a[row][col] = current;
col++;
if (col == a[row].length)
{
row++;
col = 0;
if (row == a.length)
{
System.out.println("I ran out of space in my 2D array!");
break;
}
}
}