How do i get visible row count using apache POI? - java

I have used autofilter to filter that data in excel and i want number of visible rows excluding hidden rows. I have tried searching for this, but no particular method found. I even tried using excel formula and getting row count, but this only gives cached value.
outputSheet.setAutoFilter(CellRangeAddress.valueOf("A1:C491"));
CTAutoFilter sheetFilter=outputSheet.getCTWorksheet().getAutoFilter();
CTFilterColumn myFilterColumn=sheetFilter.insertNewFilterColumn(0);
myFilterColumn.setColId(1);
CTFilterColumn myFilterColumn2=sheetFilter.insertNewFilterColumn(1);
myFilterColumn2.setColId(2);
CTFilters firstColumnFilter=myFilterColumn.addNewFilters();
CTFilter myFilter1=firstColumnFilter.addNewFilter();
CTFilters secondColumnFilter=myFilterColumn2.addNewFilters();
CTFilter myFilter2=secondColumnFilter.addNewFilter();
myFilter1.setVal("New Account");
myFilter2.setVal("Hedge Fund");
List<String> list1 = new ArrayList<String>();
list1.add("Ad Cloud");
List<String> list2 = new ArrayList<String>();
list2.add("US");
XSSFRow r1;
for(Row r : my_sheet) {
for (Cell c : r) {
c.setCellType(Cell.CELL_TYPE_STRING);
if ( (c.getColumnIndex()==1 && !list2.contains(c.getStringCellValue())) || (c.getColumnIndex()==2 && !list1.contains(c.getStringCellValue())) ){
r1=(XSSFRow) c.getRow();
if (r1.getRowNum()!=0) { /* Ignore top row */
/* Hide Row that does not meet Filter Criteria */
r1.getCTRow().setHidden(true);
}
}
}
}
outputworkbook.write(fos);
fos.close();
//format(outputFile);

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

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

Checking if an arralist contains an excel's cell value

I have an ArrayList<Cell> RM = new ArrayList<Cell>() ;
where RM=[aaa,bbb] and where aaa and bbb are some cells from an excel file
I use this code to get the cells values into the arraylist.
Row row = sheet.getRow(1);
Iterator<Cell> cells1 = row.cellIterator();
while( cells1.hasNext() ) {
Cell cell = cells1.next();
if (Cell.CELL_TYPE_STRING==cell.getCellType()) {
RM.add(cell);
}
}
Then I am trying to see if the arraylist contains aaa or bbb, but it doesnt recognise the command. System.out.println(RM) shows the proper results [aaa,bbb] but if add an if(contains) condition it wont:
if (RM.contains("aaa")) {
System.out.println("ok"); }
Changed it to:
ArrayList<String> RM = new ArrayList<String>() ;
RM.add(cell.getStringCellValue());
and contains() works properly

Categories