Do Vlookup on Excel by Java - java

Check my Excel Tables SNAP above pasted
By below CODE of java I have read the data and fetch in a arraylist;
workbook = WorkbookFactory.create(new File(SAMPLE_XLSX_FILE_PATH));
ArrayList<String> comps = new ArrayList<String>();
for (Sheet sheet : workbook) {
System.out.println("=> " + sheet.getSheetName());
}
Sheet sheet = workbook.getSheetAt(0);
DataFormatter dataFormatter = new DataFormatter();
for (Row row : sheet) {
for (Cell cell : row) {
String tempValue = dataFormatter.formatCellValue(cell);
// System.out.println(tempValue);
comps.add(tempValue);
}
}
for (int i = 2; i < comps.size(); i++) {
System.out.println(comps.get(i));
}
Output is like below after reading and storing into arraylist
A
B
1
AA
2
BB
3
CC
Now, In first table in my snap, I want to compare Column A to Second Table Column A and when there is a match then in D column of first table I need to put the data of Column B from Second Table. Simply this vlookup between 2 excels. I want to do it by java.
As per my understanding I need to read the first table as well like I did for second table and store it in a Arraylist then start comparing and write it in Column D of first table and save it.
Anyone can help me with next step? Appreciate the code on this context.

Related

Require help on Java Logic for Reading Excel file and populating to HashMap

I am reading an excel data file from Java using apache POI API and populating an HashMap collection with excel Headers as Key and specified Row Data as Value of the Map. All Headers are always present but data corresponding to some headers may or may not be present.
Below is my code logic:
First I populate all the headers to an ArrayList.
Then I Iterate through the cells of the specified excel data row and I add the header value from the ArrayList, populated previously, and Data cell value from the row as key-value to an HashMap.
Below is my code:
ArrayList<String> headerList = new ArrayList<String>();
Map<String, String> dataMap = new LinkedHashMap<String, String>();
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
// Create object of XSSFWorkbook to get hold of excel file
FileInputStream fis = new FileInputStream(System.getProperty("user.dir") + "\\Resources\\TestData.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(fis);
try
{
int noOfSheets = workbook.getNumberOfSheets();
for(int i=0; i<noOfSheets; i++)
{
if(workbook.getSheetName(i).equalsIgnoreCase(workSheet))
{
//Get access to sheet
XSSFSheet sheet = workbook.getSheetAt(i);
//Get access to all rows of sheet
Iterator<Row> rows = sheet.iterator();
Row headerRow = rows.next();
Iterator<Cell> headerCells = headerRow.cellIterator();
while(headerCells.hasNext())
{
headerList.add(headerCells.next().getStringCellValue());
}
// Get access to specific row
while(rows.hasNext())
{
Row dataRow = rows.next();
if(dataRow.getCell(0).getStringCellValue().equalsIgnoreCase(testCase))
{
int j = 0;
//Get access to collection of cells of the identified rows
Iterator<Cell> dataCells = dataRow.cellIterator();
//loop through all the cells of the row and add cell data to arraylist.
while(dataCells.hasNext())
{
Cell dataCell = dataCells.next();
if(dataCell.getCellType()==CellType.STRING)
{
//arrList.add(dataCell.getStringCellValue());
dataMap.put(headerList.get(j), dataCell.getStringCellValue());
}
else if(dataCell.getCellType()==CellType.NUMERIC)
{
if(DateUtil.isCellDateFormatted(dataCell))
{
//arrList.add(df.format(dataCell.getDateCellValue()));
dataMap.put(headerList.get(j), df.format(dataCell.getDateCellValue()));
}
else
{
//arrList.add(NumberToTextConverter.toText(dataCell.getNumericCellValue()));
dataMap.put(headerList.get(j), NumberToTextConverter.toText(dataCell.getNumericCellValue()));
}
}
else if(dataCell.getCellType()==CellType.BOOLEAN)
{
//arrList.add(Boolean.toString(dataCell.getBooleanCellValue()));
dataMap.put(headerList.get(j), Boolean.toString(dataCell.getBooleanCellValue()));
}
else
dataMap.put(headerList.get(j), null);
j++;
}
}
}
}
}
If there is no data in any cell then I do not want the corresponding header to be added in the Map. But when I iterate through the Data cells(dataCells.hasNext()), then the iterator does not return me null for that blank cell, instead it totally skips the Blank cell. So all headers are added but those cells where is no data are not added hence there is mismatch of Header-Data key-values.
Example: If data cell of Column 5 is blank then, "Value" of the column 5 header is mapped with the value of Data Column 6 as "Key-Value" in the HashMap. What I want is column 5 header should be skipped being added to the Map when column 5 data is blank. How do I resolve this logical mismatch issue?
Excel file screenshot
Debug scenario screenshot

Reading multiple columns for a row from excel, in java?

I want to read excel spreadsheet(.xlxs) having testcases preconditions column/expected result column and so on. How do i read multiple columns for specific row. Everyrow(first Column)is a testcase name.
I am able to read one row and two columns, but unsure how to read multiple columns for same row . I also don't want to hardcode column#,row# while reading it. Any suggestions?
Map<String,String> arrayExcelData = new Hashtable<String,String>();
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
Cell methodNameCol = row.getCell(0);
Cell expectedResults = row.getCell(1);
if (expectedResults != null && methodNameCol !=null)
{
arrayExcelData.put(methodNameCol.getStringCellValue(),expectedResults.getStringCellValue());
}
workbook.close();
}
The Row class provides methods that return the index of the first and last cell (aka column) in that Row instance. Use these indexes to iterate over the columns:
Row row = rowIterator.next();
short firstCellNumber = row.getFirstCellNum();
short lastCellNumber = row.getLastCellNum();
for(short cellNumber = firstCellNumber; cellNumber < lastCellNumber; cellNumber++) {
Cell dataCell = row.getCell(cellNumber);
//Do something with the dataCell here
}

why apache poi reading less number of cell in a row of excel

I am trying to fetch the cell using named range.But After trying the below code,not able to get consistent cell in a row of the sheet that's getting null exception while using r.getCell().
String cname = "TestName";
Workbook wb = getMyWorkbook(); // retrieve workbook
// retrieve the named range
int namedCellIdx = wb.getNameIndex(cellName);
Name aNamedCell = wb.getNameAt(namedCellIdx);
// retrieve the cell at the named range and test its contents
AreaReference aref = new AreaReference(aNamedCell.getRefersToFormula());
CellReference[] crefs = aref.getAllReferencedCells();
for (int i = 0; i < crefs.length; i++) {
Sheet s = wb.getSheet(crefs[i].getSheetName());
Row r = sheet.getRow(crefs[i].getRow());
Cell c = r.getCell(crefs[i].getCol());
// extract the cell contents based on cell type etc.
}
For the sake of memory consuming, totally empty rows are not stored on the sheet. Also totally empty cells are not stored in rows of the sheet.
Sheet.getRow returns null if the row is not defined on the sheet. Also Row.getCell returns null if the cell is undefined in that row.
So we always need check:
...
Row r = sheet.getRow(crefs[i].getRow());
if (r == null) {
//row is empty
} else {
Cell c = r.getCell(crefs[i].getCol());
if (c == null) {
//cell is empty
} else {
//do something with c
}
}
...

How to display an Object in a column with apache-poi

I have a big DTO with exactly 234 fields, and I have to display values of each fields of this DTO in a column of an Excel file created with apache-poi.
This is my code :
// Blank workbook
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Export values");
// Get the Entity
Simfoot simEntity = simService.findById(simId).get();
Row row = sheet.createRow(0);
row.createCell(1).setCellValue("Consult our values");
// and after this I want to convert my Simfoot object to a column in the third column ( so creteCell(2) ..... ).
I want to have in my first column : nothing , in my second only the String display ( "Consult our values" ) and in my third column I need to have my 234 fields. With an field ( the value of the field ) in one cell. So, 234 rows displaying one value in the third column.
I hope that it is clear.
Thanks a lot for your help.
Using some reflection:
// Blank workbook
XSSFWorkbook workbook = new XSSFWorkbook();
final Sheet sheet = workbook.createSheet("Export values");
// Get the Entity
final Simfoot simEntity = simService.findById(simId).get();
Row row = sheet.createRow(0);
row.createCell(1).setCellValue("Consult our values");
// and after this I want to convert my Simfoot object to a column in the third column ( so creteCell(2) ..... ).
Arrays.stream(simEntity.getClass().getDeclaredMethods())
.filter(m -> m.getName().startsWith("get") && m.getParameterTypes().length == 0 && !void.class.equals(m.getReturnType()))
.forEach(m -> {
try {
Object value = m.invoke(simEntity, null);
Row r = sheet.createRow(sheet.getLastRowNum()+1);
r.createCell(2).setCellValue(value == null ? "" : value.toString());
}
catch (Exception ex) {
// Manage Exception....
}
});
I'll add a method on Simfoot to return all the values:
public List<String> getAllValues() {
return Arrays.asList(getAtt1(), getAtt2(), .. , getAtt234());
}
Then create a row per attribute, and then you can merge the rows of the first 2 columns. Example here with 6 attributes:
int n = 6; // would be 234 for you
XSSFCellStyle styleAlignTop = workbook.createCellStyle();
styleAlignTop.setVerticalAlignment(VerticalAlignment.TOP);
Row row;
for(int i=0; i<n; i++) {
row = sheet.createRow(i);
if(i==0) {
Cell cell = row.createCell(1);
cell.setCellStyle(styleAlignTop);
cell.setCellValue("Consult our values");
}
row.createCell(2).setCellValue(simEntity.getAllValues().get(i));
}
sheet.addMergedRegion(new CellRangeAddress(0, n-1, 0, 0));
sheet.addMergedRegion(new CellRangeAddress(0, n-1, 1, 1));
It shows like this:
Another way to list your attributes would be to use Reflection but I find it very clunky:
Simfoot simEntity = new Simfoot("pap", "pep", "pip", "pop", "pup", "pyp");
for(PropertyDescriptor propertyDescriptor :
Introspector.getBeanInfo(Simfoot.class).getPropertyDescriptors()) {
System.out.println(propertyDescriptor.getReadMethod().invoke(simEntity));
}
Outputs:
pap
pep
pip
pop
pup
pyp
class Simfoot
so you have to filter out getClass and any other unwanted methods and getters

Retrieve values from excel using poi

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

Categories