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
Related
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.
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
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
}
}
...
I have a xlsx file which has multiple sheet i am using apache poi for writing excel, in sheet2 i have 2 columns
each column i want to populate by running a for loop , but i see that only last for loop get written previous one get blank in final written output file, i want to write both column by these for loop please help .
for(int i=0;i<fileNamesArray.length;i++)
{
XSSFRow row = worksheet1.createRow(i+1);
cell = row.createCell(0);
cell.setCellValue(fileNamesArray[i].toString());
}//this dont get written
for(int i=0;i<fileDatesArray.length;i++)
{
XSSFRow row = worksheet1.createRow(i+1);
cell = row.createCell(1);
cell.setCellValue(fileDatesArray[i].toString());
}//only this get written
this is complete code
public class DashBoard {
public void writeDashBoard() throws IOException, SQLException
{
CODToolUtil codToolUtil = new CODToolUtil();
// Read property file to initialize constants
String templateDashBoardFile = codToolUtil.getPropValues("templateDashBoardFile");
String outputDir = codToolUtil.getPropValues("outputDir");
String dirSeprator = codToolUtil.getPropValues("dirSeprator");
String fdate = CODToolUtil.getDate();
CODDAO coddao=new CODDAO();
LinkedHashSet<String> hs= new LinkedHashSet<String>();
LinkedHashSet<String> hs1= new LinkedHashSet<String>();
FileInputStream fsIP= new FileInputStream(new File(templateDashBoardFile)); //Template file
XSSFWorkbook wb = new XSSFWorkbook(fsIP);
XSSFSheet worksheet = wb.getSheetAt(0);
Cell cell = null;
cell = worksheet.getRow(1).getCell(0);
cell.setCellValue(CODToolUtil.getDate());//Date
cell = worksheet.getRow(1).getCell(1);
int allfiles=coddao.getAllfiles();
cell.setCellValue(allfiles);//All Files
cell = worksheet.getRow(1).getCell(2);
int callfilesY=coddao.getAllProcessedfilesCallY();
cell.setCellValue(callfilesY);//All Y Files
cell = worksheet.getRow(1).getCell(3);
int callfilesN=coddao.getAllProcessedfilesCallN();
cell.setCellValue(callfilesN);//All N Files
cell = worksheet.getRow(1).getCell(4);
int allLTE=coddao.getAllProcessedfilesLTE();
cell.setCellValue(allLTE);//All LTE Files
cell = worksheet.getRow(1).getCell(5);
int allWCDMA=coddao.getAllProcessedfilesWCDMA();
cell.setCellValue(allWCDMA);//All WCDMA Files
//Sheet 0 OverView Complete
//Sheet 1 Successfull CT
XSSFSheet worksheet1 = wb.getSheetAt(1);
hs=coddao.getAllProcessedfilesNameY();
hs1=coddao.getAllProcessedfilesDateY();
Object[] fileNamesArray = hs.toArray();
Object[] fileDatesArray = hs1.toArray();
for(int i=0;i<fileNamesArray.length;i++)
{
XSSFRow row = worksheet1.createRow(i+1);
cell = row.createCell(0);
cell.setCellValue(fileNamesArray[i].toString());
}//this dont get written
for(int i=0;i<fileDatesArray.length;i++)
{
XSSFRow row = worksheet1.createRow(i+1);
cell = row.createCell(1);
cell.setCellValue(fileDatesArray[i].toString());
}//only this get written
fsIP.close();
File saveDirectory = new File(outputDir);// Create OutPutDirectory
saveDirectory.mkdir();
String savefilePath = saveDirectory.getAbsolutePath();
FileOutputStream output_file = newFileOutputStream(newFile(savefilePath+dirSeprator+fdate+"-"+templateDashBoardFile)); // save in output
wb.write(output_file); // write changes save it.
output_file.close(); // close the stream
}
public static void main(String[] args) throws IOException, SQLException {
new DashBoard().writeDashBoard();
}
}
You are creating the same row twice - probably overriding the "first" row created in the first loop, with the "second" row created in the second loop.
If fileNamesArray and fileDatesArray are the same size, you can combine the loops as:
for(int i=0;i<fileNamesArray.length;i++)
{
XSSFRow row = worksheet1.createRow(i+1);
cell1 = row.createCell(0);
cell1.setCellValue(fileNamesArray[i].toString());
cell2 = row.createCell(1);
cell2.setCellValue(fileDatesArray[i].toString());
}
check which array is bigger and loop through it first, then loop through the second array, but instead of using worksheet1.createRow(i+1) - use worksheet1.getRow(i+1), reusing the row element you created in the first loop.
Note: in theory, even if the arrays are of different sizes you can still use one loop, just make sure you apply relevant checks to avoid ArrayIndexOutOfBoundsException.
Try
for(int i=0;i<fileNamesArray.length;i++)
{
XSSFRow row = worksheet1.createRow(i+1);
cell = row.createCell(0);
cell.setCellValue(fileNamesArray[i].toString());
cell = row.createCell(1);
cell.setCellValue(fileDatesArray[i].toString());
}
Instead of of using those 2 loops. I would imagine you are overwriting the your row when you call worksheet1.createRow in the second loop.
gradeList is an ArrayList of strings with the value "80", "81" ... "85"
for(int y = 0; y < gradeList.size(); y++){
HSSFRow row1 = worksheet.createRow((short) 1);//1
HSSFCell cell1 =row1.createCell((short) y+1);//2
cell1.setCellValue("" + gradeList.get(y));//3
HSSFCellStyle cellStylei = workbook.createCellStyle();//4
cellStylei.setFillForegroundColor(HSSFColor.GREEN.index);
cell1.setCellStyle(cellStylei);//6
}
Output of Code: _, _, _, _, _, 85.
intended Output: 80, 81, 82, 83, 84, 85.
After changing the code to
HSSFRow row1 = worksheet.createRow((short) 1);//1
HSSFCell cell1;
for(int y = 0; y < gradeList.size(); y++){
cell1 = row1.createCell((short) y+1);//2
cell1.setCellValue("" + gradeList.get(y));//3
}
HSSFCellStyle cellStylei = workbook.createCellStyle();//4
cellStylei.setFillForegroundColor(HSSFColor.GREEN.index);//5
the code prints 80, 81, 82, 83, 84, and 85 as intended but using the previous six line code it only prints 85. Can someone please explain to me why is first one wrong or not working, and if possible also can you please also explain what lines 4,5, and 6 do.
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
}
}