Need to get "value" based on given "key" from Excel file
I have excel file
File name Test xlsx
and sheet name sheet1
And sheet contains following key and value pairs and. JIRA ticket is unique .
Test case description
testdata key
Testdatavalue
testdata2 key
Testdata2 Value
testdata3 key
Testdata3 value
Sampiletest description1
Testcase-jira-1
user1id
Harshadh
Password
123ggg
Sampiletest2 discription
Testcase-jira-2
user2
Ramu
Password123
333ggg
Sampiletest3 discription
Test case jira-3
user3
latha
Password556
73hhh
Up to N number of rows
Here, I needs to get the data in following way by using Java Selenium Cucumber. I am going to use above test data to pass in Cucumber step definition class file by BDD way.
How can we get the data in definition file for following way
1)If pass Key value from current row how can we get the value of value for provide test input for webSeleinum element
Example 4th row data
Sampiletest3 discription|Test case jira-3| user3|latha|Password556|73hhh
.....
If I call the "user3" that should return "Password556"
Same way any row I need to get the value.
Please guide me
You can try the below code.
Feature file:
In examples, you can give the row numbers and sheet name to use the data for itterations.
Scenario Outline: Login to the application with multiple users.
Given get data from datasheet with "<test_id>" and "<sheetName>"
And login to the application
Examples:
| test_id | sheetName |
| 1 | Login |
| 2 | Login |
Excel data:
Read the data from excel and store it in a hashmap:
Create a class to read the data (Example: ExcelReader)
Use org.apache.poi.ss.usermodel and org.apache.poi.xssf.usermodel imports
public class ExcelReader {
private File file;
private FileInputStream inputStream;
private String testID;
private String sheetName;
private int testIdColumn;
private int numberOfColumns;
private XSSFCell cell;
public HashMap<String, String> fieldsAndValues;
public ExcelReader(String testId, String sheetName) {
file = new File(System.getProperty("user.dir") + "Excel location path");
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
System.out.println("File not found at given location: " + e);
}
this.testID = testId;
this.sheetName = sheetName;
this.readExcelAndCreateHashMapForData();
}
public HashMap<String, String> readExcelAndCreateHashMapForData() {
try {
fieldsAndValues = new HashMap<String, String>();
XSSFWorkbook workBook = new XSSFWorkbook(inputStream);
XSSFSheet sheet = workBook.getSheet(sheetName);
/* Get number of rows */
int lastRow = sheet.getLastRowNum();
int firstRow = sheet.getFirstRowNum();
int numberOfRows = lastRow - firstRow;
/*
* Get test_Id column number.
*/
outerloop: for (int row = 0; row < numberOfRows; row++) {
numberOfColumns = sheet.getRow(row).getLastCellNum();
for (int cellNumber = 0; cellNumber < numberOfColumns; cellNumber++) {
cell = sheet.getRow(row).getCell(cellNumber);
cell.setCellType(Cell.CELL_TYPE_STRING);
if (sheet.getRow(row).getCell(cellNumber).getStringCellValue().equalsIgnoreCase("test_ID")) {
testIdColumn = sheet.getRow(row).getCell(cellNumber).getColumnIndex();
break outerloop;
}
}
}
/*
* Search for the test id value.
*/
outerloop: for (int i = 0; i <= numberOfRows; i++) {
cell = sheet.getRow(i).getCell(testIdColumn);
cell.setCellType(Cell.CELL_TYPE_STRING);
if (testID.equals(sheet.getRow(i).getCell(testIdColumn).getStringCellValue())) {
for (int j = 0; j < numberOfColumns; j++) {
XSSFCell key = sheet.getRow(testIdColumn).getCell(j);
XSSFCell value = sheet.getRow(i).getCell(j);
key.setCellType(Cell.CELL_TYPE_STRING);
if (value == null) {
// Not capturing blank cells.
} else if (value.getCellType() == XSSFCell.CELL_TYPE_BLANK) {
// Not capturing blank cells.
} else {
value.setCellType(Cell.CELL_TYPE_STRING);
String fieldName = sheet.getRow(testIdColumn).getCell(j).getStringCellValue().trim();
String fieldValue = sheet.getRow(i).getCell(j).getStringCellValue().trim();
fieldsAndValues.put(fieldName, fieldValue);
}
}
System.out.println("Fields and values: " + Arrays.toString(fieldsAndValues.entrySet().toArray()));
break outerloop;
}
}
} catch (Exception e) {
System.out.println("Exception occurred at getting the sheet: " + e);
}
/* Return the hash map */
return fieldsAndValues;
}
}
StepDefinition:
ExcelReader excelReader;
#Given("get data from datasheet with \"(.*)\" and \"(.*)\"$")
public void get_data_from_datasheet(String testId, String sheetName) {
excelReader = new ExcelReader(testId, sheetName);
}
#And("login to the application")
public void loginApplication(){
driver.findElement(By.xpath("element")).sendKeys(excelReader.fieldsAndValues.get("UserName"));
driver.findElement(By.xpath("element")).sendKeys(excelReader.fieldsAndValues.get("PassWord"));
driver.findElement(By.xpath("element")).click();
}
I would recommend putting all the data for a scenario inside of Gherkin documents, but you might have a valid use cases for pulling data from excel. However, in my experience, these type of requirements are rare. The reason why it is not recommended is, your BDD feature files are your requirements and should contain the right level of information to document the expected behavior of the system. If your data comes from an excel, then it just makes the requirement reading bit more difficult and makes it difficult to maintain.
Saying that if there is a strong reason for you to have these data stored in excel, you could easily achieve this using NoCodeBDD. All you have to do is map the column names and upload the excel and the tool take care of the rest. Please check this .gif to see how it is done. https://nocodebdd.live/examples-using-excel
Disclaimer: I am the founder of NoCodeBDD.
If you are using Junit5 here is an example on how it is done https://newbedev.com/data-driven-testing-in-cucumber-using-excel-files-code-example
You can use external data-source to provide examples using qaf-cucumber. It will enable to provide data-file to be used to provide examples from external data-source, which includes csv, json, xml, excel file or database query.
We cannot directly integrete Excel file data to Gerkin file
.
Instead write separate method in step file to get data from excel and do your cases.
I use following code get the data - common code
public static JSONArray Read_Excel_Data(String filename, String sheetname) throws IOException {
FileInputStream fileIn = null;
Workbook workbookout = null;
JSONArray totalData = new JSONArray();
try{
log.info("Filename and Sheet name : "+filename+", "+ sheetname );
fileIn = new FileInputStream(new File(filename));
workbookout = new XSSFWorkbook(fileIn);
Sheet sh = workbookout.getSheet(sheetname);
int totRows = sh.getLastRowNum();
Row hearderRow = sh.getRow(0);
int totCols = hearderRow.getLastCellNum();
log.info("Total [ Rows and Colums ] : [ "+totRows+" and "+ totCols +" ] ");
for(int i=1; i <= totRows; i++ ){
log.info("Progressing row : "+i);
Row tempRw = sh.getRow(i);
JSONObject jo = new JSONObject();
for(int j=0; j<totCols; j++ ){
Cell tempCell = tempRw.getCell(j);
Cell HeaderCell = hearderRow.getCell(j);
try{
jo.put(HeaderCell.getStringCellValue(), tempCell.getStringCellValue());
log.info("Value in "+i+" / "+j+" :::::::::::: > "+tempCell.getStringCellValue() );
}catch (NullPointerException npe){
log.warn(":::::::::::: > Null Value in [ "+i+" / "+j+" ] ");
}
}
totalData.add(jo);
}
workbookout.close();
fileIn.close();
System.out.println("Total data :::::::: "+totalData.toJSONString());
}catch(Exception e){
e.printStackTrace();
log.error("Error Occured !!"+e.toString());
workbookout.close();
fileIn.close();
}
return totalData;
}
Related
I have just started learning selenium and I am not able to automate the code only reads one at a time from excel.I need to make the code read from the excel automatically instead of changing the row count number in this line "for (int i= 1; i<=6; i++)."
How can I make it automatically read from the code below?
public static void main(String[] args) throws IOException, InterruptedException {
System.setProperty("driver location");
WebDriver driver = new FirefoxDriver();
driver.get("link");
FileInputStream file = new FileInputStream("xcel file location");
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet= workbook.getSheet("SO Reg");
int noOfRows = sheet.getLastRowNum(); // returns the row count
System.out.println("No. of Records in the Excel Sheet:" + noOfRows);
int cols=sheet.getRow(1).getLastCellNum();
System.out.println("No. of Records in the Excel Sheet:" + cols);
for (int i= 1; i<=6; i++)
{
String SO_Name = row.getCell(0).getStringCellValue();
String Contact_Person = row.getCell(1).getStringCellValue();
String Address_1 = row.getCell(2).getStringCellValue();
String Address_2 = row.getCell(3).getStringCellValue();
String City = row.getCell(4).getStringCellValue();
String State = row.getCell(5).getStringCellValue();
String ZipCode = row.getCell(6).getStringCellValue();
String Phone_Number = row.getCell(8).getStringCellValue();
String Username = row.getCell(9).getStringCellValue();
String Email = row.getCell(10).getStringCellValue();
String Re_Type_Email = row.getCell(11).getStringCellValue();
//Registration Process
driver.findElement(By.cssSelector("p.text-white:nth-child(4) > a:nth-child(1)")).click(); //create an account
Thread.sleep(5000);
//Enter Data information
driver.findElement(By.id("SOName")).sendKeys(SO_Name);
driver.findElement(By.xpath("//*[#id=\"ContactPerson\"]")).sendKeys(Contact_Person);
driver.findElement(By.xpath("//*[#id=\"AddressLine1\"]")).sendKeys(Address_1);
driver.findElement(By.xpath("//*[#id=\"AddressLine2\"]")).sendKeys(Address_2);
driver.findElement(By.id("City")).sendKeys(City);
driver.findElement(By.id("State")).sendKeys(State);
driver.findElement(By.id("ZipCode")).sendKeys(ZipCode);
driver.findElement(By.id("Phone")).sendKeys(Phone_Number);
driver.findElement(By.xpath("//*[#id=\"UserName\"]")).sendKeys(Username);
driver.findElement(By.xpath("//*[#id=\"Email\"]")).sendKeys(Email);
driver.findElement(By.xpath("//*[#id=\"RandText\"]")).sendKeys(Re_Type_Email);
driver.findElement(By.id("ConfirmBox")).click();
driver.findElement(By.xpath("/html/body/app-root/app-soregistration/div[2]/div/div/div/div/form[2]/div/div[12]/div/button[1]")).click();
driver.findElement(By.cssSelector(".btn-green-text-black")).click(); //finish button
driver.findElement(By.cssSelector("p.text-white:nth-child(4) > a:nth-child(1)")).click(); //create an account
Thread.sleep(5000);
}
}
}
}
}
Do you only want to process newly added rows in Excel? If so, you should also save your last stay.
First of all, you can simply keep it in an infinite loop. Like
while(true){...}
. You can also start your loop here by keeping the last line you read from Excel in a static variable.
For example:
for (int i= previusLastSavedRowNum; i<=getLastRowNum; i++) {...}
If there is no new record, you can wait for a while in the WHILE loop.
Of course, for a better solution, you can create a SpringBoot project and set up a structure that listens for changes in Excel. When Excel detects the change, you can call the Selenium code with a trigger.
Better way to handle it is to open the excel file as CSV.
You can read all the data into one String with:
String excelToString = new String(Files.readAllBytes(Paths.get(path_to_file)));
If you want to keep it as table you can parse this String into String [] [] table.
current i am working to my school project using android studio, it is an attendance system where I store my data to Firestore and the user are able to download/export the data to become Excel file. What I am trying to do is how can I get the all data in a single document of a Collection in firestore
here's the code but it is only getting the first data in a document and it is showing in all the rows
export.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
firebaseFirestore.collection("QR").document("QRScanned").collection(LoginProfessorTabFragment.superName)
.document(TeacherDash.subjectName1).collection("Record of Attendance")
.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()){
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
HSSFSheet hssfSheet = hssfWorkbook.createSheet(TeacherDash.subjectName1);
for (int i = 0; i < 4; i++) {//for creating equal amount of row from the database
HSSFRow row = hssfSheet.createRow(i);
for (int j = 0; j <= cellCount; j++) {//creating each cell depends on the cell counter
for (DocumentSnapshot documentSnapshot : task.getResult()){
String a = documentSnapshot.getString("Name");
String b = documentSnapshot.getString("Date");
String c = documentSnapshot.getString("Time");
String d = documentSnapshot.getString("StudentNumber");
String e = documentSnapshot.getString("Course");
String f = documentSnapshot.getString("Subject");
String g = documentSnapshot.getString("Room");
String h = documentSnapshot.getString("Schedule");
arrayExport.add(a);
arrayExport.add(b);
arrayExport.add(c);
arrayExport.add(d);
arrayExport.add(e);
arrayExport.add(f);
arrayExport.add(g);
arrayExport.add(h);
arrayRemoveAll.add(a);
arrayRemoveAll.add(b);
arrayRemoveAll.add(c);
arrayRemoveAll.add(d);
arrayRemoveAll.add(e);
arrayRemoveAll.add(f);
arrayRemoveAll.add(g);
arrayRemoveAll.add(h);
row.createCell(0).setCellValue(arrayExport.get(0));
row.createCell(1).setCellValue(arrayExport.get(1));
row.createCell(2).setCellValue(arrayExport.get(2));
row.createCell(3).setCellValue(arrayExport.get(3));
row.createCell(4).setCellValue(arrayExport.get(4));
row.createCell(5).setCellValue(arrayExport.get(5));
row.createCell(6).setCellValue(arrayExport.get(6));
row.createCell(7).setCellValue(arrayExport.get(7));
}
}
}
try {
if (!filePath.exists()) {
filePath.createNewFile();
Toast.makeText(TeacherDash.this, "Download success", Toast.LENGTH_SHORT).show();
}
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
hssfWorkbook.write(fileOutputStream);
if (fileOutputStream != null) {
fileOutputStream.flush();
fileOutputStream.close();
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
});
}
});
You are looping over things multiple times where you probably don't need to be. If you want to get multiple documents from a collection and have each document be a single row in the spreadsheet where the document fields fill the columns within that row, then you only need a single loop - over documents. It would look something like this:
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
HSSFSheet hssfSheet = hssfWorkbook.createSheet(TeacherDash.subjectName1);
int rowNum = 0;
for (DocumentSnapshot documentSnapshot : task.getResult()){
// Create a new row for each document
HSSFRow row = hssfSheet.createRow(rowNum);
++rowNum;
// Get the data from the firestore document
// you want to put in this row
String name = documentSnapshot.getString("Name");
String date = documentSnapshot.getString("Date");
String time = documentSnapshot.getString("Time");
String num = documentSnapshot.getString("StudentNumber");
String course = documentSnapshot.getString("Course");
String sub = documentSnapshot.getString("Subject");
String room = documentSnapshot.getString("Room");
String sched = documentSnapshot.getString("Schedule");
// Fill the contents of that row
row.createCell(0).setCellValue(name);
row.createCell(1).setCellValue(date);
row.createCell(2).setCellValue(time);
row.createCell(3).setCellValue(num);
row.createCell(4).setCellValue(course);
row.createCell(5).setCellValue(sub);
row.createCell(6).setCellValue(room);
row.createCell(7).setCellValue(sched);
}
Update: Can we filter the student document record by date range? Ex: get all the students data ONLY from 7-26-2022 upto 7-27-2022 (which will comes from a date range picker). We need to generate a report on where the student go from 7-26 to 7-27 by looking at the field room and time. It is basically a contact tracing feature. We also need to put it in an excel file.
I believe we can also use the code that we have above but with a few modifications. We are thinking on replacing our database structure from:
firebaseFirestore.collection("QR").document("QRScanned").collection(LoginProfessorTabFragment.superName).document(TeacherDash.subjectName1).collection("Record of Attendance")
and replace the last .collection("Record of Attendance) to .collection() so that we can have an organized data. Then starts to query by the date range?
Thank you for answering our question.
I am new to Java coding. I am trying to find a Java code to retrieve the specific rows from an Excel file when it matches with my date. I found some code on the Web but not able to successfully use it for searching the Excel and retrieving the rows.
For example, my Excel sheet contains below
Empno join_date first_name last_name dob
123456 02/24/2017 John Smiths 07/14/1990
324455 02/24/2017 David Conner 12/29/1991
388787 03/14/2017 Sam Brown 04/13/1991
I need to retrieve all rows which matched join_date as '02/24/2017' like below.
123456 02/24/2017 John Smiths 07/14/1990
324455 02/24/2017 David Conner 12/29/1991
Please help.
public void readExcel() throws BiffException, IOException {
String FilePath = "D:\\fake.xls";
FileInputStream fs = new FileInputStream(FilePath);
Workbook wb = Workbook.getWorkbook(fs);
// the access to the sheet
Sheet sh = wb.getSheet("Sheet1");
// To get the number of rows present in sheet
int noOfRows = sh.getRows();
// To get the number of columns present in sheet
int noOfCols = sh.getColumns();
for (int row = 0; row < noOfRows; row++) {
if(sh.getCell(1, row).getContents()==your_date){
for (int row_1 =row ; row_1 < noOfRows; row_1++) {
for (int col = 0; col < noOfCols; col++) {
System.out.print(sh.getCell(col, row).getContents() + "\t");
}
System.out.println();
}
}
}
}
I Hope this will help you
You need to use JXL Library and XLS format file.
I am trying to get the column values for a specific row in a excel using poi methods.
I am able to get the values but the problem is I want the values only from second column.
public static ArrayList<String> GetBusinessComponentList() throws IOException{
String Tcname = "TC02_AggregateAutoByPassRO_CT";
ArrayList<String> arrayListBusinessFlow ;
arrayListBusinessFlow = new ArrayList<String>();
FileInputStream fileInput = new FileInputStream(oFile);
wb = new HSSFWorkbook(fileInput);
sheet = wb.getSheet("Business Flow");
int rownr = findRow(sheet, Tcname);
row = sheet.getRow(rownr);
for (Cell cell : row) {
String arr = cell.getStringCellValue();
arrayListBusinessFlow.add(arr);
}
return arrayListBusinessFlow;
}
private static int findRow(HSSFSheet sheet, String cellContent){
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
if (cell.getRichStringCellValue().getString().trim().equals(cellContent)) {
return row.getRowNum();
}
}
}
}
return 0;
}
}
OUTPUT:
[TC02_AggregateAutoByPassRO_CT,
StrategicUINewBusiness.Login,
StrategicUINewBusiness.CustomerSearch,
StrategicUINewBusiness.NamedInsured,
StrategicUINewBusiness.InsuranceScoreByPass,
StrategicUINewBusiness.VehiclePage,
StrategicUINewBusiness.DriverPage,
StrategicUINewBusiness.ViolationPage,
StrategicUINewBusiness.UnderwritingPage,
StrategicUINewBusiness.CoveragePage,
StrategicUINewBusiness.Portfolio,
StrategicUINewBusiness.BillingPage,
StrategicUINewBusiness.FinalSalePage,
StrategicUINewBusiness.PolicyConfirmation, , , ]
But I do not want my test case name when I am getting.
Please help me what changes i needed to do. thanks!
Currently, the code you're using to iterate over cells only returns cells with content or styling, and skips totally empty ones. You need to change to one of the other ways of iterating over cells, so you can control it to read from the second column onwards.
If you look at the Apache POI Documentation on iterating over rows and cells, you'll see a lot more details on the two main ways to iterate.
For your case, you'll want something like:
// We want to read from the 2nd column onwards, zero based
int firstColumn = 1;
// Always fetch at least 4 columns
int MY_MINIMUM_COLUMN_COUNT = 5;
// Work out the last column to go to
int lastColumn = Math.max(r.getLastCellNum(), MY_MINIMUM_COLUMN_COUNT);
// To format cells into strings
DataFormatter df = new DataFormatter();
// Iterate over the cells
for (int cn = firstColumn; cn < lastColumn; cn++) {
Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
if (c == null) {
// The spreadsheet is empty in this cell
} else {
// Do something useful with the cell's contents
// eg get the cells value as a string
String cellAsString = df.formatCellValue(c);
}
}
Use Cell cell=row.getCell(1); and also you can use sheet.getLastRowNum() to get the number last row on the sheet.
for (int i=0;i<=row.getLastCellNum();i++) {
if (i!=1){
//your stuff
}
}
I have a column defined in a table in postgres DB as:
counterparty_company_number character varying(255)
I have written a JAVA code to populate this table with values from corresponding columns of an excel file. In the sample excel file, this column has 8 rows,out of which some are blank,like:
counterparty_company_number
blank
234567
345678
456789
567890
1.03E+09
blank
blank
In my model class,I have defined the attribute for this column as:
private String counterparty_company_number;
In my code, I replaced blank values with empty String while saving.After reading the data from excel and saving in DB,the values in corresponding column of DB table appear as:
""
"234567.0"
"345678.0"
"456789.0"
"567890.0"
"1.0304388E9"
""
""
This is the snippet from the code that reads the excel file and populates the table in DB:
..
//reads excel file and stores values in a list
FileInputStream file = new FileInputStream(new File(filepath));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet xssfSheet = workbook.getSheetAt(0);
if (xssfSheet.getLastRowNum() != 0) {
for (int i = 1; i <= xssfSheet.getLastRowNum(); i++) {
Row row = xssfSheet.getRow(i);
for (int j = 0; j < row.getLastCellNum(); j++) {
Cell cell = row.getCell(j);
if (cell != null) {
valueHolder.add(cell.toString());
} else {valueHolder.add("");
}
}
}
}
..
//sets attribute values in model class
if (!valueHolder.isEmpty() && valueHolder != null) {
for (int i = 0; i < valueHolder.size(); i += 10) {
CardsCounterparty ccp = new CardsCounterparty();
..
ccp.setCounterparty_company_number(valueHolder.get(i+3).toString());
..
counterpartyList.add(ccp);//counterpartyList is a list of counterparty objects
}
}
return counterpartyList;//this list is passed to the code that will save the objects in DB table
}
..
//code to persist in DB
Configuration c = new Configuration();
c.configure("/hibernate.cfg.xml");
SessionFactory sf = c.buildSessionFactory();
Session s = sf.openSession();
Transaction tx = s.beginTransaction();
try {
for (int i = 0; i < counterparties.size(); i++) {//counterparties is the list of all counterparty objects to be saved
CardsCounterparty ccp = counterparties.get(i);
s.save(ccp);
}
tx.commit();
s.close();
} catch (Exception e) {
tx.rollback();
}
}
I want to know how can I get the values in proper numeric format like 234567 instead of 234567.0 and 1030438800 instead of 1.0304388E9. I cannot change the datatype to int from String as the values may contain characters also and there may be blank values also.
Examine your SQL to ensure that the value that is getting inserted is surrounded by quotes to prevent any conversion from happening.
"update tablex set counterparty_company_number = '" + value + "'"