Currently exploring apache poi and what seems to be the error?
I didn't get any value from my filesheets.
Tried to prompt out the value from line 51 and I didn't get any.
This is what I'm doing: I identify test cases column by scanning the entire 1st row and once column is identified then scan entire testcase column to identify purchase testcase row after you grabbing purchase testcase row = I want to pull all the data of that row and feed into test
For the excel file
TIA
Code:
public class App {
public ArrayList<String> getData(String testcaseName) throws IOException
{
ArrayList<String> a=new ArrayList<String>();
FileInputStream fis=new FileInputStream("/Users/jaxethhugomahiya/Downloads/testData.xlsx");
XSSFWorkbook workbook=new XSSFWorkbook(fis);
int sheets=workbook.getNumberOfSheets();
for(int i=0;i<sheets;i++)
{
if(workbook.getSheetName(i).equalsIgnoreCase("testdata"))
{
XSSFSheet sheet=workbook.getSheetAt(i);
Iterator<Row> rows= sheet.iterator();// sheet is collection of rows
Row firstrow= rows.next();
Iterator<Cell> ce=firstrow.cellIterator();//row is collection of cells
int k=0;
int column = 0;
while(ce.hasNext())
{
Cell value=ce.next();
if(value.getStringCellValue().equalsIgnoreCase("Testcases"))
{
column=k;
}
k++;
}
System.out.println(column);
while(rows.hasNext())
{
Row r=rows.next();
if(r.getCell(column).getStringCellValue().equalsIgnoreCase(testcaseName))
{
Iterator<Cell> cv=r.cellIterator();
while(cv.hasNext())
{
Cell c= cv.next();
if(c.getCellType()==CellType.STRING)
{
a.add(c.getStringCellValue());
}
else{
a.add(NumberToTextConverter.toText(c.getNumericCellValue()));
}
}
}
}
}
}
return a;
}
testSample.java
public static void main(String args) throws IOException{
App a = new App();
ArrayList<String> data = a.getData("Add Profile");
System.out.println(data.get(0));
System.out.println(data.get(1));
System.out.println(data.get(2));
System.out.println(data.get(3));
}
The output:
Same under app, successfully read the excel file.
Thank you
public static void main(String[] args) throws IOException {
App a = new App();
ArrayList data = a.getData("Delete Profile");
System.out.print(" "+data.get(0));
System.out.print(" "+data.get(1));
System.out.print(" "+data.get(2));
System.out.print(" "+data.get(3));
}
Related
I am reading the data from Excel file, let us say I have 5 rows and 15 columns in Java testNG.
Review the below code
Class ReadExcel {
public String[][] getCellData(String path, String sheetName) throws InvalidFormatException, IOException {
FileInputStream stream = new FileInputStream(path);
XSSFWorkbook workbook = new XSSFWorkbook(stream);
Sheet s = workbook.getSheet(sheetName);
int rowcount = s.getLastRowNum();
int cellcount = s.getRow(0).getLastCellNum();
String data[][] = new String[rowcount][cellcount];
FormulaEvaluator evaluator= workbook.getCreationHelper().createFormulaEvaluator();
DataFormatter df = new DataFormatter();
for (int i = 1; i <= rowcount; i++) {
Row r = s.getRow(i);
for (int j = 0; j < cellcount; j++) {
Cell c = r.getCell(j);
try {
if(c!=null){
if (c.getCellType() == c.CELL_TYPE_STRING) {
data[i - 1][j] = c.getStringCellValue();
}else if (c.getCellType() == c.CELL_TYPE_FORMULA) {
data[i - 1][j] = df.formatCellValue(c, evaluator);
}
else if (c.getCellType() == c.CELL_TYPE_BOOLEAN) {
data[i - 1][j] = df.formatCellValue(c, evaluator);
}
else{
data[i - 1][j] = String.valueOf(c.getNumericCellValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return data;
}
}
Another class for processing the data
public class Sample
{
ReadExcel read = new ReadExcel();
#DataProvider (parallel= true)
public String[][] getFilterValues() throws InvalidFormatException, IOException, InterruptedException{
return read.getCellData("fileLoc","fileName");
}
#Test(dataProvider = "getFilterValues")
public void verifyReports(String row, String name, String age, String lastname and so on...) throws Exception
{
System.out.println(FileName);
}
So, here I need to reduce the argument count in verifyReports method and should able to retrieve the entire records in the same method.
Note: Argument count may be changed in future.
So I tried with Map concept but I could not find out.
The main goal is to reduce the no. of arguments in verifyReports method. How to achieve this.
I achieved by using the below code. But it would be in 2D array in order to use it in testNG DataProviders
Below is the code, I tried using list of map.
public ArrayList<String> readHeader(String path, String sheetName) throws IOException
{
FileInputStream stream = new FileInputStream(path);
XSSFWorkbook workbook = new XSSFWorkbook(stream);
Sheet s = workbook.getSheet(sheetName);
int rowcount = s.getLastRowNum();
int cellcount = s.getRow(0).getLastCellNum();
ArrayList<String> al = new ArrayList<String>();
Row r = s.getRow(0);
for(int i=0;i<cellcount;i++)
{
Cell c = r.getCell(i);
al.add(c.getStringCellValue());
}
return al;
}
public ArrayList<HashMap<String,String>> getCellData(String path, String sheetName) throws InvalidFormatException, IOException {
//ExcelConfig ec = new ExcelConfig();
FileInputStream stream = new FileInputStream(path);
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
XSSFWorkbook workbook = new XSSFWorkbook(stream);
Sheet s = workbook.getSheet(sheetName);
int rowcount = s.getLastRowNum();
int cellcount = s.getRow(0).getLastCellNum();
FormulaEvaluator evaluator= workbook.getCreationHelper().createFormulaEvaluator();
DataFormatter df = new DataFormatter();
ArrayList<String> head = ec.readHeader(path, sheetName);
for (int i = 1; i <= rowcount; i++) {
HashMap<String,String> map = new HashMap<String,String>();
Row r = s.getRow(i);
for (int j = 0; j < cellcount; j++) {
Cell c = r.getCell(j);
try {
if(c!=null){
if (c.getCellType() == c.CELL_TYPE_STRING) {
map.put(head.get(j), c.getStringCellValue());
}else if (c.getCellType() == c.CELL_TYPE_FORMULA) {
map.put(head.get(j), df.formatCellValue(c, evaluator));
}
else if (c.getCellType() == c.CELL_TYPE_BOOLEAN) {
map.put(head.get(j), df.formatCellValue(c, evaluator));
}
else{
map.put(head.get(j), String.valueOf(c.getNumericCellValue()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
list.add(map);
}
return list;
}
public void multiRec() throws InvalidFormatException, IOException
{
ArrayList<HashMap<String, String>> map = read.getCellData(fileLoc,"ComparisonStatus");
for(HashMap<String, String> ls : map)
{
System.out.println(ls.get("Row"));
System.out.println(ls.get("FileName"));
}
}
Here, Row and FileName are Excel file header. So now I reduced the no. of arguments. But how to convert it to 2D array will be the task now.
The best way would be to create a class containing all the arguments as fields of the class. Let the class name be CellData
class CellData {
private String row;
private String name;
// and all other relevant fields..
}
In the getCellData method, create and initialize an object of CellData with the relevant values of each row and instead of returning String[][] return CellData[]. Then make the below changes:
#DataProvider (parallel= true)
public Object[][] getFilterValues() throws InvalidFormatException, IOException, InterruptedException{
CellData[] cellData = read.getCellData("fileLoc","fileName");
Object[][] data = new Object[cellData.length][];
for(int i = 0; i < cellData.length; i++) {
data[i][0] = cellData[i];
}
return data;
}
#Test(dataProvider = "getFilterValues")
public void verifyReports(CellData data) throws Exception
{
// test code.
}
Since you are saying that new arguments could be introduced in the future, using a class would be very much beneficial as it could help the code be maintainable and readable. Any future updates would also require much less code changes as there is no need of updating the DataProvider method or the test method. The only change would be a new field in the CellData class and setting the values for the new fields in getCellData method.
I am using JAVA 8 and Apache POI 3.17. I have an Excel file and i want to keep only few lines and delete the others. But my Excel have 40K rows and deleting them one by one is quite long (nearly 30 min :/ )
So i try to change my way of doing it. Now i think it's better to only take rows that i need in the excel source and copy to another new one. But what i have tried so far is not efficient.
I have all my rows and want to keep in a List. But this not working and create me a blank excel :
public void createExcelFileFromLog (Path logRejetFilePath, Path fichierInterdits) throws IOException {
Map<Integer, Integer> mapLigneColonne = getRowAndColumnInError(logRejetFilePath);
Workbook sourceWorkbook = WorkbookFactory.create(new File(fichierInterdits.toAbsolutePath().toString()));
Sheet sourceSheet = sourceWorkbook.getSheetAt(0);
List<Row> listLignes = new ArrayList<Row>();
// get Rows from source Excel
for (Map.Entry<Integer, Integer> entry : mapLigneColonne.entrySet()) {
listLignes.add(sourceSheet.getRow(entry.getKey()-1));
}
// The new Excel
Workbook workbookToWrite = new XSSFWorkbook();
Sheet sheetToWrite = workbookToWrite.createSheet("Interdits en erreur");
// Copy Rows
Integer i = 0;
for (Row row : listLignes) {
copyRow(sheetToWrite, row, i);
i++;
}
FileOutputStream fos = new FileOutputStream(config.getDossierTemporaire() + "Interdits_en_erreur.xlsx");
workbookToWrite.write(fos);
workbookToWrite.close();
sourceWorkbook.close();
}
private static void copyRow(Sheet newSheet, Row sourceRow, int newRowNum) {
Row newRow = newSheet.createRow(newRowNum);
newRow = sourceRow;
}
EDIT : Change the method of copyRow it's better but the date have weird format and blank cells from the original row are gone.
private static void copyRow(Sheet newSheet, Row sourceRow, int newRowNum) {
Row newRow = newSheet.createRow(newRowNum);
Integer i = 0;
for (Cell cell : sourceRow) {
if(cell.getCellTypeEnum() == CellType.NUMERIC) {
newRow.createCell(i).setCellValue(cell.getDateCellValue());
} else {
newRow.createCell(i).setCellValue(cell.getStringCellValue());
}
i++;
}
}
EDIT 2 : To keep blank cell
private static void copyRow(Sheet newSheet, Row sourceRow, Integer newRowNum, Integer cellToColor) {
Row newRow = newSheet.createRow(newRowNum);
//Integer i = 0;
int lastColumn = Math.max(sourceRow.getLastCellNum(), 0);
for(int i = 0; i < lastColumn; i++) {
Cell oldCell = sourceRow.getCell(i, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
if(oldCell == null) {
newRow.createCell(i).setCellValue("");
} else if (oldCell.getCellTypeEnum() == CellType.NUMERIC) {
newRow.createCell(i).setCellValue(oldCell.getDateCellValue());
} else {
newRow.createCell(i).setCellValue(oldCell.getStringCellValue());
}
}
}
I am trying to write data into excel through the web tables.
starting rows get created with blank data and last row is filled with data, with last index value.
other rows are not getting filled with data even when data is present in the Arraylist.
public class Write_Excel {
public static `FileInputStream` `fis`;
public static FileOutputStream fos;
public static `HSSFWorkbook` `wb`;
public static `HSSFSheet` `sheet`;
public static `HSSFCell` `cell`;
public static `HSSFRow` `row`;
public static `int a = 0`;
public static void write_Excel(String fileName, String sheetName,
`ArrayList`<String> `dataToWrite`) throws `IOException` {
fos = new `FileOutputStream(fileName);
wb = new HSSFWorkbook();
sheet = `wb.createSheet(sheetName);`
`row = sheet.createRow(a++);`
for (int i = 0; i < 16; i++) {
cell = row.createCell(i);
System.out.println(dataToWrite.get(i).toString());
cell.setCellValue(new HSSFRichTextString(dataToWrite.get(i)));
}
wb.write(fos);
fos.flush();
}
}
You should add this line into for loop
HSSFRow row = sheet.createRow(a++);
As you do it, you create a new workbook every time you call the function and you just end up erasing the previous ones. Therefore you only get the result of the last call.
If you want to add a line at every call, do it this way, you need to have the row number and the workbook as class variables. Also you need to get hold of the sheet that you already created to append to it. or you are going to erase it too.
public static void main(String[] args) {
try {
write_Excel("myFile.xls","sheetName",
Arrays.asList("value 1", "value 2", "value 3"));
write_Excel("myFile.xls","sheetName",
Arrays.asList("value 4", "value 5", "value 6"));
} catch(IOException e) {
e.printStackTrace();
}
}
private static int newRowIndex = 0;
private static HSSFWorkbook workbook = new HSSFWorkbook();
public static void write_Excel(String fileName, String sheetName, List<String> dataToWrite) throws IOException {
FileOutputStream fos = new FileOutputStream(fileName);
// open or create sheet
HSSFSheet sheet = workbook.getSheet(sheetName) != null ?
workbook.getSheet(sheetName) :
workbook.createSheet(sheetName);
// create a new row
HSSFRow row = sheet.createRow(newRowIndex ++);
// write your data in the new row
for (int colIndex = 0; colIndex < dataToWrite.size(); colIndex++) {
HSSFCell cell = row.createCell(colIndex);
cell.setCellValue(new HSSFRichTextString(dataToWrite.get(colIndex)));
}
workbook.write(fos);
fos.flush();
fos.close();
}
I want to run selenium-webdriver-java-eclipse, using excel file contains multiple excel sheets with different name(sheet1,sheet2,sheet3,...), i need a for loop help me to do that and read from this sheets.
public class ExcelDataConfig {
XSSFWorkbook wb;
XSSFSheet sheet = null;
public ExcelDataConfig(String Excelpath) throws IOException {
// TODO Auto-generated method stub
try {
File file = new File(Excelpath);
// Create an object of FileInputStream class to read excel file
FileInputStream fis = new FileInputStream(file);
wb = new XSSFWorkbook(fis);
} catch (Exception e) {
}
}
public String GetData(int sheetNumber, int Row, int Column) {
Iterator<Row> rowIt=sheet.rowIterator();
DataFormatter formatter = new DataFormatter();
XSSFCell cell = sheet.getRow(Row).getCell(Column);
String data = formatter.formatCellValue(cell);
return data;
}
public int GetRowCount(String sheetNumber) {
int row = wb.getSheet(sheetNumber).getLastRowNum();
row = row + 1;
return row;
}
}
try something like this, it is working for me you need to add the sheet numbers and cell numbers at the places of k and j
enter code here
String filePath="C:\\Users\\USER\\Desktop\\Book1.xlsx";// file path
FileInputStream fis=new FileInputStream(filePath);
Workbook wb=WorkbookFactory.create(fis);
ArrayList<String> ls=new ArrayList<String>();
for(int k=0; k<=3;k++)//k =sheet no
{
Sheet sh=wb.getSheetAt(k);
System.out.println(sh);
// int count=0;
for(int i=0;i<=sh.getLastRowNum();i++)
{
System.out.println("row no:"+i);
for(int j=0; j<=4;j++)//j=column no
{
try {
String values=sh.getRow(i).getCell(j).getStringCellValue().trim();
System.out.println(values);
//condetions
/* if(values.contains("condtn1"))
{
System.out.println("Value of cell "+values+" ith row "+(i+1));
ls.add(values);
count++;
}
if(values.contains("condn2"))
{
System.out.println("Value of cell "+values+" ith row "+(i+1));
ls.add(values);
count++;
}*/
}catch(Exception e){
}
}
}
}
}
}
Please try writing similar to something like this:
for (int i = startRow; i < endRow + 1; i++) {
for (int j = startCol; j < endCol + 1; j++) {
testData[i - startRow][j - startCol] = ExcelWSheet.getRow(i).getCell(j).getStringCellValue();
Cell cell = ExcelWSheet.getRow(i).getCell(j);
testData[i - startRow][j - startCol] = formatter.formatCellValue(cell);
}
}
Terms used in method are pretty self explanatory. Let us know if you get stuck or need more info.
public class sample {
private static Workbook workbook;
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("C://Users//chakku//Desktop//ch//updated/TestReport Lang Funda1.xls");
workbook = new HSSFWorkbook(fis);
Sheet sh = workbook.getSheetAt(0);
for(int i=0;i<=sh.getLastRowNum();i++) {
int z=i+1;
Cell cell = sh.getRow(z).getCell(1);
if(Cell.CELL_TYPE_BLANK == cell.getCellType()) {
System.out.println("3");
}else {
System.out.println(cell.getRichStringCellValue());
}
}
}catch(FileNotFoundException ex) {
ex.printStackTrace();
}catch(IOException ex) {
ex.printStackTrace();
}
}
}
I don't know what's wrong but at the end when all records are fetched it's printing NullPointerException
Error in constructing the access index - use this:
for(int z= 1;z<=sh.getLastRowNum();z++) {
if say you just have two rows, then sh.getLastRowNum() will return you one (as it starts count with 0), and you will try to access it like
for(int i=0;i<=sh.getLastRowNum();i++) {
int z=i+1;
Cell cell = sh.getRow(z).getCell(1);
So for i = 1, you are accessing 2nd row (sh.getRow(2)), which doesnt exists as you should start with 0th row. You should do the following:
for(int i=0;i<=sh.getLastRowNum();i++) {
Cell cell = sh.getRow(z).getCell(1);