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);
Related
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));
}
Maybe "writing" wasn't the correct word since in this function, I am just setting the cells and then writing afterwards.
I have a function that I have pin pointed to be the cause of it bogging down. When it gets to this function, it spends over 10 minutes here before I just terminate it.
This is the function that I am passing an output_wb to:
private static void buildRowsByListOfRows(int sheetNumber, ArrayList<Row> sheet, Workbook wb) {
Sheet worksheet = wb.getSheetAt(sheetNumber);
int lastRow;
Row row;
String cell_value;
Cell cell;
int x = 0;
System.out.println("Size of array list: " + sheet.size());
for (Row my_row : sheet) {
try {
lastRow = worksheet.getLastRowNum();
row = worksheet.createRow(++lastRow);
for (int i = 0; i < my_row.getLastCellNum(); i++) {
cell_value = getCellContentAsString(my_row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
cell = row.createCell(i);
cell.setCellValue(cell_value);
System.out.println("setting row #: " + x + "with value =>" + cell_value);
}
x++;
} catch (Exception e) {
System.out.println("SOMETHING WENT WRONG");
System.out.println(e);
}
}
}
The size of the ArrayList is 73,835. It starts off running pretty fast then it gets to around row 20,000 and it then you can see the print statements in the loop getting spread out further and further apart. Each row has 70 columns.
Is this function really written that poorly or is something else going on?
What can I do to optimize this?
I create the output workbook like this if this matters:
// Create output file with the required sheets
createOutputXLSFile(output_filename_path);
XSSFWorkbook output_wb = new XSSFWorkbook(new FileInputStream(output_filename_path));
And the createOutputXLSFile() looks like this:
private static void createOutputXLSFile(String output_filename_path) throws FileNotFoundException {
try {
// Directory path where the xls file will be created
// Create object of FileOutputStream
FileOutputStream fout = new FileOutputStream(output_filename_path);
XSSFWorkbook wb = new XSSFWorkbook();
wb.createSheet("Removed records");
wb.createSheet("Added records");
wb.createSheet("Updated records");
// Build the Excel File
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
wb.write(outputStream);
outputStream.writeTo(fout);
outputStream.close();
fout.close();
wb.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static String getCellContentAsString(Cell cell) {
DataFormatter fmt = new DataFormatter();
String data = null;
if (cell.getCellType() == CellType.STRING) {
data = String.valueOf(cell.getStringCellValue());
} else if (cell.getCellType() == CellType.NUMERIC) {
data = String.valueOf(fmt.formatCellValue(cell));
} else if (cell.getCellType() == CellType.BOOLEAN) {
data = String.valueOf(fmt.formatCellValue(cell));
} else if (cell.getCellType() == CellType.ERROR) {
data = String.valueOf(cell.getErrorCellValue());
} else if (cell.getCellType() == CellType.BLANK) {
data = String.valueOf(cell.getStringCellValue());
} else if (cell.getCellType() == CellType._NONE) {
data = String.valueOf(cell.getStringCellValue());
}
return data;
}
Update #1- Seems to be happening here. If I comment out all 3 lines then it finishes:
cell_value = getCellContentAsString(my_row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
cell = row.createCell(i);
cell.setCellValue(cell_value);
Update #2 - If I comment out these two lines, then the loop finishes as expected:
cell = row.createCell(i); // The problem
cell.setCellValue(cell_value);
So now I know the problem is the row.createCell(i) but why? How can I optimize this?
I finally managed to resolve this issue. Turns out that using XSSF to write is just too slow if the files are large. So I converted the XSSF output workbook to an SXSSFWorkbook. To do that I just passed in my already existing XSSFWorkbook into SXSSFWorkbook like this :
// Create output file with the required sheets
createOutputXLSFile(output_filename_path);
XSSFWorkbook output_wb_temp = new XSSFWorkbook(new FileInputStream(output_filename_path));
SXSSFWorkbook output_wb = new SXSSFWorkbook(output_wb_temp);
The rest of the code works as is.
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.
I have a problem with getting data from this function when I call it twice. The function returns an arrayList of all rows fetched from an excel sheet. When I call the function the first time I get the correct amount of rows (all rows except the headline row and the row with exit). The second time I call the function I get 0.
It seems that something happens with file or the sheets created the second time, here is the code:
private static List<String[]> getDataFromXLS(String excelPath) {
FileInputStream fis;
Workbook workbook; Sheet sheet; XSSFRow row;
Iterator<Row> rows;
XSSFCell cell;
List<String[]> allExcelRows = new ArrayList<String[]>();
String[] xlsRow;
columnNames = new LinkedHashMap<Integer, String>();
paramNames = new LinkedHashMap<String, Integer>();
int totalColumnCount = 0;
int rowNumber = 1;
try {
fis = new FileInputStream(new File(excelPath));
workbook = WorkbookFactory.create(fis);
sheet = workbook.getSheet("TestData");
rows = sheet.rowIterator();
while (rows.hasNext()) {
row = ((XSSFRow) rows.next());
if (rowNumber == 1) {
//based on amount of parameters on first xls row
totalColumnCount = row.getLastCellNum();
}
xlsRow = new String[totalColumnCount];
//check which column is TestType
//iterate through all the columns
for (int columnNumber=0; columnNumber<totalColumnCount; columnNumber++) {
cell = row.getCell(columnNumber, Row.CREATE_NULL_AS_BLANK);
if (getCellValue(cell).trim().toLowerCase().trim().equals("testtype") ){
testTypeColumnIndex = columnNumber; //this is Testtype index
break;
}
}
if (rowNumber != 1) {
for(int columnNumber=0; columnNumber<totalColumnCount; columnNumber++) {
cell = row.getCell(columnNumber, Row.CREATE_NULL_AS_BLANK);
//read only rows before exit
if (columnNumber == testTypeColumnIndex && getCellValue(cell).trim().toLowerCase().trim().equals("exit") ){
reachedExit = true;
break;
}
xlsRow[columnNumber] = getCellValue(cell).trim();
}
//reached exit?
if (reachedExit) {
break;
}
allExcelRows.add(xlsRow);
} else {
//save column names into map
for(int columnNumber=0; columnNumber<totalColumnCount; columnNumber++) {
cell = row.getCell(columnNumber, Row.CREATE_NULL_AS_BLANK);
columnNames.put(columnNumber, getCellValue(cell).trim());
paramNames.put(getCellValue(cell).trim(), columnNumber);
}
}
rowNumber++;
}
} catch (Exception e) {
e.printStackTrace();
}
fis.close();
return allExcelRows;
}
Am taking a bit of a guess here but I think the problem is that the reachedExit class level boolean is not reset at the start of the method. Hence when you call it the second time this code block executes:
//reached exit?
if (reachedExit) {
break;
}
....meaning that nothing gets added to allExcelRows