Hopefully i will explain clear enough, I have a List of objects ( each object have 3 properties ) those objects are printed to xls file, I am trying to locate the cell where the value were assigned first and the last in order to get a references and setFormula to get Sum of all of the middle values
public String getCellReference(int rowPosition, int cellPosition) {
CellReference reference = new CellReference(rowPosition, cellPosition);
return reference.formatAsString();
}
public String getCellReference(int rowPosition, int cellPosition) {
CellReference reference = new CellReference(rowPosition, cellPosition);
return reference.formatAsString();
}
public String getSumFormula(int rowPosition, int cellPosition, int rowPosition2, int cellPosition2) {
String startCell = getCellReference(rowPosition, cellPosition);
String finishCell = getCellReference(rowPosition2, cellPosition2);
return "SUM(" + startCell + ":" + finishCell + ")";
}
To locate first value and last its not a problem but its seems to be a problem for me to locate a cell indexes
public Cell locateCell(List<Invoice> invoices){
BigDecimal firstGeneralTotal = invoices.get(0).generalTotal();
BigDecimal lastGeneralTotal = invoices.get(invoices.size()-1).generalTotal();
}
Basic access using POI would be like this:
XSSFWorkbook wb = new XSSFWorkbook( … );
XSSFSheet sheet = workbook1.getSheetAt(0);
XSSFRow row = sheet.getRow(0);
XSSFCell cell = row.getCell(0);
String value = cell.getStringCellValue();
Instead of using getStringCellValue you can also use one of those methods:
cell.getCellFormula()
cell.getNumericCellValue()
cell.getBooleanCellValue()
cell.getErrorCellValue()
Accordingly, you can do cell.setCellFormula(String formula) to set a cell.
If you want to add a formular to the end of the table containing the sum, you could use the cell references if you like. In this case, you'd need to find the last row in the excel sheet:
sheet.getPhysicalNumberOfRows()
Then you could add a new row to the end of your sheet:
sheet.createRow(sheet.getPhysicalNumberOfRows()+1);
and put your sum in according cell.
Btw, I am not sure if I would use CellReferences, since they can contain references to other sheets as well. If I work only with a single sheet, I'd try to use the index numbers and translate them accordingly to A1:A200 etc.
Does this help you? If I got your question wrong, let me know in the comments, I may update my answer if possible.
public String getCellReference(int rowPosition, int cellPosition) {
CellReference reference = new CellReference(rowPosition, cellPosition);
return reference.formatAsString();
}
public String getCoefficientFormula(int startRow, int firstCell, int endRow, int lastCell) {
String firstReference = getCellReference(startRow, firstCell);
String lastReference = getCellReference(endRow, lastCell);
return firstReference + "/" + lastReference;
}
public String getSumFormula(int startRow, int endRow, int start, int finish) {
String startCell = getCellReference(startRow,start);
String finishCell = getCellReference(endRow,finish);
return "SUM(" + startCell + ":" + finishCell + ")";
}
Related
UPDATE: POSSIBLE SOLUTION POSTED BELOW BY MYSELF
I need my program to read a cell. If it contains a specific string, lets say the name "Jacob", then it needs to execute a certain static function defined later in the code.
My IF statement will be nested in a while loop.
int currentRow = 1;
Cell cell;
Cell ncell;
while (!(cell = sheet.getCell(URL_COLUMN, currentRow)).getType().equals(CellType.EMPTY)) {
String url = cell.getContents();
System.out.println("Checking URL: " + url);
ncell = sheet.getCell(NAME_COLUMN, currentRow);
ncell.getContents();
ncell.toString();
if (ncell.contains("Jacob")) {
String FAV = JacobFavFood(url); // A static function will be defined later for this
System.out.println("Jacob's favorite food is " + name);
Label cellWithFAV = new Label(FAV_COLUMN, currentRow, FAV);
sheet.addCell(cellWithFAV);
}
currentRow++;
}
workbook.write();
workbook.close();
UPDATE: POSSIBLE SOLUTION POSTED BELOW BY MYSELF
int currentRow = 1;
Cell cell;
Cell ncell;
while (!(cell = sheet.getCell(URL_COLUMN, currentRow)).getType().equals(CellType.EMPTY)) {
String url = cell.getContents();
String NAME = ncell.getcontents();
System.out.println("Checking URL: " + url);
ncell = sheet.getCell(NAME_COLUMN, currentRow);
if (NAME.contains("Jacob")) {
String FAV = JacobFavFood(url); // A static function will be defined later for this
System.out.println("Jacob's favorite food is " + name);
Label cellWithFAV = new Label(FAV_COLUMN, currentRow, FAV);
sheet.addCell(cellWithFAV);
}
currentRow++;
}
workbook.write();
workbook.close();
I forgot I can define the string as was done with the url. This does work, and it is able to call on a static function. I am still wondering why .toString() didn't work, though.
I'm writing a program where I want to iterate certain attributes inside a document with an ID that looks like this:
"id": "competitor:2672"
I want to iterate based on data that I read from an excel file. The only problem is that, in said excel file, the ID is only given as
2672
in the column "Competitor ID".
I cannot parse the given String to integer. What is the best and cleanest way to compare the two IDs
Using apache POI I want to do something like this
String COLUMN_ID = "G" // Column letter in which the IDs are stored
Document home = competitors.get(0);
Document away = competitors.get(1);
String homeIDString = home.get("id").toString();
int homeID = //how to get this from the upper string?
String awayIDString = away.get("id").toString();
int awayID = //how to get this from the upper string?
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
XSSFSheet sheet = workbook.getSheetAt(0);
for (int row=0; <something>; row++) {
XSSFCell cell = sheet.getRow(row).getCell(CellReference.convertColStringToIndex(COLUMN_ID));
if (cell.getCellTypeEnum().equals(NUMERIC)) int cellValue = (int) cell.getNumericValue();
if (cellValue == homeID) { do something }
else if (cellValue == awayID) { do something }
}
You are currently getting a NumberFormatException because you are trying to convert your String into an int before comparing it with another int.
What #azurefrog is saying is that you can try instead to convert your int into a String (the other way around) and it will be fine.
strVariable.endsWith(String.valueOf(intVariable))
However this has the problem that "id": "competitor:2672" and 72 would return true too.
A better way is to just remove competitor: using substring before converting 2672 to an int
String myInput = "competitor:2672"; // "competitor:2672"
myInput = myInput.substring(11); // "2672"
int myValue = Integer.parseInt(myInput); // 2672
I've the below Java (Selenium) method that will insert data into Excel sheet:
private static void getPaceNumber(WebDriver chromeDriver, String dBName, XSSFSheet paceSheet, String pubName, int i,
XSSFCell cell, XSSFWorkbook workbook) throws Exception {
CellStyle style = workbook.createCellStyle();
cell = paceSheet.getRow(i).createCell(1);
if (dBName == "" || dBName.equals("null")) {
cell.setCellValue("N/A");
} else {
chromeDriver.findElement(By.xpath("html/body/form[2]/b/b/table/tbody/tr[2]/td[2]/textarea"))
.sendKeys("\"" + dBName + "\"");
chromeDriver.findElement(By.xpath("html/body/form[2]/b/b/table/tbody/tr[4]/td[2]/input[1]")).click();
List<WebElement> pace = chromeDriver
.findElements(By.xpath("html/body/form[2]/table[1]/tbody/tr[2]/td[2]/input[1]"));
int paceSize = pace.size();
if (paceSize >= 1) {
int dbPaceNumber = Integer.parseInt(
chromeDriver.findElement(By.xpath("html/body/form[2]/table[1]/tbody/tr[2]/td[2]/input[1]"))
.getAttribute("value"));
chromeDriver.findElement(By.xpath(".//*[#id='searchPublication']")).click();
chromeDriver.findElement(By.xpath("html/body/form[2]/b/b/table/tbody/tr[2]/td[2]/textarea"))
.sendKeys("\"" + pubName + "\"");
chromeDriver.findElement(By.xpath("html/body/form[2]/b/b/table/tbody/tr[4]/td[2]/input[1]")).click();
int pubPaceNumber = Integer.parseInt(
chromeDriver.findElement(By.xpath("html/body/form[2]/table[1]/tbody/tr[2]/td[2]/input[1]"))
.getAttribute("value"));
if (dbPaceNumber == pubPaceNumber) {
cell.setCellValue(dbPaceNumber);
} else {
cell.setCellValue(dbPaceNumber + "\n" + pubPaceNumber);
style.setWrapText(true);
cell.setCellStyle(style);
}
} else {
List<WebElement> table = chromeDriver
.findElements(By.xpath("html/body/form[2]/table[1]/tbody/tr[4]/td/b"));
int tabSize = table.size();
if (tabSize == 1) {
chromeDriver.findElement(By.xpath(".//*[#id='searchPublication']")).click();
chromeDriver.findElement(By.xpath("html/body/form[2]/b/b/table/tbody/tr[2]/td[2]/textarea"))
.sendKeys("\"" + pubName + "\"");
chromeDriver.findElement(By.xpath("html/body/form[2]/b/b/table/tbody/tr[4]/td[2]/input[1]"))
.click();
List<WebElement> paceWithFPN = chromeDriver
.findElements(By.xpath("html/body/form[2]/table[1]/tbody/tr[2]/td[2]/input[1]"));
int paceWithFPNSize = paceWithFPN.size();
if (paceWithFPNSize >= 1) {
int paceSubNumber = Integer.parseInt(chromeDriver
.findElement(By.xpath("html/body/form[2]/table[1]/tbody/tr[2]/td[2]/input[1]"))
.getAttribute("value"));
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
cell.setCellValue(paceSubNumber);
} else {
cell.setCellValue("N/A");
}
} else {
cell.setCellValue("N/A");
}
}
}
}
I want to check the value with two different criteria, if both of them are same, insert the value in Excel cell, else insert both the values in a single cell. Basically the values retrieved are of integer type. I'm able to insert the values correctly, but if there are two values, they are getting inserted as a single line (one continuation of the other). The single value is automatically aligned right in Excel cell (in general number format).
Where there are two values, I need to double click on the cell and then they are shown in two line format, and also they are displayed as strings (left aligned).
I'm aware that when I use a +"XXX"+ the resultant is a string, but how can I make this into an integer?
Like single value, this has to be right aligned and also is there a way I can get a line break automatically inside the cell?
**Current output:** **Expected Output:**
I think you have to increase the rowheight of the row that contains the cell.
In the beginning:
int defaultHeight = paceSheet.getRow(0).getHeight();
and later, when you create such a cell:
paceSheet.getRow(i).setHeight(defaultHeight*2);
Those lines:
style.setWrapText(true);
style.setAlignment(CellStyle.ALIGN_RIGHT);
are something you just have to do once (e.g.right after creation) since style is the same for all affected cells.
how can I get a CellEntry given a specific cell address e.g in A1 notation. For example,
String address = "A1";
CellEntry cellEntry = getCellEntry(address);
public CellEntry getCellEntry(String address){
//- What can I do inside here
}
Previously, I fetch everything using CellFeed and iterating using cellFeed.getEntries to get each CellEntry and filter out based on cell address. But I think it will have a performance issues since my spreadsheet is large. Any idea ? I'm using Java.
I think I got two approaches here :
Method 1
Using CellQuery
public CellEntry getCellEntry(URL cellFeedUrl, Integer colNum, Integer rowNum){
CellQuery cellQuery = new CellQuery(cellFeedUrl);
cellQuery.setMaximumCol(colNum);
cellQuery.setMinimumCol(colNum);
cellQuery.setMaximumRow(rowNum);
cellQuery.setMinimumRow(rowNum);
CellFeed cellFeed = service.getFeed(cellQuery, CellFeed.class)
return cellFeed.getEntries().get(0);
}
Note : The setMaximumCol and setMinimumCol must be the same to get the specified column. Similar with the setMaximumRow and setMinimumRow.
Method 2
Using CellFeedURL
public CellEntry getCellEntry(WorksheetEntry worksheet, Integer colNum, Integer rowNum){
if (colNum == null || rowNum == null){
//- do something
}
else {
String row = "?min-row=" + rowNum + "&max-row=" + rowNum;
String col = "&min-col=" + colNum + "&max-col=" + colNum;
URL cellFeedUrl = new URI(worksheet.getCellFeedUrl().toString()
+ row + col).toURL();
CellFeed cellFeed = service.getFeed(cellFeedUrl, CellFeed.class);
return cellFeed.getEntries().get(0);
}
}
Note : Based on Google Spreadsheet API : Changing content of a cell
Personally I think the second method is better.
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
}
}