I am using apache POI for excel import and parsing .
I have to get the data by passing column name .
this is my code
JSONObject jo = new JSONObject();
JSONArray dataCollection = new JSONArray();
JSONObject data = null;
try {
String tempCampaignFilesPath = getSessionData("userPath") + System.getProperty("file.separator") + "tempCampaignFiles";
File someFile = new File(tempCampaignFilesPath, fileName);
/* read from this file */
FileInputStream fileInputStream = new FileInputStream(someFile);
HSSFWorkbook workbook = new HSSFWorkbook(fileInputStream);
HSSFSheet sheet = workbook.getSheet(sheetName);
int rowNum = sheet.getLastRowNum() + 1;
int colNum = sheet.getRow(0).getLastCellNum();
Row row = null;
Cell cell = null;
for (int i = 1; i < rowNum; i++) {
row = sheet.getRow(i);
data = new JSONObject();
for (int j = 0; j < colNum; j++) {
cell = row.getCell(j);
data.put(columnList.get(j), cellToString(cell));
}
dataCollection.put(data);
}
fileInputStream.close();
// someFile.delete();
jo.put("tableData", dataCollection);
} catch (Exception e) {
e.printStackTrace();
}
return jo;
There is a provision for column index but how could I do it by column name.
Please help me.
You have to convert column name to index:
int colIdx = CellReference.convertColStringToIndex(letter);
CellUtil.getCell(row, colIdx)
or if you need convert column index to string:
String colName = CellReference.convertNumToColString(colIdx)
Please find below the code an another workaround for this .Please see the comments in code to be more clear what I have done.
JSONObject jo = new JSONObject();
JSONArray dataCollection = new JSONArray();
JSONObject data = null;
try {
String tempCampaignFilesPath = getSessionData("userPath") + System.getProperty("file.separator") + "tempCampaignFiles";
File someFile = new File(tempCampaignFilesPath, fileName);
/* read from this file */
FileInputStream fileInputStream = new FileInputStream(someFile);
HSSFWorkbook workbook = new HSSFWorkbook(fileInputStream);
HSSFSheet sheet = workbook.getSheet(sheetName);
int rowNum = sheet.getLastRowNum() + 1;
int colNum = sheet.getRow(0).getLastCellNum();
Row row = null;
Cell cell = null;
/* first row data for column names and index */
Map<String, Integer> colMapByName = new HashMap<String, Integer>();
if (sheet.getRow(0).cellIterator().hasNext()) {
for (int j = 0; j < colNum; j++) {
colMapByName.put(cellToString(sheet.getRow(0).getCell(j)), j);
}
}
System.out.println(colMapByName);//shows the indexes of columns populated by traversing first row
/* first row data */
for (int i = 1; i < rowNum; i++) {
row = sheet.getRow(i);
data = new JSONObject();
//colMap consists the columnnames and alias name for it
for (Entry<String, String> colData : colMap.entrySet()) {
cell = row.getCell(colMapByName.get(colData.getValue()));//gives the index of column from colMapByName Map by passing column name
data.put(colData.getKey(), cellToString(cell));//now the data passed to the alias for the column tobe used in application
}
dataCollection.put(data);
}
fileInputStream.close();
someFile.delete();
jo.put("tableData", dataCollection);
} catch (Exception e) {
e.printStackTrace();
}
return jo;
Related
i have a large excel file containing 600.000 rows , i used XSSFWorkbook to upload the excel file at a Jtable in my GUI but it takes about 15 minutes to be done in eclipse and once i export my project to a jar file i can't do it even in the 15 minutes . Any help please ?
Here is the method , that i found in internet to upload my excel file .
void fillData(File file) {
int index = -1;
XSSFWorkbook workbook = null;
try {
try {
String f = file.getPath();
File file1 = new File(f);
OPCPackage opcPackage = OPCPackage.open(file1);
workbook = new XSSFWorkbook(opcPackage);
} catch (IOException ex) {
Logger.getLogger(ProjectApp3.class.getName()).log(Level.SEVERE, null, ex);
}
String[] strs = new String[workbook.getNumberOfSheets()];
//get all sheet names from selected workbook
for (int i = 0; i < strs.length; i++) {
strs[i] = workbook.getSheetName(i);
}
JFrame frame = new JFrame("Input Dialog");
//select sheet
String selectedsheet = (String) JOptionPane.showInputDialog(
frame, "Which worksheet you want to import ?", "Select Worksheet",
JOptionPane.QUESTION_MESSAGE, null, strs, strs[0]);
if (selectedsheet != null) {
for (int i = 0; i < strs.length; i++) {
if (workbook.getSheetName(i).equalsIgnoreCase(selectedsheet))
index = i;
}
XSSFSheet sheet = workbook.getSheetAt(index);
XSSFRow row = sheet.getRow(0);
//import headers data
headers.clear();
for (int i = 0; i < row.getLastCellNum(); i++) {
XSSFCell cell1 = row.getCell(i);
headers.add(cell1.toString());
}
//import data
data1.clear();
for (int j = 1; j < sheet.getLastRowNum() + 1; j++) {
Vector d = new Vector();
row = sheet.getRow(j);
int noofrows = row.getLastCellNum();
for (int i = 0; i < noofrows; i++) { //To handle empty excel cells
XSSFCell cell = row.getCell(i,
org.apache.poi.ss.usermodel.Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
d.add(cell.toString());
}
d.add("\n");
data1.add(d);
}
} else {
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
I think the basic problem is that you're trying to give. your Jtable all the data at startup. This is going to be deeply problematic. You may want to write a custom subclass from AbstractTableModel. See the docs for Jtable that includes this:
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return 10; }
public int getRowCount() { return 10;}
public Object getValueAt(int row, int col) { return new Integer(row*col); }
};
JTable table = new JTable(dataModel);
JScrollPane scrollpane = new JScrollPane(table);
You can implement those three methods based on the info that POI gives you. But do lazy loading of the data, most especially for getValueAt(). Keep the spreadsheet file open and grab the data only when the user scrolls to view it.
int col = driver.findElements(By.xpath("//table[#id=\"transactionListData\"]/thead/tr/th")).size();
int row =driver.findElements(By.xpath("//table[#id=\"transactionListData\"]/tbody/tr")).size();
//ArrayList<Object[]> mydata = new ArrayList<Object[]>();
Object [][] ob = new Object[row][col];
for( int i=1; i<=row; i++)
{
for (int j=1; j<=col; j++)
{
String text =driver.findElement(By.xpath("//*[#id='transactionListData']/tbody/tr["+i+"]/td["+j+"]")).getText();
//System.out.println("text " +text);
ob[i][j] = text;
}
}
try {
String s = util.writeIntoExcel(ob, row, col);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//return flag;
}
I have passed ob in below function to write its content in to excel file. but unable to print where ob is a object array Object [][] ob = new Object[row][col];. I am getting an error where i am trying to write data in to excel regarding Object in to string conversion.
public static String writeIntoExcel(Object ob, int rowi,int colj ) throws IOException
{
int rowcount = rowi;
int colcount = colj;
Object oa[][] = new Object[rowcount][colcount];
oa = (Object[][]) ob;
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Transacton History");
for (int i=1; i<=rowcount ; i++)
{
for (int j=1; j<=colcount ; j++)
{
String val = (String) oa[i][j];
Row row = sheet.createRow(i);
row.createCell(colj).setCellValue(val);
}
}
FileOutputStream fileOut = new FileOutputStream("\"\\\\btfin.com\\filesrv\\User\\Offshore\\SG1\\L097117\\user\\My Documents\\workbook.xlsx");
workbook.write(fileOut);
fileOut.close();
return "Data is written";
}
}
Answer to question above is :
Object [][] ob = new Object[row][col];
for( int i=1; i<=row; i++)
{
for (int j=1; j<=col; j++)
{
String text =driver.findElement(By.xpath("//*[#id='transactionListData']/tbody/tr["+i+"]/td["+j+"]")).getText();
//System.out.println("text " +text);
ob[i-1][j-1] = text;
}
}
// rest everything is fine..
public static String writeIntoExcel(Object[][] sob ) throws IOException
{
//String oa[][] = sob;
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Transacton History");
Object cellvalue = null;
for (int i=0; i<=sob.length ; i++)
{
Row row = sheet.createRow(i + 1);
for (int j=0; j<=sob[i].length ; j++)
{
Cell cell=row.createCell(j+1);
cellvalue = sob[i][j];
if (cellvalue instanceof String)
cell.setCellValue((String)(cellvalue));
else if (cellvalue instanceof Integer)
cell.setCellValue((Integer)cellvalue);
cell.setCellValue((String)cellvalue);
}
}
FileOutputStream fileOut = new FileOutputStream("");
workbook.write(fileOut);
fileOut.close();
workbook.close();
return "Data is written";
I am trying to read data from excel which contains only one column with three rows in it
ID
A1002
B1003
C1004
I am using dataprovider in Testng to achieve the same. But on returning the 2D Object array, I am getting sun.reflect.NativeMethodAccessorImpl#2f1ea80d error
#DataProvider(name = "getLoginData")
public Object[][] LoginData() throws Exception
{
Workbook workbook = null;
ArrayList<String> values = new ArrayList<String>();
FileInputStream ExcelFile = new FileInputStream(Path_TestData);
ExcelWBook = new XSSFWorkbook(ExcelFile);
ExcelWSheet = ExcelWBook.getSheet(Home.sheetname);
int rows = ExcelWSheet.getPhysicalNumberOfRows();
System.out.println("Rows is" +rows);
for(int i=1; i<rows; i++)
{
XSSFRow row = ExcelWSheet.getRow(i);
values.add(row.getCell(0).getStringCellValue());
}
System.out.println("value size is" +values.size());
Object[][] returnValue = new Object[10][10];
for(i=0; i<values.size();i++)
{
returnValue[i][0] = values.get(i);
}
return returnValue;
}
#Test(dataProvider="getLoginData")
public void LoginData(String ID)
{
driver.findElement(By.xpath("//*[text()='select']")).click();
//clicking on the ID selected in dropdown
driver.findElement(By.xpath("//*[text()=ID]")).click();
}
Try following code, I've made few adjustments here and there:
#DataProvider(name = "getLoginData")
public static Object[][] LoginData() throws Exception
{
XSSFWorkbook ExcelWBook = null;
ArrayList<String> values = new ArrayList<String>();
FileInputStream ExcelFile = new FileInputStream("C:\\Users\\kushal8\\Desktop\\K1.xlsx");
ExcelWBook = new XSSFWorkbook(ExcelFile);
XSSFSheet ExcelWSheet = ExcelWBook.getSheet("Sheet1");
int rows = ExcelWSheet.getPhysicalNumberOfRows();
System.out.println("Rows is" +rows);
for(int i=1; i<rows; i++)
{
XSSFRow row = ExcelWSheet.getRow(i);
values.add(row.getCell(0).getStringCellValue());
}
System.out.println("value size is" +values.size());
Object[][] returnValue = new Object[15][15];
for(int i=0; i<values.size();i++)
{
returnValue[i][0] = values.get(i);
//System.out.println(returnValue[i][0]);
}
return returnValue;
}
public Object[][] dataProviderMethod() throws IOException {
try {
file = new FileInputStream(new File("/Users/nanthakumar/Documents/workspace/Myna_Admin/src/com/myna/testdata/login.xls"));
workbook = new HSSFWorkbook(file);
sheet = workbook.getSheetAt(0);
row = sheet.getLastRowNum() + 1;
col = sheet.getRow(0).getLastCellNum();
data = new String[row][col];
for (i = 0; i < row; i++) {
rowvalue = sheet.getRow(i);
for (j = 0; j < col; j++) {
cellValue = rowvalue.getCell(j);
data[i][j] = cellValue.getStringCellValue();
System.out.println("The value is ----->" + data[i][j]);
}
workbook.close();
file.close();
}
} catch (FileNotFoundException nana) {
nana.printStackTrace();
}
return data;
}
This is my code and I tried to add the getnumericalCellvalue() instead of getStringCellValue() but that is not working for me.
first you have to check in the template excel whether the column is number or text.you can get the numerical value if and only if the column is of type number.so change the template excel and try
I have an array list of custom objects. I am trying to loop on these objects to write my output to an excel file.
In my code below, in the first loop, I set the header row in the excel file by looping over the class member variables. In the second loop, I write the object values.
My code:
class ChecklistOutput {
//Instantiating class data members
String a, b, c;
public ChecklistOutput() {
a = ""; b = ""; c = ""; }
}
private static ArrayList<ChecklistOutput> MasterOutput = new ArrayList<ChecklistOutput>();
private static void writeToMasterExcel() {
ChecklistOutput obj1 = new ChecklistOutput();
obj1.a = "AA"; obj1.b = "BB"; obj1.c = "CC";
ChecklistOutput obj1 = new ChecklistOutput();
obj2.a = "AA"; obj2.b = "BB"; obj2.c = "CC";
ChecklistOutput obj1 = new ChecklistOutput();
obj3.a = "AA"; obj3.b = "BB"; obj3.c = "CC";
ChecklistOutput obj1 = new ChecklistOutput();
obj4.a = "AA"; obj4.b = "BB"; obj4.c = "CC";
MasterOutput.add(obj1);
MasterOutput.add(obj2);
MasterOutput.add(obj3);
MasterOutput.add(obj4);
System.out.println(MasterOutput.size());
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = null;
HSSFRow row = null;
HSSFCell cell = null;
int rownum = 0, cellnum = 0;
sheet = workbook.createSheet("Master Spreadsheet");
row = sheet.createRow(rownum);
System.out.println("rownum " + rownum);
Class<?> c = new ChecklistOutput().getClass();
Field[] fields = c.getDeclaredFields();
// First loop
for (Field field : fields) {
cell = row.createCell(cellnum);
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue(field.getName());
cellnum += 1;
}
System.out.println(MasterOutput.size());
// Second loop
for (ChecklistOutput x : MasterOutput) {
// This prints 4 times meaning that there are 4 values in
// MasterOutput
System.out.println("Hell");
rownum += 1;
cellnum = 0;
row = sheet.createRow(rownum);
for (Field field : fields) {
cell = row.createCell(cellnum);
cell.setCellType(Cell.CELL_TYPE_STRING);
try {
// I can see values here
System.out.println(field.get(x).toString());
cell.setCellValue(field.get(x).toString());
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
cellnum += 1;
}
}
BufferedOutputStream bos;
try {
bos = new BufferedOutputStream(new FileOutputStream(
"C:\\Users\\ABC\\Documents\\Checklist-Output.xls",
true));
workbook.write(bos);
bos.close();
workbook.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
However, I only get the header values in my excel file.
Output:
| a | b | c |
Can someone help me on this? Thanks!
Try this:
for (int col = 0; col < fields.length; col++) {
Field field = fields[col];
HSSFRow header = sheet.getRow(rownum);
if (header == null) {
header = sheet.createRow(rownum);
}
HSSFCell cell = header.createCell(col);
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue(field.getName());
}
for (ChecklistOutput x : MasterOutput) {
rownum += 1;
HSSFRow rowData = sheet.getRow(rownum);
if (rowData == null) {
rowData = sheet.createRow(rownum);
}
for (int col = 0; col < fields.length; col++) {
Field field = fields[col];
HSSFCell cellData = rowData.createCell(col);
cellData.setCellType(Cell.CELL_TYPE_STRING);
try {
// I can see values here
System.out.println(field.get(x).toString());
cellData.setCellValue(field.get(x).toString());
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
Also i recommend you use a POJO instead of ChecklistOutput (private fields with getters and setters).
I did the same thing you did. If you want the values for the fields from a pojo you can use reflection to invoke the getters. You can look into my question . It asks for something else, but provides a working example to get the values with reflection (i used it for POI as well).