testNG multiple dataproviders passing data to one class having multiple test methods - apache-poi

EDIT1: I have an ExcelUtility.java class to get cell data from it and pass it on to the tests methods in my test class.
I am reading from 1 excel file.
The excel file has 3 worksheets.
Every worksheet has 1 unique working table inside.
I have 1 Test class.
The test class has 3 test methods.
The test class contains 3 dataProviders.
All dataProviders differ in the worksheet name and working table name.
The tests in the test class are written in the following manner:
#Test(priority = 0, dataProvider = "dp1")
public void test01(String...strings){
}
#Test(priority = 1, dataProvider = "dp2")
public void test02(String...strings){
}
#Test(priority = 2, dataProvider = "dp3")
public void test03(String...strings){
}
I have the following java class to read from XLSX file using apache poi jars:
public class ExcelUtility {
private static XSSFWorkbook ExcelWBook;
private static XSSFSheet ExcelWSheet;
/*
* Set the File path, open Excel file
* #params - Excel Path and Sheet Name
*/
public static void setExcelFile(String path, String sheetName) throws Exception {
try {
// Open the Excel file
FileInputStream ExcelFile = new FileInputStream(path);
// Access the excel data sheet
ExcelWBook = new XSSFWorkbook(ExcelFile);
ExcelWSheet = ExcelWBook.getSheet(sheetName);
} catch (Exception e) {
throw (e);
}
}
public static String[][] getTestData(String tableName) {
String[][] testData = null;
try {
// Handle numbers and strings
DataFormatter formatter = new DataFormatter();
XSSFCell[] boundaryCells = findCells(tableName);
XSSFCell startCell = boundaryCells[0];
XSSFCell endCell = boundaryCells[1];
int startRow = startCell.getRowIndex() + 1;
int endRow = endCell.getRowIndex() - 1;
int startCol = startCell.getColumnIndex() + 1;
int endCol = endCell.getColumnIndex() - 1;
testData = new String[endRow - startRow + 1][endCol - startCol + 1];
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);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return testData;
}
public static XSSFCell[] findCells(String tableName) {
DataFormatter formatter = new DataFormatter();
String pos = "begin";
XSSFCell[] cells = new XSSFCell[2];
for (Row row : ExcelWSheet) {
for (Cell cell : row) {
// if (tableName.equals(cell.getStringCellValue())) {
if (tableName.equals(formatter.formatCellValue(cell))) {
if (pos.equalsIgnoreCase("begin")) {
cells[0] = (XSSFCell) cell;
pos = "end";
} else {
cells[1] = (XSSFCell) cell;
}
}
}
}
return cells;
}
}
In order to read from the excel file I have organized the test methods in the following manner:
#DataProvider(name = "dp1")
public Object[][] dp1() throws IOException {
Object[][] testData = new Object[0][];
try {
ExcelUtility.setExcelFile(Constants.File_Path+Constants.File_Name, "Page1");
testData = ExcelUtility.getTestData("P1");
} catch (Exception e) {
e.printStackTrace();
}
return testData;
}
#DataProvider(name = "dp2")
public Object[][] dp2() throws IOException {
Object[][] testData = new Object[0][];
try {
ExcelUtility.setExcelFile(Constants.File_Path+Constants.File_Name, "Page2");
testData = ExcelUtility.getTestData("P2");
} catch (Exception e) {
e.printStackTrace();
}
return testData;
}
#DataProvider(name = "dp3")
public Object[][] dp3() throws IOException {
Object[][] testData = new Object[0][];
try {
ExcelUtility.setExcelFile(Constants.File_Path+Constants.File_Name, "Page3");
testData = ExcelUtility.getTestData("P3");
} catch (Exception e) {
e.printStackTrace();
}
return testData;
}
#Test(priority = 0, dataProvider = "dp1")
public void test01(String...strings){
//read data from excel and pass the value to the strings added as arguments in the method above
}
#Test(priority = 1, dataProvider = "dp2")
public void test02(String...strings){
}
#Test(priority = 2, dataProvider = "dp3")
public void test03(String...strings){
}
What I would like to do is the following:
Read first row data from sheet1, pass it to test1, continue to test2
Read first row data from sheet2, pass it to test2, continue to test3
Read first row data from sheet3, pass it to test3, continue to test1
Read second row data from sheet 1, pass it to test1, continue to test2
And so on, depending of number of rows in the excel sheets.
What happens is:
The first test is executed, reads worksheet 1, row 1.
The first test is executed, reads worksheet 1, row 2.
The second test is executed, reads worksheet 2, row 1.
The second test is executed, reads worksheet 2, row 2.
All tests fail because they are dependable from each other, that is why I set execution priority.
Should I change something in the Test class, or something in the ExcelUtility.java class should be changed?
Thank you in advance!

See files related to the commit
It creates testng.xml based on xlsx with test data.

Related

Not able to run java code from Eclipse to Jmeter using Groovy

The code below prints the content from the excel file (tried in eclipse) but I am not able to run it in Jmeter 3.1 using Groovy.
I throws error:
Problem in JSR223 script JSR223 Sampler, message:
javax.script.ScriptException:
org.codehaus.groovy.control.MultipleCompilationErrorsException:
startup failed
This is my code:
public static void main (String args[]) throws IOException
{
GetExcelTableInto2DArrayListString("C:\\Users\\val1\\Desktop\\Book1.xlsx", true);
}
public static void GetExcelTableInto2DArrayListString(String excelFile, boolean debug) throws IOException{
ArrayList<String> OUT = new ArrayList<String>();
File myFile = new File(excelFile);
FileInputStream fis = null;
fis = new FileInputStream(myFile);
String columnWanted = "PhysicalIDs";
Integer columnNo = null;
XSSFWorkbook myWorkBook = null;
myWorkBook = new XSSFWorkbook (fis);
// Return first sheet from the XLSX workbook
XSSFSheet mySheet = myWorkBook.getSheetAt(0);
// Get iterator to all the rows in current sheet
List<Cell> cells = new ArrayList<Cell>();
Row firstRow = mySheet.getRow(0); //rowIterator.next();
for(Cell cell:firstRow){
if (cell.getStringCellValue().equals(columnWanted)){
columnNo = cell.getColumnIndex();
}
}
System.out.println(columnNo);
DataFormatter formatter = new DataFormatter(Locale.US);
if (columnNo != null){
for (Row row : mySheet) {
Cell c = row.getCell(columnNo);
System.out.println(formatter.formatCellValue(c));
if (c == null) {
// Nothing in the cell in this row, skip it
} else {
cells.add(c);
}
}
}else{
System.out.println("could not find column " + columnWanted + " in first row of " + myFile.toString());
}
}
I strongly doubt that your code works in eclipse (whatever it is) and anywhere else because this line:
public static void main (String args[])
is not syntactically correct neither in Java nor in Groovy.
The "good" declaration of the entry point (although it's not required for Groovy scripts) would be:
public static void main(String[] args)
Full code just in case:
import org.apache.poi.ss.usermodel.Cell
import org.apache.poi.ss.usermodel.DataFormatter
import org.apache.poi.ss.usermodel.Row
import org.apache.poi.xssf.usermodel.XSSFSheet
import org.apache.poi.xssf.usermodel.XSSFWorkbook
public static void main(String[] args) throws IOException {
GetExcelTableInto2DArrayListString("C:\\Users\\val1\\Desktop\\Book1.xlsx", true);
}
public static void GetExcelTableInto2DArrayListString(String excelFile, boolean debug) throws IOException {
ArrayList<String> OUT = new ArrayList<String>();
File myFile = new File(excelFile);
FileInputStream fis = null;
fis = new FileInputStream(myFile);
String columnWanted = "PhysicalIDs";
Integer columnNo = null;
XSSFWorkbook myWorkBook = null;
myWorkBook = new XSSFWorkbook(fis);
// Return first sheet from the XLSX workbook
XSSFSheet mySheet = myWorkBook.getSheetAt(0);
// Get iterator to all the rows in current sheet
List<Cell> cells = new ArrayList<Cell>();
Row firstRow = mySheet.getRow(0); //rowIterator.next();
for (Cell cell : firstRow) {
if (cell.getStringCellValue().equals(columnWanted)) {
columnNo = cell.getColumnIndex();
}
}
System.out.println(columnNo);
DataFormatter formatter = new DataFormatter(Locale.US);
if (columnNo != null) {
for (Row row : mySheet) {
Cell c = row.getCell(columnNo);
System.out.println(formatter.formatCellValue(c));
if (c == null) {
// Nothing in the cell in this row, skip it
} else {
cells.add(c);
}
}
} else {
System.out.println("could not find column " + columnWanted + " in first row of " + myFile.toString());
}
}
More information:
Lesson: A Closer Look at the "Hello World!" Application
Busy Developers' Guide to HSSF and XSSF Features
Apache Groovy - Why and How You Should Use It

VSTO - Excel - AutoFilter - Trying to get Date filter criteria (year, month or day) throws exception

I'm trying to get the filters of a table in order to reapply them after some modifications. Everything is ok, but the trouble begins when the filter is on a Date column. This is the way I'm doing it:
for (int i = 1; i <= filters.Count; i++)
{
FilterTemp f = new FilterTemp();
f.On = filters[i].On;
if (f.On)
{
f.Field = i;
try
{
f.Criteria1 = filters[i].Criteria1;
}
catch { }
f.Operator = (int)filters[i].Operator;
try
{
f.Criteria2 = filters[i].Criteria2;
}
catch { }
}
fs.Add(f);
}
When the filter is on a text or number column, everything works beautifully, but when a date column is filtered by year, month or day, I get an exception on line 5 when trying to get the "Criteria1".
I tried to change the operator to xlFilterDynamic, as mentioned on an answer of this MSDN post: https://social.msdn.microsoft.com/Forums/vstudio/en-US/15ec8d69-3e6f-450d-82c0-ca53e63c8f64/getting-data-of-list-object-filters-for-date-column?forum=vsto
Something like this:
for (int i = 1; i <= filters.Count; i++)
{
FilterCache f = new FilterCache();
f.On = filters[i].On;
if (f.On)
{
f.Field = i;
try
{
f.Criteria1 = filters[i].Criteria1;
}
catch
{
filters[i].Operator = XlAutoFilterOperator.xlFilterDynamic;
f.Criteria1 = filters[i].Criteria1;
}
f.Operator = (int)filters[i].Operator;
if (f.Operator == 0)
f.Operator = (int)XlAutoFilterOperator.xlAnd;
try
{
f.Criteria2 = filters[i].Criteria2;
}
catch { }
}
fs.Add(f);
}
No success. The filters[i].Criteria1 is now returning 1 forever, it doesn't matter the filter I use on that date column.
In order to simulate this issue, it is necessary to create a table on an Excel worksheet and then put some random dates in a column. Then, filter this column selecting at least 3 different dates. Run the code.
There's already a post about this on stackoverflow: Excel VSTO - accessing AutoFilter's Array Criteria throws exceptions
Also at: https://social.msdn.microsoft.com/Forums/office/en-US/281fdbc5-6535-497f-b427-f69f4b092e24/excel-vsto-accessing-autofilters-array-criteria-throws-exceptions
... But there are no satisfactory answers or maybe it is a little bit difficult to understand the question.
FilterTemp class:
public class FilterTemp
{
public bool On;
public object Field;
public object Criteria1;
public int Operator;
public object Criteria2;
}
So this is just an idea The ultimate goal is to return the date back to client in a way that it can be re-applied via AutoFilter like here
string[] FilterList = new string[] { "10/31/2013", "5/4/2013" };
visibleCells.AutoFilter(1, FilterList.Length > 0 ? FilterList.ToArray() : Type.Missing, Excel.XlAutoFilterOperator.xlFilterValues, Type.Missing, true);
Hopefully this will give you a hint how to continue. I'll try to finalize it some day.
All code with example on GitHub
using System;
using System.Collections.Generic;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Excel = Microsoft.Office.Interop.Excel;
using System.IO;
namespace AutoFilterRetriever
{
/// <summary>
/// An example class how to get AutoFilter criteria from internal XML representation
/// </summary>
public class CriteriaFilterRetriever : IDisposable
{
private readonly Excel.Worksheet wks;
private readonly string filePath;
private Stream docStream;
private SpreadsheetDocument openXmlDoc;
private WorkbookPart wkb;
public CriteriaFilterRetriever(Excel.Worksheet sheet)
{
wks = sheet;
filePath = sheet.Application.ActiveWorkbook.FullName;
if (!filePath.Contains("\\"))
{
throw new FileLoadException("Save the file in order to get autofilter criteria");
}
}
/// <summary>
/// This can be changed to a complex object instead of just list of strings
/// </summary>
public List<string> FilterCriteria { get; private set; }
public void GetFilterCriteria()
{
if (!OpenFile()) throw new FileLoadException($"Couldn't open the file - {filePath}");
if (wks.AutoFilter == null) return;
// here we get sheet in the workbook.xml (Equals don't work here)
var sheetInWkb = wkb.Workbook.Descendants<Sheet>().Where(s => s.Name == wks.Name).FirstOrDefault();
// get a reference to the worksheet part. Imagine part as the folder in the zip structure
WorksheetPart wsPart = (WorksheetPart)(wkb.GetPartById(sheetInWkb.Id));
// finally get the xml file e.g. sheet1.xml
var sheet = wsPart.Worksheet;
// there should be just one autofilter per sheet
var filter = sheet.Descendants<AutoFilter>().First();
if (filter == null) throw new InvalidOperationException($"Couldn't get autofilter data from the {wks.Name} sheet.");
ManageFilterData(filter);
}
private void ManageFilterData(AutoFilter filter)
{
FilterCriteria = new List<string>();
// this is always the first element in AutoFilter
foreach (FilterColumn filterCol in filter)
{
// here we get the filters data
var filters = filterCol.FirstChild;
if (filters is Filters)
{
foreach (var item in filters)
{
if (item is DateGroupItem)
{
FilterCriteria.Add(GetDateFilterCriteria(item as DateGroupItem));
}
else if (item is Filter)
{
FilterCriteria.Add(((Filter)item).Val);
}
else
{
throw new Exception("Not sure what to do here");
}
}
}
else if (filters is CustomFilters)
{
// if custom filter is applied (more than one criteria it falls to this category
foreach (var item in filters)
{
if (item is CustomFilter)
{
var tmp = item as CustomFilter;
FilterCriteria.Add($"{tmp.Operator}, {tmp.Val}");
}
else
{
throw new Exception("Not sure what to do here");
}
}
}
}
}
private string GetDateFilterCriteria(DateGroupItem criteria)
{
if (criteria.DateTimeGrouping == DateTimeGroupingValues.Year)
{
return criteria.Year.ToString();
}
else if (criteria.DateTimeGrouping == DateTimeGroupingValues.Month)
{
return $"{criteria.Year.ToString()}-{criteria.Month.ToString()}";
}
else if (criteria.DateTimeGrouping == DateTimeGroupingValues.Day)
{
return $"{criteria.Year.ToString()}-{criteria.Month.ToString()}-{criteria.Day.ToString()}";
}
else if (criteria.DateTimeGrouping == DateTimeGroupingValues.Hour)
{
return $"{criteria.Year.ToString()}-{criteria.Month.ToString()}-{criteria.Day.ToString()} {criteria.Hour.ToString()}:00:00";
}
else if (criteria.DateTimeGrouping == DateTimeGroupingValues.Minute)
{
return $"{criteria.Year.ToString()}-{criteria.Month.ToString()}-{criteria.Day.ToString()} {criteria.Hour.ToString()}:{criteria.Minute.ToString()}:00";
}
else
{
return $"{criteria.Year.ToString()}-{criteria.Month.ToString()}-{criteria.Day.ToString()} " +
$"{criteria.Hour.ToString()}:{criteria.Minute.ToString()}:{criteria.Second.ToString()}";
}
}
/// <summary> Opens the given file via the DocumentFormat package </summary>
/// <returns></returns>
private bool OpenFile()
{
try
{
docStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
openXmlDoc = SpreadsheetDocument.Open(docStream, false);
wkb = openXmlDoc.WorkbookPart;
return true;
}
catch (Exception)
{
return false;
}
}
public void Dispose()
{
openXmlDoc?.Close();
docStream?.Close();
}
}
}

Embed Excel in JavaFx

Is there a library that allows for the display of an excel sheet/workbook inside a FX GUI? It does not need to be modifiable.
I am using apache POI for the reading and writing of documents.
Thanks in advance.
As an update on how I solved this. I used controlsFX's SpreadsheetView to display the excel sheet I read using the poi library. All that was required was to read the sheet and build up the data for the view. I added the code below.
/**
* This class allows for the displaying of excel files within a window by
* utilizing SpreadsheetView from controlsFX and the reading capabilities of the POI library.
*
* Only usable for .xlsx files
*
* #author TM
*
*/
public class ExcelView {
/**
* Path to Excel
*/
private String filePath;
private int sheetIndex;
private boolean editible;
private FileInputStream inStream;
private XSSFWorkbook poiWorkbook;
private XSSFSheet poiSheet;
private SpreadsheetView theView;
public ExcelView(String path, int sheetIndex ,boolean editable){
filePath =path;
this.editible =editable;
this.sheetIndex =sheetIndex;
}
public ExcelView(String path, int sheetIndex){
filePath =path;
this.editible =false;
this.sheetIndex = sheetIndex;
}
private void initializeView() throws Exception{
GridBase grid = excelToGrid();
theView = new SpreadsheetView(grid);
theView.setEditable(editible);
}
public SpreadsheetView getView() throws Exception{
initializeView();
return theView;
}
public void showInNewWindow(){
Parent root;
try {
initializeView();
root = theView;
Stage stage = new Stage();
stage.setTitle(new File(filePath).getName());
stage.setScene(new Scene(root, 450, 450));
stage.getIcons().addAll(ResourceLoader.getIcons("Excel.ico"));
stage.show();
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* Updates the values in the view. This may happen after the Excel file has been
* modified after the initial reading.
* #throws Exception
*/
public void updateView() throws Exception{
GridBase newgrid = excelToGrid();
theView.setGrid(newgrid);
}
/**
* Creates a {#link GridBase} object from the excel file located at the path
* #return
* #throws Exception - when opening the file
*/
private GridBase excelToGrid() throws Exception{
// Read the Excel document and collect the rows
openBook();
poiSheet = poiWorkbook.getSheetAt(sheetIndex);
int[] size = getSize();
GridBase grid = new GridBase(size[0], size[1]);
ObservableList<ObservableList<SpreadsheetCell>> rows = FXCollections.observableArrayList();
Row poiRow;
Cell cell;
String value;
FormulaEvaluator evaluator = poiWorkbook.getCreationHelper().createFormulaEvaluator();
for (int row = 0; row < grid.getRowCount(); ++row) {
final ObservableList<SpreadsheetCell> list = FXCollections.observableArrayList();
poiRow = poiSheet.getRow(row);
for (int column = 0; column < grid.getColumnCount(); ++column) {
cell = poiRow.getCell(column);
value = ExcelUtils.cellStringValue(evaluator,cell);
list.add(SpreadsheetCellType.STRING.createCell(row, column, 1, 1,value));
}
rows.add(list);
}
grid.setRows(rows);
closeBook();
return grid;
}
/**
* Calculates the number of rows and columns in the sheet by looping
* and reading all the things :)
* #return the size as int[{rows, cols}]
*/
private int[] getSize(){
int numRows = 0;
int numCols =0;
int nullRowCounter = 0;
int nullColCounter = 0;
int maxNullRows = 6;
int maxNullCols = 6;
Row row;
Cell cell;
int localColCounter;
while(true){
row= poiSheet.getRow(numRows);
numRows++;
// Check row...
if(row == null){
nullRowCounter++;
}
else{
nullRowCounter = 0;
// If row not null, check columns...
localColCounter = 0;
while(true){
cell = row.getCell(localColCounter);
localColCounter++;
if(cell==null){
nullColCounter++;
}else{
nullColCounter = 0;
}
if(nullColCounter == maxNullCols){
// reached max null cells
localColCounter -= maxNullCols;
if(localColCounter > numCols)
numCols = localColCounter;
break;
// go to next row...
}
}
}
if(nullRowCounter == maxNullRows){
// reached max null rows
numRows -= maxNullRows;
break;
}
}
return new int[]{numRows, numCols};
}
private void openBook() throws Exception{
try {
File myFile = new File(filePath);
inStream = new FileInputStream(myFile);
poiWorkbook = new XSSFWorkbook (inStream);
}catch (Exception e) {
e.printStackTrace();
throw e;
}
}
private void closeBook() throws Exception{
try {
poiWorkbook.close();
inStream.close();
}catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}

How to edit data with dynamic TableView with dynamic column in JAVAFX

Today This is the demo to show data from CSV for DAT file without make custom class on tableView in JavaFX 2.0. I call this TableView as Dynamic TableView because the tableview automatically manages the columns and rows.
On my research about the editable on tableView we must have a custom class and implement it to tableView to show as this demo ==> http://docs.oracle.com/javafx/2/ui_controls/table-view.htm
But in this case I can not do it because we don't know how many column example with csv file or .dat file.... I want to do editable on this tableView in this case by add TextField into TableCell. How does it do without make custom class (because you do not how many column ...), and if it must make custom class then how about the design of custom class for this case?
Could you please help me?
private void getDataDetailWithDynamic() {
tblView.getItems().clear();
tblView.getColumns().clear();
tblView.setPlaceholder(new Label("Loading..."));
// #Override
try {
File aFile = new File(txtFilePath.getText());
InputStream is = new BufferedInputStream(new FileInputStream(aFile));
Reader reader = new InputStreamReader(is, "UTF-8");
BufferedReader in = new BufferedReader(reader);
final String headerLine = in.readLine();
final String[] headerValues = headerLine.split("\t");
for (int column = 0; column < headerValues.length; column++) {
tblView.getColumns().add(
createColumn(column, headerValues[column]));
}
// Data:
String dataLine;
while ((dataLine = in.readLine()) != null) {
final String[] dataValues = dataLine.split("\t");
// Add additional columns if necessary:
for (int columnIndex = tblView.getColumns().size(); columnIndex < dataValues.length; columnIndex++) {
tblView.getColumns().add(createColumn(columnIndex, ""));
}
// Add data to table:
ObservableList<StringProperty> data = FXCollections
.observableArrayList();
for (String value : dataValues) {
data.add(new SimpleStringProperty(value));
}
tblView.getItems().add(data);
}
} catch (Exception ex) {
System.out.println("ex: " + ex.toString());
}
for(int i=0; i<tblView.getColumns().size(); i++) {
TableColumn col = (TableColumn)tblView.getColumns().get(i);
col.setPrefWidth(70);
}
}
private TableColumn createColumn(
final int columnIndex, String columnTitle) {
TableColumn column = new TableColumn(DefaultVars.BLANK_CHARACTER);
String title;
if (columnTitle == null || columnTitle.trim().length() == 0) {
title = "Column " + (columnIndex + 1);
} else {
title = columnTitle;
}
Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {
#Override
public TableCell call(TableColumn p) {
System.out.println("event cell");
EditingCellData cellExtend = new EditingCellData();
return cellExtend;
}
};
column.setText(title);
column.setCellValueFactory(cellFactory);
return column;
}
Thanks for your reading.
This is the best way to resolve it ==> https://forums.oracle.com/message/11216643#11216643
I'm really thank for your reading about that.
Thanks

How to read excel file omitting first two rows

I have an excel file of 111 rows. I need to omit first two rows of the sheet and then read the file using java and POI.
You have to skip first two rows using rownum().Here is the sample code
HSSFWorkbook workBook = new HSSFWorkbook (fileSystem);
HSSFSheet sheet = workBook.getSheetAt (0);
Iterator<HSSFRow> rows = sheet.rowIterator ();
while (rows.hasNext ())
{
HSSFRow row = rows.next ();
// display row number in the console.
System.out.println ("Row No.: " + row.getRowNum ());
if(row.getRowNum()==0 || row.getRowNum()==1){
continue; //just skip the rows if row number is 0 or 1
}
}
Here is the complete example
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
public class POIExcelReader
{
/** Creates a new instance of POIExcelReader */
public POIExcelReader ()
{}
#SuppressWarnings ("unchecked")
public void displayFromExcel (String xlsPath)
{
InputStream inputStream = null;
try
{
inputStream = new FileInputStream (xlsPath);
}
catch (FileNotFoundException e)
{
System.out.println ("File not found in the specified path.");
e.printStackTrace ();
}
POIFSFileSystem fileSystem = null;
try
{
fileSystem = new POIFSFileSystem (inputStream);
HSSFWorkbook workBook = new HSSFWorkbook (fileSystem);
HSSFSheet sheet = workBook.getSheetAt (0);
Iterator<HSSFRow> rows = sheet.rowIterator ();
while (rows.hasNext ())
{
HSSFRow row = rows.next ();
if(row.getRowNum()==0 || row.getRowNum()==1){
continue; //just skip the rows if row number is 0 or 1
}
// once get a row its time to iterate through cells.
Iterator<HSSFCell> cells = row.cellIterator ();
while (cells.hasNext ())
{
HSSFCell cell = cells.next ();
System.out.println ("Cell No.: " + cell.getCellNum ());
/*
* Now we will get the cell type and display the values
* accordingly.
*/
switch (cell.getCellType ())
{
case HSSFCell.CELL_TYPE_NUMERIC :
{
// cell type numeric.
System.out.println ("Numeric value: " + cell.getNumericCellValue ());
break;
}
case HSSFCell.CELL_TYPE_STRING :
{
// cell type string.
HSSFRichTextString richTextString = cell.getRichStringCellValue ();
System.out.println ("String value: " + richTextString.getString ());
break;
}
default :
{
// types other than String and Numeric.
System.out.println ("Type not supported.");
break;
}
}
}
}
}
catch (IOException e)
{
e.printStackTrace ();
}
}
public static void main (String[] args)
{
POIExcelReader poiExample = new POIExcelReader ();
String xlsPath = "c://test//test.xls";
poiExample.displayFromExcel (xlsPath);
}
}
Apache POI provides two ways to access the rows and cells in an Excel file. One is an iterator that gives you all the entries, the other is to loop up by index. (POI will also tell you the start/end rows/columns). The iterator is often simpler to use, but both are equally as fast.
If you have specific requirements on rows to fetch, I'd suggest you use the latter. Your code would want to be something like:
int FIRST_ROW_TO_GET = 2; // 0 based
Sheet s = wb.getSheetAt(0);
for (int i = FIRST_ROW_TO_GET; i < s.getLastRowNum(); i++) {
Row row = s.getRow(i);
if (row == null) {
// The whole row is blank
}
else {
for (int cn=row.getFirstCellNum(); cn<row.getLastCellNum(); cn++) {
Cell c = row.getCell(cn, Row.RETURN_BLANK_AS_NULL);
if (c == null) {
// The cell is empty
} else {
// Process the cell
}
}
}
}
you can improve Murali N s answer. If you want to skip 40 rows for example, use:
if (currentRow.getRowNum() <= 40) {
continue;
}

Resources