I am trying to read in each row that has data in the first cell into an ArrayList of Objects. My problem is that my code doesn't seem to be incrementing my counter past the first row. Am I missing something simple?
Code
try
{
wb = new XSSFWorkbook(new FileInputStream(fileName));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
XSSFSheet sheet = wb.getSheetAt(2);
ArrayList<Object> obj = new ArrayList<Object>();
int rowIndex = 0;
int cellIndex = 0;
XSSFRow row = sheet.getRow(rowIndex);
Iterator<Cell> rowItr = row.iterator();
while(rowIndex <= sheet.getLastRowNum())
{
if(row.getCell(0) == null)
{
continue;
}
else
{
while(rowItr.hasNext() && rowItr.next() != null)
{
XSSFCell cell = row.getCell(cellIndex);
if(cell == null)
{
continue;
}
else
{
obj.add(row.getCell(cellIndex).toString());
}
cellIndex++;
}
rowIndex++;
cellIndex = 0;
}
System.out.println(obj.toString());
}
rowIndex++;
}
}
Output
[ValuSmart Series 1120 Double Hung]
... I get this output 72 times since there are 72 rows in the sheet
Isolated Loop
ArrayList<Object> obj = new ArrayList<Object>();
int rowCounter = 16;
int x = 0;
while(rowCounter <= 21)
{
XSSFRow row = sheet.getRow(rowCounter);
Iterator<Cell> rowItr = row.iterator();
while(rowItr.hasNext() && rowItr.next() != null)
{
XSSFCell cell = row.getCell(x);
if(cell == null)
{
continue;
}
else
{
obj.add(row.getCell(x).toString());
}
x++;
}
rowCounter++;
x = 0;
}
System.out.println(obj.toString());
You're not select the next row anywhere, and your loops are confusing and switch between index- and iterator-based lookups. Try a simple enhanced for loop:
for (Row row : sheet) {
for (Cell cell : row) {
if (cell != null) {
obj.add(row.getCell(x).toString());
}
}
}
System.out.println(obj.toString());
Related
I am working on a xlsx file which contains two last rows in the end , i have to excluse the rows on the basis of the cell values it contains.i.e My excel contains Total India(10%) and Total(10%) in its last two rows so i have to exclude the two rows on a basis of Total keyword. I am using the following approach but its not working
#Override
public List<String> processSheet(Sheet sheet) {
ActivityLauncher.logConsoleMsg("Processing sheet " + sheet.getSheetName() + " started");
List<String> rows = new ArrayList<String>();
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext()) {
Row currentRow = rowIterator.next();
StringBuilder row = new StringBuilder();
for (int i = 0; i < currentRow.getLastCellNum(); i++) {
if(currentRow.getRowNum()==0 || currentRow.getRowNum()==1|| currentRow.getRowNum()==2|| currentRow.getRowNum()==3|| currentRow.getRowNum()==4|| currentRow.getRowNum()==5|| currentRow.getRowNum()==6|| currentRow.getRowNum()==7|| currentRow.getRowNum()==9|| currentRow.getRowNum()==10|| currentRow.getRowNum()==11) {
continue;
}else {
Cell currentCell = currentRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String cellValue = excelManager.evalCell(currentCell);
if (!cellValue.isEmpty()) {
row.append(cellValue);
}
// trying to remove the rows containing total --------------------------------------->
int rowNums = sheet.getPhysicalNumberOfRows();
for(int k =0;k<rowNums;k++) {
currentRow = sheet.getRow(k);
if(currentRow !=null) {
for(int j=0;j<currentRow.getLastCellNum();j++) {
currentCell = currentRow.getCell(j);
if(currentCell !=null && currentCell.getCellTypeEnum().equals(CellType.STRING) && currentCell.getStringCellValue().toLowerCase().contains("total")){
sheet.removeRow(currentRow);
rowNums++;
}
}
}
}
//---------------------------------------------------------->
//adjusting the cell values with the | or BLANK
if(currentCell == null || currentCell.getCellType() == Cell.CELL_TYPE_BLANK) {
row.append("");
}else {
row.append(SEPARATOR);
}
}
}
if (!row.toString().isEmpty()) {
rows.add(row.toString());
}
}
ActivityLauncher.logConsoleMsg("Processing sheet " + sheet.getSheetName() + " completed");
return rows;
}
}
Can anyone help ??
This is my little test program. It removes every row that contains the word total. You will have to remove the code that you don't need (first 2 and last line probably)
XSSFWorkbook wb = new XSSFWorkbook(new File("test.xlsx"));
XSSFSheet sheet = wb.getSheetAt(0);
int rowNums = sheet.getPhysicalNumberOfRows();
for (int i = 0; i < rowNums; i++) {
XSSFRow r = sheet.getRow(i);
if (r != null) {
for (int j = 0; j < r.getLastCellNum(); j++) {
XSSFCell c = r.getCell(j);
if (c != null && c.getCellTypeEnum().equals(CellType.STRING)
&& c.getStringCellValue().toLowerCase().contains("total")) {
sheet.removeRow(r);
rowNums++;
}
}
}
}
wb.write(Files.newOutputStream(Paths.get("test2.xlsx"), StandardOpenOption.CREATE_NEW));
Updated for your code:
List<String> rows = new ArrayList<String>();
int rowNums = sheet.getPhysicalNumberOfRows();
for (int k = 0; k < rowNums; k++) {
Row currentRow = sheet.getRow(k);
if (currentRow != null) {
StringBuilder row = new StringBuilder();
for (int i = 0; i < currentRow.getLastCellNum(); i++) {
if (currentRow.getRowNum() <= 11 && currentRow.getRowNum() != 8) {
continue;
} else {
Cell currentCell = currentRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String cellValue = excelManager.evalCell(currentCell);
if (!cellValue.isEmpty()) {
row.append(cellValue);
}
if (currentCell != null && currentCell.getCellTypeEnum().equals(CellType.STRING)
&& currentCell.getStringCellValue().toLowerCase().contains("total")) {
sheet.removeRow(currentRow);
rowNums++;
}
if (currentCell == null || currentCell.getCellType() == Cell.CELL_TYPE_BLANK) {
row.append("");
} else {
row.append(SEPARATOR);
}
}
}
if (!row.toString().isEmpty()) {
rows.add(row.toString());
}
}
}
I am coding a program to format the contents of an excel file. Eclipse is saying that the line Cell cell = cellIterator.next(); is unreachable and I don't understand why. Where did I go wrong?
private String formatExcel(File excel)
{
this.statusLabel.setText("formatting...");
try
{
FileInputStream file = new FileInputStream(excel);
try
{
this.workbook = WorkbookFactory.create(file);
}
catch (InvalidFormatException ex)
{
file.close();
}
int excelType = 0;
if ((this.workbook instanceof HSSFWorkbook)) {
excelType = 1;
}
int sheetNum = 0;
try
{
sheetNum = Integer.parseInt(this.sheetNumber.getText());
}
catch (NumberFormatException e)
{
file.close();
}
if ((sheetNum < 1) || (sheetNum > this.workbook.getNumberOfSheets()))
{
file.close();
return "Please input a valid sheet number.";
}
Sheet sheet = this.workbook.getSheetAt(sheetNum - 1);
sheet.setZoom(17, 20);
Iterator<Row> rowIterator = sheet.iterator();
int startRow = Integer.MAX_VALUE;
Iterator<Cell> cellIterator;
for (; rowIterator.hasNext(); cellIterator.hasNext())
{
Row row = (Row)rowIterator.next();
cellIterator = row.cellIterator();
continue;
Cell cell = (Cell)cellIterator.next(); // <- this line is unreachable
switch (cell.getCellType())
{
case 4:
break;
case 0:
break;
case 1:
if (cell.getStringCellValue().trim().equalsIgnoreCase("Condition Code")) {
startRow = cell.getRowIndex();
}
if ((cell.getRowIndex() > startRow + 1) && (cell.getColumnIndex() > 0) && (cell.getColumnIndex() < 5)) {
if (excelType == 0) {
cell.setCellValue(formatCellXSSF(
cell.getStringCellValue(),
cell.getColumnIndex()));
} else {
cell.setCellValue(formatCellHSSF(
cell.getStringCellValue(),
cell.getColumnIndex()));
}
}
if (!cell.getStringCellValue().trim().equalsIgnoreCase("<<Test Data>>")) {
if (!cell.getStringCellValue().trim().equalsIgnoreCase("<<Screenshots>>")) {
break;
}
}
break;
}
}
sheet.autoSizeColumn(5);
file.close();
FileOutputStream out = new FileOutputStream(excel);
this.workbook.write(out);
out.close();
return "";
}
catch (FileNotFoundException ex)
{
return "Error. File is open. Please close it first.";
}
catch (IOException ex) {}
return "Cannot format file because it is open. Please close it first.";
}
You have an unconditionnal continue in your for loop. Next statements are never executed, no way.
for (; rowIterator.hasNext(); cellIterator.hasNext())
{
Row row = (Row)rowIterator.next();
cellIterator = row.cellIterator();
continue;
Cell cell = (Cell)cellIterator.next();
The output file is created but only the first cell is written and nothing else. I tested it with system print and all the data that I want shows up in console but is not written to the worksheet.
public class excel_read_2 {
public static void main(String[] args)
{
try
{
FileInputStream file = new FileInputStream(new File("C:/Users/h.M/Desktop/20151007-110016_outgoing.xls")); //input
HSSFWorkbook workbook = new HSSFWorkbook(file);
HSSFSheet sheet = workbook.getSheetAt(0);
Workbook wb = new HSSFWorkbook();
Sheet sheet1 = wb.createSheet("new sheet");
FileOutputStream fileOut = new FileOutputStream("C:/Users/h.M/Desktop/workbook.xls"); //output
int rowcounter = 0;
for (int rowNum = 150; rowNum < 180; rowNum++) {
Row r = sheet.getRow(rowNum);
if (r == null) {
continue;
}
int lastColumn=6;
for (int cn = 0; cn < lastColumn; cn++) {
Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
if (c == null){
}
else if (c.getCellType() == HSSFCell.CELL_TYPE_STRING) {
Row row = sheet1.createRow((short)rowcounter);
Cell cell = row.createCell(cn);
row.createCell(cn).setCellValue(c.getStringCellValue());
System.out.println("The cell was a string \" " + c.getStringCellValue()+" \" ");
} else if (c.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
Row row = sheet1.createRow((short)rowcounter);
Cell cell = row.createCell(cn);
row.createCell(cn).setCellValue(c.getNumericCellValue());
System.out.println("The cell was a number " + c.getNumericCellValue());
}
}
rowcounter++;
}
wb.write(fileOut);
fileOut.close();
file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Create the new row before you loop, then use it once per loop.
Row row = sheet1.createRow((short)rowcounter);
int lastColumn=6;
for (int cn = 0; cn < lastColumn; cn++) {
Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
if (c == null){
}
else if (c.getCellType() == HSSFCell.CELL_TYPE_STRING) {
Cell cell = row.createCell(cn);
cell.setCellValue(c.getStringCellValue());
I was using Apache POI 3.7 to create Excel with HSSF. It was working fine. But during load test, I realized that it is very slow. So I Googled and found I can use SXSSF. I changed my existing code to XSSF. The result was awesome.
But I stuck with a situation, autorezisecolum() is not functioning as expected. It displays large contents as #####, because the column width shrinks. I found it is a kind of a bug already raised.
Now my point is, is there any solution so that i can use SXSSF(very important for performance) with a nice output.
Note: I am using Windows 7, JDK 1.7.09 , POI-3.10.beta-2
Please help me.
Here is my code :
Main Function :
sxssfWorkbook = new SXSSFWorkbook(5);
sxssfSheet = (SXSSFSheet) sxssfWorkbook.createSheet(sheetName);
try {
// TO Write Header
//ew.writeHeaderRow(sheet, headerNames);
ew.writeHeaderRow(sxssfSheet, headerNames);
int rowNum = headerRow + 1;
for(Map.Entry<String, List<Object>> columnData : columnDataMap.entrySet()){
ew.writeNonHeaderRow(sxssfSheet, columnData.getValue(), rowNum);
rowNum++;
}
resizeXLSXColumns(sxssfSheet,rowNum-1);
sxssfWorkbook.write(outputStream);
outputStream.close();
public void writeHeaderRow(Sheet sheet, List<String> headerNames ) {
//public void writeHeaderRow(SXSSFSheet sxssfSheet, List<String> headerNames ) {
// LinkedHashMap<String,Object> mp = getFieldNames(obj);
// ArrayList<String> colNames = (ArrayList<String>) getColumnNames();
try {
XSSFCellStyle hCellStyle = getHeaderStyle();
SXSSFRow row = (SXSSFRow) sheet.createRow(headerRow);
for (int hCellInd = 0; hCellInd < headerNames.size(); hCellInd++) {
SXSSFCell cell = (SXSSFCell) row.createCell(hCellInd);
cell.setCellStyle(hCellStyle);
cell.setCellValue(headerNames.get(hCellInd));
//sheet.autoSizeColumn(hCellInd);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void writeNonHeaderRow(SXSSFSheet sxssfSheet, List<Object> rowObj, int rowIndex)
{
CreationHelper createHelper = sxssfWorkbook.getCreationHelper();
try {
SXSSFRow row = (SXSSFRow)sheet.createRow(rowIndex);
XSSFCellStyle normalStyle = getNormalStyle();
int count = 0;
for (int rCellInd = 0; rCellInd < rowObj.size(); rCellInd++) {
//Cell cell = row.createCell(rCellInd);
SXSSFCell cell = (SXSSFCell)row.createCell(rCellInd);
cell.setCellStyle(normalStyle);
Object cellData = rowObj.get(rCellInd);
if (cellData != null) {
if (cellData instanceof Double) {
cell.setCellValue((Double) cellData);
if((Double)cellData < 0){
cell.setCellStyle(getNegativeValueStyle());
}else if((Double)cellData == 0){
normalStyle.setDataFormat((short) SXSSFCell.CELL_TYPE_BLANK) ;
cell.setCellStyle(normalStyle);
}else
cell.setCellStyle(normalStyle);
} else {
//normalStyle.setDataFormat((short) HSSFCell.CELL_TYPE_BLANK);
cell.setCellType(SXSSFCell.CELL_TYPE_BLANK);
}
//sxssfSheet.autoSizeColumn();
//sxssfSheet.setColumnWidth(rCellInd, sxssfSheet.getColumnWidth(rCellInd));
//resizeXLSXColumns(sheet);
}
//autoResizeColumns(sxssfSheet);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void resizeXLSXColumns(Sheet sheet ,int rowNum){
SXSSFRow row = (SXSSFRow)sheet.getRow(rowNum);
Iterator<Cell> itr = row.cellIterator();
int max = 0;
while(itr.hasNext()){
Cell cell = itr.next();
int width = sheet.getColumnWidth(cell.getColumnIndex());
if(width > max){
max = width;
}
//sheet.setColumnWidth(cell.getColumnIndex(),max);
}
while(itr.hasNext()){
Cell cell = itr.next();
sheet.setColumnWidth(cell.getColumnIndex(),max);
}
}
I am making a program where I am reading data from excel files and store them in tables. I have made the program using Apache POI and works fine. But when files have blank cells as the one here I have some problems. The program skip the blanks and read the next data. Could anyone help me how I would do it? I know that there are several posts for this issue but I have not found something useful for me.
The code for reading the data from excel file is the below. As you can see I have 3 types of data. How i would give the option for BLANK CELL?
// Create an ArrayList to store the data read from excel sheet.
List sheetData = new ArrayList();
FileInputStream fis = null;
try {
// Create a FileInputStream that will be use to read the
// excel file.
fis = new FileInputStream(strfullPath);
// Create an excel workbook from the file system
HSSFWorkbook workbook = new HSSFWorkbook(fis);
// Get the first sheet on the workbook.
HSSFSheet sheet = workbook.getSheetAt(0);
// store the data read on an ArrayList so that we can printed the
// content of the excel to the console.
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
HSSFRow row = (HSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
while (cells.hasNext()) {
HSSFCell cell = (HSSFCell) cells.next();
data.add(cell);
}
sheetData.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
fis.close();
}
}
showExcelData(sheetData);
}
private static void showExcelData(List sheetData) {
// LinkedHashMap<String, String> tableFields = new LinkedHashMap();
for (int i = 0; i < sheetData.size(); i++) {
List list = (List) sheetData.get(i);
for (int j = 0; j < list.size(); j++) {
Cell cell = (Cell) list.get(j);
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
System.out.print(cell.getNumericCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
System.out.print(cell.getRichStringCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
System.out.print(cell.getBooleanCellValue());
} else if (cell.getCellType()== Cell.CELL_TYPE_BLANK ){
System.out.print(cell.toString());
}
if (j < list.size() - 1) {
System.out.print(", ");
}
}
System.out.println("");
}
}
}
Also I have read about workbook.setMissingCellPolicy(HSSFRow.RETURN_NULL_AND_BLANK);. Could this help me with my problem?
int maxNumOfCells = sheet.getRow(0).getLastCellNum(); // The the maximum number of columns
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
HSSFRow row = (HSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
for( int cellCounter = 0
; cellCounter < maxNumOfCells
; cellCounter ++){ // Loop through cells
HSSFCell cell;
if( row.getCell(cellCounter ) == null ){
cell = row.createCell(cellCounter);
} else {
cell = row.getCell(cellCounter);
}
data.add(cell);
}
sheetData.add(data);
YOUR METHOD:
public static void showExcelData(List sheetData) {
// LinkedHashMap<String, String> tableFields = new LinkedHashMap();
for (int i = 0; i < sheetData.size(); i++) {
List list = (List) sheetData.get(i);
for (int j = 0; j < list.size(); j++) {
Cell cell = (Cell) list.get(j);
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
System.out.print(cell.getNumericCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
System.out.print(cell.getRichStringCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
System.out.print(cell.getBooleanCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
System.out.print("THIS IS BLANK");
}
if (j < list.size() - 1) {
System.out.print(", ");
}
}
System.out.println("");
}
}
Explanation:
int maxNumOfCells = sheet.getRow(0).getLastCellNum(); - This line will make sure that you were able to get the number of columns. Using the Row's method .getLastCellNum() on the next rows will result to unexpected number. Example on your on row 3 of your spreadsheet, the method will return 2 since the next value is null.
for( int cellCounter = 0
; cellCounter < maxNumOfCells
; cellCounter ++){ // Loop through cells
HSSFCell cell;
if( row.getCell(cellCounter ) == null ){
cell = row.createCell(cellCounter);
} else {
cell = row.getCell(cellCounter);
}
data.add(cell);
}
Looping through the cells. From cell 0 (Base 0) to the last cell number. If the cell was found null, basically, it would create the cell with a blank value. Lastly, adding the cell to your List.
Another solution if you don't know the size of your spreadsheet is to loop through row and column and compare the index of row and column with the previous one you parsed. If the increment is more than one you will create the missing intermediate cells.