I am trying to read data from a excel sheet but getting NullPointerException every time when reading data at the cell index =6. Put while(value != null) to avoid null values but still got the exception without any output.
I am putting the screen shot of excel sheet from where i am trying to get data.
Code-
package com.selenium;
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.io.IOException;
public class Exxcel {
public static void main(String[] args) throws Exception,NullPointerException{
//WebDriver driver= new FirefoxDriver();
//WebElement wb;
try{
FileInputStream file= new FileInputStream("C:\\Documents and Settings\\OMEGA\\Desktop\\Test Planning And Documents\\Automation Data.xlsx");
Workbook data=WorkbookFactory.create(file);
Sheet sheet=data.getSheet("Sheet1");
for(int i=1;i<=sheet.getLastRowNum();i++){
Row row= sheet.getRow(i);
int j=0;
String value=row.getCell(j).getStringCellValue();
while(value != null){
System.out.println(value);
}//while
while(value == null){
j++;
}
}//for
/*while(j1==9){
String value=row.getCell(j1).getStringCellValue();
System.out.println(value);
}//while2
*/
}catch(NullPointerException n){n.printStackTrace();
System.out.println("Null");
}// catch
}//main
}//class
StackTrace-
Null
java.lang.NullPointerException
at com.selenium.Exxcel.main(Exxcel.java:22)
It's not enough to check that row.getCell(j).getStringCellValue() != null. You should check that row.getCell(j) != null.
In addition, your while loops makes no sense :
The first one will either do nothing or print value forever (since you are not changing value inside the loop).
while(value != null) {
System.out.println(value);
}//while
The second one will either do nothing or increment j forever (since you are not changing value inside the loop).
while(value == null) {
j++;
}
I suggest you replace them with the following code :
Row row = sheet.getRow(i);
if (row != null) {
for (int j = 0; j < row.getLastCellNum(); j++) {
if (row.getCell(j) != null) {
if (row.getCell(j).getCellType() == CELL_TYPE_STRING) {
String value=row.getCell(j).getStringCellValue();
if(value != null) {
System.out.println(value);
}
}
}
}
}
Related
I want to read an Excel file and skip blank lines. My code reads data and blank cells. How can I skip blank lines, I am using Apache POI.
Help me with this problem
package com.company;
import org.apache.commons.compress.archivers.dump.InvalidFormatException;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.String;
import java.util.Iterator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
XSSFWorkbook library_table = new XSSFWorkbook(new FileInputStream("C:\\Users\\admin\\Desktop\\Курсовая\\Table for course work.xlsx"));
XSSFSheet library_sheet = library_table.getSheet("Library");
Iterator rowiter = ((XSSFSheet) library_sheet).rowIterator();
boolean continue_first_row = true;
System.out.println("1 - Name\n2 - Author\n3 - Date of publishing");
System.out.print("Choose type of search: ");
int choice = in.nextInt(), count = 0;
while(rowiter.hasNext()){
XSSFRow row = (XSSFRow) rowiter.next();
if (count == 0){
count++;
continue;
}
else {
System.out.println(row.getCell(choice));
}
}
}
}
Sheet.rowIterator does not contain totally empty rows. But it of course contains rows only having part of the cells filled. And it contains rows having format or having cells having formats even if those cells are empty.
So, if the need is to skip empty cells, then your program must check whether the found cell is empty or not. Simplest possibility is to check whether the Cell is null or Cell.toString equals a empty String.
...
while(rowiter.hasNext()) { // does not contain totally empty rows
XSSFRow row = (XSSFRow) rowiter.next();
if (count == 0) { //skip header row
count++;
continue;
} else {
XSSFCell cell = row.getCell(choice);
if (cell == null || "".equals(cell.toString())) { // check whether cell is empty
// cell is empty
} else {
System.out.println(cell.toString());
}
}
}
...
Note: Relying on Cell.toString is not good practice. Instead do using DataFormatter to get the cell values as String.
Example:
...
import org.apache.poi.ss.usermodel.DataFormatter;
...
while(rowiter.hasNext()) { // does not contain totally empty rows
XSSFRow row = (XSSFRow) rowiter.next();
if (count == 0) { //skip header row
count++;
continue;
} else {
XSSFCell cell = row.getCell(choice);
String cellValue = dataFormatter.formatCellValue(cell);
if ("".equals(cellValue)) { // check whether cell is empty
// cell is empty
} else {
System.out.println(cellValue);
}
}
}
...
I'm try to make a export Excel, and i need some formula for count number in my excel , but i have a data from database and it will be more than one. so i wanna clone that formula to next data.
it goes well , but the reference cell can't change to next cell, like if we tried copy cell from excel
cellOne[data].setCellFormula(celltwo[data].getCellFormula());
i want to copy count from data1 to data2
Instead of manipulating the formula strings to update formula references, best practice is really using a FormulaParser in my opinion. Advantage is that really all possible formulas can be updated as long as the FormulaParser knows them. Manipulating the formula strings easily leads to problems. For example a formula template like "SUM(H%d;I%d)" has %d as a variable to be replaced. But the percent sign could also be a not variable part in some formulas.
The apache poi has a FormulaParser which can be used. In Apache POI update formula references when copying I have shown this already for XSSF only.
Since this question is about HSSF I will show an String copyFormula(Sheet sheet, String formula, int coldiff, int rowdiff) method which works for SS that is for HSSFas well as for XSSF.
import java.io.FileOutputStream;
import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.formula.ptg.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
public class ExcelCopyFormula {
private static String copyFormula(Sheet sheet, String formula, int coldiff, int rowdiff) {
Workbook workbook = sheet.getWorkbook();
EvaluationWorkbook evaluationWorkbook = null;
if (workbook instanceof HSSFWorkbook) {
evaluationWorkbook = HSSFEvaluationWorkbook.create((HSSFWorkbook) workbook);
} else if (workbook instanceof XSSFWorkbook) {
evaluationWorkbook = XSSFEvaluationWorkbook.create((XSSFWorkbook) workbook);
}
Ptg[] ptgs = FormulaParser.parse(formula, (FormulaParsingWorkbook)evaluationWorkbook,
FormulaType.CELL, sheet.getWorkbook().getSheetIndex(sheet));
for (int i = 0; i < ptgs.length; i++) {
if (ptgs[i] instanceof RefPtgBase) { // base class for cell references
RefPtgBase ref = (RefPtgBase) ptgs[i];
if (ref.isColRelative())
ref.setColumn(ref.getColumn() + coldiff);
if (ref.isRowRelative())
ref.setRow(ref.getRow() + rowdiff);
}
else if (ptgs[i] instanceof AreaPtgBase) { // base class for range references
AreaPtgBase ref = (AreaPtgBase) ptgs[i];
if (ref.isFirstColRelative())
ref.setFirstColumn(ref.getFirstColumn() + coldiff);
if (ref.isLastColRelative())
ref.setLastColumn(ref.getLastColumn() + coldiff);
if (ref.isFirstRowRelative())
ref.setFirstRow(ref.getFirstRow() + rowdiff);
if (ref.isLastRowRelative())
ref.setLastRow(ref.getLastRow() + rowdiff);
}
}
formula = FormulaRenderer.toFormulaString((FormulaRenderingWorkbook)evaluationWorkbook, ptgs);
return formula;
}
public static void main(String[] args) throws Exception {
//String type = "XSSF";
String type = "HSSF";
try (Workbook workbook = ("XSSF".equals(type))?new XSSFWorkbook():new HSSFWorkbook();
FileOutputStream out = new FileOutputStream(("XSSF".equals(type))?"Excel.xlsx":"Excel.xls") ) {
Sheet sheet = workbook.createSheet();
for (int r = 2 ; r < 10; r++) {
Row row = sheet.createRow(r);
for (int c = 2 ; c < 5; c++) {
Cell cell = row.createCell(c);
if (r == 2) {
if (c == 2) cell.setCellValue("No");
if (c == 3) cell.setCellValue("Number One");
if (c == 4) cell.setCellValue("Number Two");
} else {
if (c == 2) cell.setCellValue("data" + (r-2));
if (c == 3) cell.setCellValue(r*c);
if (c == 4) cell.setCellValue(r*c);
}
}
}
for (int r = 2 ; r < 10; r++) {
Row row = sheet.getRow(r);
Cell cell = row.createCell(5);
String formula = "D4+E4";
if (r == 2) cell.setCellValue("Formula");
else cell.setCellFormula(copyFormula(sheet, formula, 0, r-3));
}
for (int r = 2 ; r < 10; r++) {
Row row = sheet.getRow(r);
Cell cell = row.createCell(6);
String formula = "G4+F5";
if (r == 2) cell.setCellValue("Cumulative");
else if (r == 3) cell.setCellFormula("F4");
else cell.setCellFormula(copyFormula(sheet, formula, 0, r-4));
}
workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();
workbook.write(out);
}
}
}
Is there any way to solve sorting web element ? I am getting difficulties while sorting using drag and drop function. My drag and drop is not working, i think my logic is good, but while running code nothing happening...
public void sortable() { // loop for drag and drop is not working...
try {
driver.get("http://jqueryui.com/");
myLibrary.clickButton(By.partialLinkText("Sortable"));
WebElement iframe = driver.findElement(By.xpath("//*[#id='content']/iframe"));
driver.switchTo().frame(iframe);
String temp = "";
Thread.sleep(10 * 1000); //manual work to disorder sortable list prior to start for loop.
Actions action = new Actions(driver);
int i = 1, j = 1;
for (i = 1; i < 8; i = i + 1) {
WebElement sourceText = driver.findElement(By.cssSelector("#sortable > li:nth-child(" + i + ")"));
WebElement dragElement = driver
.findElement(By.cssSelector("#sortable > li:nth-child(" + i + ") > span"));
while (true) {
temp = "Item" + " " + j;
if (temp == sourceText.getText()) {
WebElement targetElement = driver
.findElement(By.cssSelector("#sortable > li:nth-child(" + j + ")"));
action.moveToElement(dragElement).dragAndDrop(dragElement, targetElement).build().perform();
Thread.sleep(1 * 1000);
break;
} else {
if (j == 8) {
break;
} else {
j++;
}
}
}
}
Thread.sleep(5 * 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
Building upon what #JeffC posted as an answer, here's another variant of the same that uses some of the built in capabilities of Java.
We basically use the List.sort() and a Comparator to get this done.
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class SorterSample {
private RemoteWebDriver driver;
#BeforeClass
public void setup() {
driver = new ChromeDriver();
}
#AfterClass
public void cleanup() {
if (driver != null) {
driver.quit();
}
}
#Test
public void testMethod() {
String url = "http://jqueryui.com/sortable/";
driver.get(url);
driver.switchTo().frame(driver.findElement(By.cssSelector("iframe.demo-frame")));
List<WebElement> items = driver.findElements(By.cssSelector("#sortable > li"));
items.sort(
(o1, o2) -> {
int compareValue = o1.getText().compareTo(o2.getText());
if (compareValue < 0) {
new Actions(driver).dragAndDrop(o1, o2).perform();
}
return compareValue;
});
}
}
This was a fun little exercise...
Rather than trying to invent your own sorting code, you should use an established sorting algorithm. I chose bubble sort but you can pick any one you want. If you are just sorting a few items, this should work just fine. It runs in just a few seconds.
The main code
String url = "http://jqueryui.com/sortable/";
driver.get(url);
driver.switchTo().frame(driver.findElement(By.cssSelector("iframe.demo-frame")));
List<WebElement> items = driver.findElements(By.cssSelector("#sortable > li"));
bubbleSort(items);
The bubble sort method
static void bubbleSort(List<WebElement> items)
{
int n = items.size();
boolean swapped;
for (int i = 0; i < n - 1; i++)
{
swapped = false;
for (int j = 0; j < n - i - 1; j++)
{
int compare = items.get(j).getText().compareTo(items.get(j + 1).getText());
if (compare < 0)
{
swap(items.get(j + 1), items.get(j));
swapped = true;
}
}
// break if no elements were swapped
if (swapped == false)
{
break;
}
}
}
and finally the support method to swap items
public static void swap(WebElement source, WebElement target)
{
new Actions(driver).dragAndDrop(source, target).perform();
}
I just ran this code a few times and it's working just fine. It sorts the items in reverse order (so you don't have to mix them up manually). This is not the most efficient way to do this but I wanted to be able to watch the bubble sort work so you see each swap. If you want this to go faster, you can pull the text from the items, sort that list and then line up the elements with their sorted text so you only have to do n swaps.
package com.selenium;
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.io.IOException;
public class Exxcel {
public static void main(String[] args) throws Exception,NullPointerException{
//WebDriver driver= new FirefoxDriver();
//WebElement wb;
String Value;
try{
FileInputStream file= new FileInputStream("C:\\Documents and Settings\\OMEGA\\Desktop\\Test Planning And Documents\\Automation Data.xlsx");
Workbook data=WorkbookFactory.create(file);
Sheet sheet=data.getSheet("Sheet1");
for(int i=1;i<=sheet.getLastRowNum();i++){
Row row = sheet.getRow(i);
if(row != null){
// Putting condition to check row is null or not
for (int j = 1; j < row.getLastCellNum();) {
if (row.getCell(j) != null) {
// Putting condition to check row cell is null or not
String value=row.getCell(j).getStringCellValue();
Value=value;
//String value1=row.getCell(j+1).getStringCellValue();
String[] array= new String[2];
array[0]=Value;
//array[1]=value1;
if( array[0] != null ) {
// Putting condition to check array[] is null or not
System.out.println(array[0]);
//System.out.println(array[1]);
}
}
}
}
}
}catch(NullPointerException n){
n.printStackTrace();
//System.out.println("Null");
}// catch
}//main
}//class
This is the code which i am trying to run but as soon as i click on run buton the entier eclipse stops responding. Don't know why its happening?
It is possible that your loop never ends:
for (int j = 1; j < row.getLastCellNum();) {
I don't see j being incremented anywhere in your code.
An infinite loop on the main GUI thread would have the side-effect to freeze the IDE.
As the OP Shantanu commented, adding an increment j++ was enough to resolve the situation:
for(int j=0; j<=row.getLastRowNumber(); j++) {
...
}
You must put an increment or decrement operater on the second for loop. You have not put any condition in the second loop which is why your program is going in an infinite loop and eclipse becomes slow in performance.
Change your code with:
for(int j=0; j<=row.getLastRowNumber(); j++)
{
//Your Code
}
I have a requirement to read Excel file particular column values.
I unable to read the cell values as they are.
My code is
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.Workbook;
public class ExcelSheetColumn
{
public static void main(String[] args) throws InvalidFormatException, FileNotFoundException, IOException
{
Workbook wb = WorkbookFactory.create(new FileInputStream("C:/Users/Pradeep.HALCYONTEKDC/Desktop/My Data/ExcelFiles/XLS1.xls"));
Sheet sheet = wb.getSheet("Retail - All");
Row row=null;
Cell cell ;
for (int j=0; j< sheet.getLastRowNum()+1; j++)
{
row = sheet.getRow(j);
cell = row.getCell(0);
if(cell!=null)
{
int type = cell.getCellType();
if (type == HSSFCell.CELL_TYPE_STRING)
System.out.println(cell.getRichStringCellValue().toString());
else if (type == HSSFCell.CELL_TYPE_NUMERIC)
System.out.println(cell.getNumericCellValue());
else if (type == HSSFCell.CELL_TYPE_BOOLEAN)
System.out.println( cell.getBooleanCellValue());
else if (type == HSSFCell.CELL_TYPE_BLANK)
System.out.println(cell.getColumnIndex() + "] = BLANK CELL");
}
}
}
}
Excel column values are
79
999861
999861
https://staging.adpcreditsolutions.com
/index/contract_decision
9200278
2011/01/17
79
5032944200
IL4-PCC#TEST.COM
1979/12/31
0.00
0.00
But the output I am getting is
79.0
999861.0
999861.0
https://staging.adpcreditsolutions.com
/index/contract_decision
9200278.0
17-Jan-2011
79.0
5.0329442E9
IL4-PCC#TEST.COM
31-Dec-1979
0.0
0.0
How to read code my above program to read the excel column values as they are? Please help me!!
if (type == HSSFCell.CELL_TYPE_NUMERIC)
{
String stringValue=""+cell.getNumericCellValue();
String[] splitValue=stringValue.split(".0");
System.out.println(splitValue[0]);
}
System.out.println(cell.toString());//here is the problem
toString() method returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object.
Use cell.getStringCellValue()
instead
cell.toString()
And propor usage needed.
For numeric values you have to use
getNumericCellValue()
and put a condition there
if(cell!=null)
{
int type = cell.getCellType();
if (type == HSSFCell.CELL_TYPE_STRING)
System.out.println(cell.getRichStringCellValue().toString());
else if (type == HSSFCell.CELL_TYPE_NUMERIC)
String[] splits = String.valueOf(cell.getNumericCellValue()).split(".");
System.out.println(splits[0]);
else if (type == HSSFCell.CELL_TYPE_BOOLEAN)
System.out.println( cell.getBooleanCellValue());
else if (type == HSSFCell.CELL_TYPE_BLANK)
System.out.println(cell.getColumnIndex() + "] = BLANK CELL");
}
You can not read String value from numeric field. it throws exception.
This is working for me. try this
if (currentCell.getCellType().toString().contentEquals("NUMERIC")) {
value = String.valueOf(currentCell.getNumericCellValue());
value = value.endsWith(".0") ? value.replace(".0", "") : value;
}