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;
}
Related
I am trying to make use of Apache POI to read an excel file and convert it to a 2-dimensional object array. Attached is the code section.
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = workbook.getSheetAt(1);
int numRows = 3;
int cols = 5;
double[][] excelData = new double[numRows][cols];
for (int i = 1; i < numRows; i++) {
Row row = firstSheet.getRow(i);
if (row != null) {
for (int j = 1; j < cols; j++) {
Cell cell = row.getCell(j);
if (cell != null) {
try {
excelData[i][j] = cell.getNumericCellValue();
} catch (IllegalStateException e) {
System.out.println("Cell data is not a double");
}
}
}
}
}
workbook.close();
inputStream.close();
return excelData;
}
enter image description here This is my excel sheet and I want to "just" read the blue part of it as a 2d array, but after running the code the first row and column all are zero and I don't want it, appreciate your help on how can quickly pull out all the zeros enter image description here.
You need to change index in the 1st loop to 0 (first field in excel file)
but in row you must provide index + 1 bc you need to read from the 2nd field.
Same analogy for 2nd loop and cell field
Workbook workbook = new XSSFWorkbook(new File("d:\\book1.xlsx"));
Sheet firstSheet = workbook.getSheetAt(1);
int numRows = 3;
int cols = 5;
double[][] excelData = new double[numRows][cols];
for (int i = 0; i < numRows; i++) {
Row row = firstSheet.getRow(i + 1);
if (row != null) {
for (int j = 0; j < cols; j++) {
Cell cell = row.getCell(j + 1);
if (cell != null) {
try {
if (cell.getCellType().equals(CellType.NUMERIC)) {
excelData[i][j] = Double.valueOf(cell.getNumericCellValue());
}
} catch (IllegalStateException e) {
System.out.println("Cell data is not a double");
}
}
}
}
}
workbook.close();
Returned result for it:
0.041256 0.033079 -0.01138 -0.02138 -0.01138
0.041256 0.033079 -0.01138 -0.01138 -0.01138
0.020628 0.01654 -0.00569 -0.10569 -0.00569
public static ArrayList<Double> readSheet(XSSFSheet spreadsheet) {
int rows = spreadsheet.getPhysicalNumberOfRows();
for (int i = 0; i <= i; i++) {
XSSFRow row = spreadsheet.getRow(i);
if (row == null) {
continue;
}
int cells = row.getPhysicalNumberOfCells();
ArrayList<Double> cellList = new ArrayList<>();
for (int j = 0; j < cells; j++) { //遍历每一列
XSSFCell cell = row.getCell(j);
cell.setCellType(cell.CELL_TYPE_STRING);
//new Double("1.0").intValue()
Double cellValue = cell.getNumericCellValue();
cellList.add(cellValue);
}
return cellList;
}
}
Can someone please help
You should provide the return statement outside of your for loop:
public static ArrayList<Double> readSheet(XSSFSheet spreadsheet) {
int rows = spreadsheet.getPhysicalNumberOfRows();
ArrayList<Double> cellList = new ArrayList<>();
for (int i = 0; i <= i; i++) {
...
}
return cellList;
}
Because the compile cannot decide if there is any run of your for loop and therefore not guarantee that your return statement will be reached.
This also means that you need to declare your cellList variable outside of the for loop.
And please also check your loop condition. While i<=i might be always true you don't want to loop indefinitely.
Firstly, your condition in for loop is wrong: i <= i is always true.
Secondly, you must provide return statement for all branches. For example, if condition in for loop will be false, there is no return statements in remaining function body.
You should:
put cellList before for loop
put return statement outside for loop
I am trying to delete empty cell in apache-poi. I get this error at
unmarkedColumns.remove(unmarkedColumns.get(i)):
There is a problem with remove method.
I don't understand why.Can you help me?
java.lang.UnsupportedOperationException: null
at java.util.AbstractList.remove(Unknown Source)
at java.util.AbstractList$Itr.remove(Unknown Source)
)
Integer[] integers = new Integer[headers.size()];
Arrays.fill(integers, 0);
List<Integer> unmarkedColumns = Arrays.asList(integers);
for (ScoredFormData scoredFormData : scoredFormDatas) {
Row dataRow = sheet.createRow(++rownum);
List<Object> rowValues = prepareExportRow(scoredFormData, visitManager, parameters,
dynamicDatamanager,
scoreCriteriaDefinitions);
for (int i = 0; i < rowValues.size(); i++) {
if (unmarkedColumns.get(i) != 1 && rowValues.get(i) != null
&& !rowValues.get(i).equals("")) {
unmarkedColumns.set(i, 1);
}
}
populateCells(rowValues, dataRow);
}
for (int i = 0; i < unmarkedColumns.size(); i++) {
if (unmarkedColumns.get(i) == 0) {
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Boolean changed = false;
for (int j = i + 1; j < row.getLastCellNum() + 1; j++) {
Cell oldCell = row.getCell(j - 1);
if (oldCell != null) {
row.removeCell(oldCell);
changed = true;
Cell nextCell = row.getCell(j);
if (nextCell != null) {
Cell newCell = row.createCell(j - 1, nextCell.getCellType());
switch (newCell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN: {
newCell.setCellValue(nextCell.getBooleanCellValue());
break;}}}}
if (changed ) {
unmarkedColumns.remove(unmarkedColumns.get(i));
i = 0;
}
}
Arrays.asList(..) returns a List with a fixed size, so you can't expand or shrink it.
To fix it, you could wrap it in an ArrayList:
List<Integer> unmarkedColumns = new ArrayList<>(Arrays.asList(integers));
Your problem is here
List<Integer> unmarkedColumns = Arrays.asList(integers);
If you use Arrays.asList(...), it returns a fixed size list, therefore you cannot remove elements from it.
You could make a workaround by wrapping it:
List<Integer> list = new ArrayList<Integer>(Arrays.asList(integers));
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;
}
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);