detecting and replacing variables in a string by values - java

I have an excel sheet whose first column contains following data "What is ${v1} % of ${v2}?", two more columns (v1 and v2) in this sheet contains {"type":"int", "minimum":15, "maximum":58} and {"type":"int", "minimum":30, "maximum":100}, these are the ranges of variable v1 and v2. I need to replace v1 and v2 in the expression with a random value from the given range and store the expression in another spread sheet using JAVA. How can I do this by making use of JETT?
For example: I should store "What is 25% of 50?"
This is what I have done,I am able to read the column in my java program but not replace the values
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
public class ACGS {
public static void main(String[] args) throws Exception {
//test file is located in your project path
FileInputStream fileIn = new FileInputStream("C://users/user/Desktop/Content.xls");
//read file
POIFSFileSystem fs = new POIFSFileSystem(fileIn);
HSSFWorkbook filename = new HSSFWorkbook(fs);
//open sheet 0 which is first sheet of your worksheet
HSSFSheet sheet = filename.getSheetAt(0);
//we will search for column index containing string "Your Column Name" in the row 0 (which is first row of a worksheet
String columnWanted = "${v1}";
Integer columnNo = null;
//output all not null values to the list
List<Cell> cells = new ArrayList<Cell>();
Row firstRow = sheet.getRow(0);
for(Cell cell:firstRow){
if (cell.getStringCellValue().contains(columnWanted)){
columnNo = cell.getColumnIndex();
System.out.println("cell contains "+cell.getStringCellValue());
}
}
if (columnNo != null){
for (Row row : sheet) {
Cell c = row.getCell(columnNo);
if (c == null || c.getCellType() == Cell.CELL_TYPE_BLANK) {
// Nothing in the cell in this row, skip it
} else {
cells.add(c);
}
}
} else{
System.out.println("could not find column " + columnWanted + " in first row of " + fileIn.toString());
}
}
}

First, it looks like you aren't using JETT at all. You appear to be attempting to read the spreadsheet yourself and do some processing.
Here is how you would do this in JETT. JETT doesn't provide its own random number support, but together with its Apache Commons JEXL expression support, and Java's own Random, you can publish the expected ranges of your random variables as beans to JETT, and you can calculate a random variable with an expression.
First, create your template spreadsheet, populating it with expressions (between ${ and }) that JETT will evaluate. One cell might contain something like this.
What is ${rnd.nextInt(v1Max - v1Min + 1) + v1Min}% of ${rnd.nextInt(v2Max - v2Min + 1) + v2Min}?
Next, create beans to be supplied to JETT. These beans are the named objects that are available to JEXL expressions in your spreadsheet template.
Map<String, Object> beans = new HashMap<String, Object>();
beans.put("v1Min", 15);
beans.put("v1Max", 58);
beans.put("v2Min", 30);
beans.put("v2Max", 100);
beans.put("rnd", new Random());
Next, create your code that invokes the JETT ExcelTransformer.
try
{
ExcelTransformer transformer = new ExcelTransformer();
// template file name, destination file name, beans
transformer.transform("Content.xls", "Populated.xls", beans);
}
catch (IOException e)
{
System.err.println("IOException caught: " + e.getMessage());
}
catch (InvalidFormatException e)
{
System.err.println("InvalidFormatException caught: " + e.getMessage());
}
In the resultant spreadsheet, you will see the expressions evaluated. In the cell that contained the expressions above, you will see for example:
What is 41% of 38?
(Or you will see different numbers, depending on the random numbers generated.)

Related

Check if a cell has a data validation of type list behind it in APACHE POI [duplicate]

I'm trying to get the pre-existing data validation information out of an Excel cell with Apache POI. For example, if a cell already has a data validation constraint that only allows integers between 0 and 100, I'd like to be able to pull that information out of the cell.
On the Data Validation section of the Quick Guide, the examples only seem to cover adding validation to cells, not retrieving it. I've found the DataValidationEvaluator object that appears to do what I am looking for with its getValidationForCell method. However, I cannot figure out how to properly instantiate an instance of this object since its constructor requires a WorkbookEvaluatorProvider which, according to its official documentation, is for internal POI use only.
Any help or guidance on this would be greatly appreciated! Maybe one of you will know a much easier and better way to get this information. Here is a snippet of code that demonstrates what I would like to do:
// The impossible (?) bit
WorkbookEvaluatorProvider wep = ...???...
// Easy through here
DataValidationEvaluator dve = new DataValidationEvaluator(wb, wep)
CellReference cRef = aRef.getFirstCell();
DataValidation dv = dve.getValidationForCell(cRef);
We can have a method which gets the data validation constraint out of the given Cell.
First we need get sheet's data validations and then for each data validation get Excel cell ranges the data validation applies to. If the cell is in one of that cell ranges then return that validation constraint.
Example:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.FileInputStream;
import java.util.List;
import java.util.Arrays;
public class ExcelGetDataValidationConstraints {
static DataValidationConstraint getDataValidationConstraint(Cell cell) {
Sheet sheet = cell.getSheet();
List<? extends DataValidation> dataValidations = sheet.getDataValidations(); // get sheet's data validations
for (DataValidation dataValidation : dataValidations) {
CellRangeAddressList addressList = dataValidation.getRegions(); // get Excel cell ranges the data validation applies to
CellRangeAddress[] addresses = addressList.getCellRangeAddresses();
for (CellRangeAddress address : addresses) {
if (address.isInRange(cell)) { // if the cell is in that cell range
DataValidationConstraint constraint = dataValidation.getValidationConstraint();
return constraint; // return this
}
}
}
return null; // per default return null
}
public static void main(String[] args) throws Exception {
//String filePath = "ExcelWorkbook.xls";
String filePath = "ExcelWorkbook.xlsx";
Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
DataValidationConstraint constraint = getDataValidationConstraint(cell);
System.out.println(cell.getAddress());
System.out.println(constraint);
if (constraint != null) {
System.out.println("DataValidationConstraint.ValidationType: " + constraint.getValidationType());
//https://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/DataValidationConstraint.ValidationType.html
System.out.println("Formula1: " + constraint.getFormula1());
System.out.println("DataValidationConstraint.OperatorType: " + constraint.getOperator());
//https://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/DataValidationConstraint.OperatorType.html
System.out.println("Formula2: " + constraint.getFormula2());
String[] listValues = constraint.getExplicitListValues();
if (listValues != null) System.out.println("List values: " + Arrays.asList(listValues));
}
System.out.println();
}
}
workbook.close();
}
}
See How to get datavalidation source for a cell in java using poi? for working with differnt types of list constraints.
To answer your question about using WorkbookEvaluatorProvider:
WorkbookEvaluatorProvider is an interface which is implemented by all FormulaElevators. So to get a WorkbookEvaluatorProvider we need creating a FormulaEvaluator. This can be done using CreationHelper.html#createFormulaEvaluator. The CreationHelper can be got form the Workbook.
So what you have described could be done using method:
DataValidation getDataValidationFromDataValidationEvaluator (Cell cell) {
Sheet sheet = cell.getSheet();
Workbook workbook = sheet.getWorkbook();
WorkbookEvaluatorProvider workbookEvaluatorProvider =
(WorkbookEvaluatorProvider)workbook.getCreationHelper().createFormulaEvaluator();
DataValidationEvaluator dataValidationEvaluator = new DataValidationEvaluator(workbook, workbookEvaluatorProvider);
DataValidation dataValidation = dataValidationEvaluator.getValidationForCell(new CellReference(cell));
return dataValidation;
}
Complete example:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.formula.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.FileInputStream;
import java.util.List;
import java.util.Arrays;
public class ExcelGetDataValidationFromDataValidationEvaluator {
static DataValidation getDataValidationFromDataValidationEvaluator (Cell cell) {
Sheet sheet = cell.getSheet();
Workbook workbook = sheet.getWorkbook();
WorkbookEvaluatorProvider workbookEvaluatorProvider =
(WorkbookEvaluatorProvider)workbook.getCreationHelper().createFormulaEvaluator();
DataValidationEvaluator dataValidationEvaluator = new DataValidationEvaluator(workbook, workbookEvaluatorProvider);
DataValidation dataValidation = dataValidationEvaluator.getValidationForCell(new CellReference(cell));
return dataValidation;
}
public static void main(String[] args) throws Exception {
//String filePath = "ExcelWorkbook.xls";
String filePath = "ExcelWorkbook.xlsx";
Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
System.out.println(cell.getAddress());
DataValidation dataValidation = getDataValidationFromDataValidationEvaluator(cell);
if (dataValidation!=null) {
DataValidationConstraint constraint = dataValidation.getValidationConstraint();
System.out.println(dataValidation);
System.out.println(constraint);
if (constraint != null) {
System.out.println("DataValidationConstraint.ValidationType: " + constraint.getValidationType());
//https://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/DataValidationConstraint.ValidationType.html
System.out.println("Formula1: " + constraint.getFormula1());
System.out.println("DataValidationConstraint.OperatorType: " + constraint.getOperator());
//https://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/DataValidationConstraint.OperatorType.html
System.out.println("Formula2: " + constraint.getFormula2());
String[] listValues = constraint.getExplicitListValues();
if (listValues != null) System.out.println("List values: " + Arrays.asList(listValues));
}
}
System.out.println();
}
}
workbook.close();
}
}
Worth testing what approach is more performant.

Java Sellinum Cucumber Excell data driven

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;
}

How to read .xlsx file with apache poi?

See the picture below, I am trying to write a program that can "scan" a given row with no limit of from which cell to which cell, then, find all the "strings" that are identical the same. Is it possible to do that? Thank you.
To give an example so that this will not be very confusing, for ex.: On row H, you see there are customer's names, there are "Coresystem", "Huawei", "VIVO", etc... Now the problem is, what if the names are not grouped together, they are all split up, like, On H5, it will be "Huawei" and On H9, it will be "VIVO", etc, it's like, unlike the picture provided below, on row H all the names are split up, and I want apache POI to find all the customers that have the same name, for ex.: If user enter "coReSysteM", it should be able to find all the .equalsIgnoreCase of all Coresystem on row H (btw, the user should be able to enter the customer's name that they want to enter and the row they want to search for), and display from A5, B5, C5, D5, E5, F5, G5, H5 to A14, B14, C14, D14, E14, F14, G14, H5, is it possible?
I was thinking about setting a formula to find all the customer, for example: =CountIf
These are the code that I am currently trying to do, but then I am stuck with it:
package excel_reader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelReader2d {
ExcelReader link = new ExcelReader();
Scanner scan = new Scanner(System.in);
// instance data
private static int numberGrid[][] = null;
private static String stringGrid[][] = null;
// constructor
public ExcelReader2d(String desLink) {
}
// methods
public void ExeScan() throws FileNotFoundException, IOException {
Scanner scan = new Scanner(System.in);
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("C:\\Users\\Sonic\\Desktop\\20191223 IMPORTS.xlsx"));
XSSFSheet sheet = workbook.getSheetAt(0);
final int rowStart = Math.min(15, sheet.getFirstRowNum()), rowEnd = Math.max(1400, sheet.getLastRowNum());
System.out.print("Enter the rows that you want to search for: (for ex. the rows that stores customer's name) ");
int searchRows = scan.nextInt();
System.out.print("Enter the customer's name that you are looking for: ");
String name = scan.nextLine();
//int rowNum;
// Search given row
XSSFRow row = sheet.getRow(searchRows);
try {
for (int j = 4; j < rowEnd; j++) {
Row r = sheet.getRow(j);
if (name.equalsIgnoreCase(name)) {
row.getCell(j).getStringCellValue();
}
// skip to next iterate if that specific cell is empty
if (r == null)
continue;
}
} catch (Exception e){
System.out.println("Something went wrong.");
}
}
}
ps. I know that this will be very confusing, but please feel free to ask for any kind of questions to help you get rid of the confusion and help me either because this has been a problem for me. Thank you very much and I will super appreciated for your help. Currently using apache poi, vscode, java.
I would iterate over the rows in the sheet and get the string content of cell 7 (H) from each row. If that string fulfills the requirement equalsIgnoreCase the searched value, that row is one of the result rows, else not.
One could collect the result rows in a List<Row>. Then this List contains the result rows after that.
Example:
ExcelWorkbook.xlsx:
Code:
import org.apache.poi.ss.usermodel.*;
import java.util.List;
import java.util.ArrayList;
import java.io.FileInputStream;
public class ExcelReadRowsByColumnValue {
public static void main(String[] args) throws Exception {
String filePath = "./ExcelWorkbook.xlsx";
String toSearch = "coresystem";
int searchColumn = 7; // column H
List<Row> results = new ArrayList<Row>();
DataFormatter dataFormatter = new DataFormatter();
Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) { // iterate over all rows in the sheet
Cell cellInSearchColumn = row.getCell(searchColumn); // get the cell in seach column (H)
if (cellInSearchColumn != null) { // if that cell is present
String cellValue = dataFormatter.formatCellValue(cellInSearchColumn, formulaEvaluator); // get string cell value
if (toSearch.equalsIgnoreCase(cellValue)) { // if cell value equals the searched value
results.add(row); // add that row to the results
}
}
}
// print the results
System.out.println("Found results:");
for (Row row : results) {
int rowNumber = row.getRowNum()+1;
System.out.print("Row " + rowNumber + ":\t");
for (Cell cell : row) {
String cellValue = dataFormatter.formatCellValue(cell, formulaEvaluator);
System.out.print(cellValue + "\t");
}
System.out.println();
}
workbook.close();
}
}
Result:

How to get datavalidation source for a cell in java using poi?

I have defined a list of valuses my_list in one excel sheet as follow:
In another excel sheet, I reference for some cells to that list sothat this list is shown as dropdown in the cell as follows:
Using poi, I go throw excel sheet rows/columns and read cells for cell.
I get value of cells using method:
cell.getStringCellValue()
My question is how to get the name of the list my_list from the cell?
This problem contains multiple different problems.
First we need get sheet's data validations and then for each data validation get Excel cell ranges the data validation applies to. If the cell is in one of that cell ranges and if data validation is a list constraint then do further proceedings. Else return a default value.
If we have a explicit list like "item1, item2, item3, ..." then return this.
Else if we have a formula creating the list and is formula1 a area reference to a range in same sheet, then get all cells in that cell range and put their values in an array and return this.
Else if we have a formula creating the list and is formula1 a reference to a defined name in Excel, then get the Excel cell range the name refers to. Get all cells in that cell range and put their values in an array and return this.
Complete Example. The ExcelWorkbook contains the data validation in first sheet cell D1.
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.FileInputStream;
import java.util.List;
public class ExcelGetDataValidationList {
static String[] getDataFromAreaReference(AreaReference areaReference, Sheet sheet) {
DataFormatter dataFormatter = new DataFormatter();
Workbook workbook = sheet.getWorkbook();
CellReference[] cellReferences = areaReference.getAllReferencedCells(); // get all cells in that cell range
String[] listValues = new String[cellReferences.length]; // and put their values in an array
for (int i = 0 ; i < cellReferences.length; i++) {
CellReference cellReference = cellReferences[i];
if (cellReference.getSheetName() == null) {
listValues[i] = dataFormatter.formatCellValue(
sheet.getRow(cellReference.getRow()).getCell(cellReference.getCol())
);
} else {
listValues[i] = dataFormatter.formatCellValue(
workbook.getSheet(cellReference.getSheetName()).getRow(cellReference.getRow()).getCell(cellReference.getCol())
);
}
}
return listValues;
}
static String[] getDataValidationListValues(Sheet sheet, Cell cell) {
List<? extends DataValidation> dataValidations = sheet.getDataValidations(); // get sheet's data validations
for (DataValidation dataValidation : dataValidations) {
CellRangeAddressList addressList = dataValidation.getRegions(); // get Excel cell ranges the data validation applies to
CellRangeAddress[] addresses = addressList.getCellRangeAddresses();
for (CellRangeAddress address : addresses) {
if (address.isInRange(cell)) { // if the cell is in that cell range
DataValidationConstraint constraint = dataValidation.getValidationConstraint();
if (constraint.getValidationType() == DataValidationConstraint.ValidationType.LIST) { // if it is a list constraint
String[] explicitListValues = constraint.getExplicitListValues(); // if we have a explicit list like "item1, item2, item3, ..."
if (explicitListValues != null) return explicitListValues; // then return this
String formula1 = constraint.getFormula1(); // else if we have a formula creating the list
System.out.println(formula1);
Workbook workbook = sheet.getWorkbook();
AreaReference areaReference = null;
try { // is formula1 a area reference?
areaReference = new AreaReference(formula1,
(workbook instanceof XSSFWorkbook)?SpreadsheetVersion.EXCEL2007:SpreadsheetVersion.EXCEL97
);
String[] listValues = getDataFromAreaReference(areaReference, sheet); //get data from that area reference
return listValues; // and return this
} catch (Exception ex) {
//ex.printStackTrace();
// do nothing as creating AreaReference had failed
}
List<? extends Name> names = workbook.getNames(formula1); // is formula1 a reference to a defined name in Excel?
for (Name name : names) {
String refersToFormula = name.getRefersToFormula(); // get the Excel cell range the name refers to
areaReference = new AreaReference(refersToFormula,
(workbook instanceof XSSFWorkbook)?SpreadsheetVersion.EXCEL2007:SpreadsheetVersion.EXCEL97
);
String[] listValues = getDataFromAreaReference(areaReference, sheet); //get data from that area reference
return listValues; // and return this
}
}
}
}
}
return new String[]{}; // per default return an empy array
}
public static void main(String[] args) throws Exception {
//String filePath = "ExcelWorkbook.xls";
String filePath = "ExcelWorkbook.xlsx";
Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));
Sheet sheet = workbook.getSheetAt(0);
Row row = sheet.getRow(0); if (row == null) row = sheet.createRow(0); // row 1
Cell cell = row.getCell(3); if (cell == null) cell = row.createCell(3); // cell D1
System.out.println(cell.getAddress() + ":" + cell);
String[] dataValidationListValues = getDataValidationListValues(sheet, cell);
for (String dataValidationListValue : dataValidationListValues) {
System.out.println(dataValidationListValue);
}
workbook.close();
}
}
Note: Current Excel versions allow data validation list reference to be a direct area reference to another sheet without using a named range. But this is nothing what apache poi can get. Apache poi is on Excel 2007 level only.
The my_list your mean is Define Name in excel, honestly i don't know is apache-poi can do it or not. But this is may a clue, you can get the my_list formula using .getRefersToFormula();, please try the bellow code :
String defineNameFromExcel = "my_list";
List define = new ArrayList<>();
define = myExcel.getAllNames();
Iterator<List> definedNameIter = define.iterator();
while(definedNameIter.hasNext()) {
Name name = (Name) definedNameIter.next();
if(name.getNameName().equals(defineNameFromExcel)) {
String sheetName = name.getSheetName();
String range = name.getRefersToFormula();
range = range.substring(range.lastIndexOf("!"));
System.out.println(sheetName);
System.out.println(range);
}
}
It will get sheet name and range, with the information may you can extract for get the value you want, hope this helps.
Reference

perform operations on excel data sheet using java

there are four columns in excel sheet
I need to perform operations on three columns and display the result on the fourth one.
Image with data in excel
If I perform B9-D9 then the result is equal to C9.
when this happens the output should be as "matched".
i need to know how to access each row and column and perform the necessary operation on it.
See if you can help me and let me know if any additional details are required.
package com.infy;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
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.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReconMatch {
public static void main(String[] args) throws IOException,
FileNotFoundException{
// TODO Auto-generated method stub
String excelFilePath ="C:/Users/akshay.kuchankar/Documents/demo.xlsx";
FileInputStream inputStream = new FileInputStream(new
File(excelFilePath));
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = workbook.getSheetAt(0);
Iterator<Row> iterator = firstSheet.iterator();
while (iterator.hasNext()) {
Row nextRow = iterator.next();
Iterator<Cell> cellIterator = nextRow.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
//what should be the basic approach or the syntax to perform the operaiton??
}
System.out.println();
}
workbook.close();
inputStream.close();
}
}
for(int i= 0; i<firstSheet.getRow(0).getCell(0).getNumericCellValue(); i++)
{
FGAmount = firstSheet.getRow(1).getCell(1).getNumericCellValue();
// System.out.println(FGAmount);
difference = firstSheet.getRow(1).getCell(3).getNumericCellValue();
value = FGAmount + difference;
}
alconAmount = firstSheet.getRow(1).getCell(2).getNumericCellValue();
// result = firstSheet.getRow(1).getCell(4).getStringCellValue();
}
}
try {
if(value== alconAmount){
firstSheet.getRow(1).getCell(4).setCellValue("Manual Matched");
System.out.println("matched");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
// System.out.println(result);
workbook.close();
inputStream.close();
Take a look at the API for your library:
https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html
You can interact with the cell in a number of ways, for example:
cell.setCellValue("My new value");
As for how to get values form cells and check against them you can do something a bit like this example where we do a bit of math and compare the values:
//Value of row 9, column 1 (column B)
String B9 = firstSheet.getRow(9).getCell(1).getStringCellValue();
//Value of row 9, column 2 (column C)
String D9 = firstSheet.getRow(9).getCell(2).getStringCellValue();
//Value of row 9, column 3 (column D)
String D9 = firstSheet.getRow(9).getCell(3).getStringCellValue();
//do math B9 - D9
double value = Double.parseDouble(B9) - Double.parseDouble(D9);
//check if C9 matches the result of B9 - D9
if(value == Double.parseDouble(C9))
{
//if it matches set cell E9 to display "Matched" and print out a message
firstSheet.getRow(9).getCell(4).setCellValue("matched");
System.out.println("matched");
}
I have not tested this code, but it should point you in the right direction.
Obviously there are things you should do like putting this in a loop rather than hard coding values, and you should check the column name to the make sure you have the right column before getting your values, and then you should check that the cell is a number and not text etc.
Edit in reply to your comment. Here is some code that will go over every row in a sheet except row 1 and will do exactly the same thing as in my example above and write "matched" in column E if column B - column D is equal to column C:
Iterator<Row> iterator = firstSheet.iterator();
while (iterator.hasNext()) {
Row nextRow = iterator.next();
//Check to make sure we skip the first row because that has all the column names:
if (nextRow.getRowNum() != 0){
//Get cell values of the current row
String columnB = nextRow.getCell(1).getStringCellValue();
String columnC = nextRow.getCell(2).getStringCellValue();
String columnD = nextRow.getCell(3).getStringCellValue();
try{
//do math column B - column D
double value = Double.parseDouble(columnB) - Double.parseDouble(columnD);
//check if column C matches the result of (column B - column D)
if(value == Double.parseDouble(columnC)){
//if it matches set text in column E to "matched"
nextRow.getCell(4).setCellValue("matched");
//print to console showing if a row matched
System.out.println("Row " + (nextRow.getRowNum()+1) + " matched");
}
}
catch(NumberFormatException nfe){
//do nothing here, this will happen if a cell contains text instead of numbers
}
catch(NullPointerException npe){
//Something else happened, you can probably ignore this as well but it will pay to throw a stack trace just in case something is wrong with this code
npe.printStackTrace();
}
}
}

Categories