How about reading the row with multiple values using excel
for instance
reference
testcase1
testcase2
testcase3
Name
Sam
ram
cam
Age
20
25
30
sex
m
F
m
place
place1
place2
place 3
I have to read
testcase1.name=sam
testcase2.name=ram
testcase3.name=cam
and age
how can I do this... any help would be appreciated
Use apache poi library.
First you must read the Excel file in a java object
FileInputStream myFile = new FileInputStream(new File(FILE_NAME));
Workbook myWorkbook = new XSSFWorkbook(myFile);
Sheet datatypeSheet = myWorkbook.getSheetAt(0); //read the first sheet
Iterator<Row> iterator = datatypeSheet.iterator();
Then you can iterate over each row and in each row you can read each cell (aka column value)
List<TestCase> myList = new ArrayList();
int rowNum = 0;
while (iterator.hasNext()) {
Row row = iterator.next();
int columnsSize = row.getLastCellNum();
//create all objects
if(rowNum == 0) {
for (int i = 1; i <= columnsSize; i++) {
myList.add(new TestCase());
}
} else {
//initialize property in each row for all objects
for (int i = 1; i <= columnsSize; i++) {
TestCase testCase = myList.get(i-1);
int cellType = row.getCell(i).getCellType();
switch(cellType) {
case Cell.CELL_TYPE_NUMERIC:
testCase.properties.add(new Property(row.getCell(0).getStringCellValue(),
String.valueOf(row.getCell(i).getNumericCellValue()));
break;
case Cell.CELL_TYPE_STRING:
testCase.properties.add(new Property(row.getCell(0).getStringCellValue(),
row.getCell(i).getStringCellValue());
break;
}
}
}
rowNum++;
}
System.out.println(myList);
public class TestCase {
public List<Property> properties;
public TestCase(){
this.properties = new ArrayList();
}
}
public class Property {
String name;
String value;
public Property(String name, String value){
this.name = name;
this.value = value;
}
}
*Edit: For loop must have <= condition instead of <
This tutorial might be helpful to use: https://www.javatpoint.com/how-to-read-excel-file-in-java.
Basically, you are using the Apache POI Library to parse the file's values, generating iterators for each row, then for each cell in each row, and dealing with the data that way.
In your case, after importing the relevant Classes, the code snippet will be something like this:
//Input Data for Class
FileInputStream in = new FileInputStream(new File("<File Location>.xls(x)"));
// Create an Apache POI Workbook reading the file
HSSFWorkbook workbook = new HSSFWorkbook(in);
// Use the Workbook to make a sheet
HSSFSheet sheet = workbook.getSheetAt(0); // Replace 0 with your sheet number
List<Row> rowsList = new ArrayList<Row>();
sheet.iterator().forEachRemaining(actualList::add); // Gets a list of all the rows
int i = -1;
String[] names = new String[3];
for (Cell cell : rowsList[1]) { // Start at second row
if (i++ > 0) {
names[i] = cell.getStringCellValue();
}
}
testcase1.name = names[0];
testcase2.name = names[1];
testcase3.name = names[2];
i = -1;
int[] ages = new int[3];
for (Cell cell : rowsList[2]) { // Start at Third Row
if (i++ > 0) {
ages[i] = (int) cell.getNumericCellValue();
}
}
testcase1.name = ages[0];
testcase2.name = ages[1];
testcase3.name = ages[2];
Related
I have an Excel file which needs filtering on a specific column.
String fileName = "filepath";
String cellContent = "Automation";
int rownr = 0;
int colnr = 0; //column from which you need data to store in array list
InputStream input = new FileInputStream(fileName);
XSSFWorkbook wb = new XSSFWorkbook(input);
XSSFSheet sheet = wb.getSheetAt(0);
List filteredCol = new ArrayList();
filteredCol = findRow(sheet, cellContent);
if (filteredCol != null) {
for (Iterator iter = filteredCol.iterator(); iter.hasNext(); ) {
System.out.println(iter.next());
}
}
private static List findRow(HSSFSheet sheet, String cellContent) {
List filter=new ArrayList();
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
if (cell.getRichStringCellValue().getString().trim().equals(cellContent)) {
//System.out.println("Row numbers are"+row.getRowNum());
int rownumber=row.getRowNum();
//return row.getRowNum();
XSSFRow row1 = sheet.getRow(rownumber);
XSSFCell cell1 = row1.getCell(0);
filter.add(cell1);
}
}
}
}
return filter;
}
I am getting number format exception on this codeline:
"cell.getRichStringCellValue().getString().trim().equals(cellContent)"
I am trying to copy a sheet from two different XSSF Workbooks. I have written a code that works really well (see below) but it doesn't take into account the pop-up documentation for cells and doesn't copy it (which is logical because I haven't written that functionnality).
I have searched the Apache POI documentation and it looks like there is no way to do this. Any idea on how I could do to copy-paste that information?
public class CopySheets {
public static void copySheet(String sheetName, XSSFWorkbook wbSrc,XSSFWorkbook wbDest) throws IOException {
XSSFSheet srcSheet = null;
XSSFRow srcRow = null;
XSSFCell srcCell = null;
XSSFSheet destSheet = null;
XSSFRow destRow = null;
XSSFCell destCell = null;
int fCell = 0;
int lCell = 0;
int fRow = 0;
int lRow = 0;
System.out.println(sheetName);
srcSheet = wbSrc.getSheet(sheetName);
System.out.println(srcSheet);
if (srcSheet != null) {
destSheet = wbDest.createSheet(sheetName);
fRow = srcSheet.getFirstRowNum();
lRow = srcSheet.getLastRowNum();
for (int iRow = fRow; iRow <= lRow; iRow++) {
srcRow = srcSheet.getRow(iRow);
destRow = destSheet.createRow(iRow);
if (srcRow != null) {
fCell = srcRow.getFirstCellNum();
lCell = srcRow.getLastCellNum();
for (int iCell = fCell; iCell < lCell; iCell++) {
srcCell = srcRow.getCell(iCell);
destCell = destRow.createCell(iCell);
if (srcCell != null) {
switch (srcCell.getCellTypeEnum()) {
case BLANK:
destCell.setCellValue("");
break;
case BOOLEAN:
destCell.setCellValue(srcCell.getBooleanCellValue());
break;
case ERROR:
destCell.setCellErrorValue(srcCell.getErrorCellValue());
break;
case FORMULA:
destCell.setCellFormula(srcCell.getCellFormula());
break;
case NUMERIC:
destCell.setCellValue(srcCell.getNumericCellValue());
break;
case STRING:
destCell.setCellValue(srcCell.getStringCellValue());
break;
default:
destCell.setCellFormula(srcCell.getCellFormula());
}
CellStyle origStyle = srcCell.getCellStyle(); // Or from a cell
CellStyle newStyle = wbDest.createCellStyle();
newStyle.cloneStyleFrom(origStyle);
destCell.setCellStyle(newStyle);
Comment origComment=srcCell.getCellComment();
destCell.setCellComment(origComment);
}
}
}
}
}
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("workbook.xls", true));
wbDest.write(bos);
bos.close();
}
}
Thanks a lot!
Okay, I found the answer, it turns out POI has something that enables us to get that info on the sheet as a whole so I added this bit to my code and it works like a charm!
List<XSSFDataValidation> validations=srcSheet.getDataValidations();
for (XSSFDataValidation validation:validations){
destSheet.addValidationData(validation);
}
Looking at the documentation-
http://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/Comment.html
Seems like the getAddress() method of the src Comment object will return the reference to the cell it was previously attached to (which is the src cell).
You should try creating a new Comment instead of doing
Comment origComment=srcCell.getCellComment();
destCell.setCellComment(origComment);
You should use RangeCopier.
XSSFWorkbook workbookFrom = new XSSFWorkbook(new File("/path/to/workbookFrom.xlsx"));
XSSFSheet sheetFrom = workbookFrom.getSheetAt(0);
XSSFWorkbook workbookTo = new XSSFWorkbook(new File("/path/to/workbookTo.xlsx"));
XSSFSheet sheetTo = workbookTo.createSheet("sheet1");
workbookTo.setSheetOrder("sheet1", 0);
XSSFRangeCopier xssfRangeCopier = new XSSFRangeCopier(sheetFrom, sheetTo);
//copy the row height and column width, and find the max column num
int lastRow = sheetFrom.getLastRowNum();
int lastCol = 0;
for (int i = 0; i < lastRow; i++) {
Row row = sheetFrom.getRow(i);
if (row != null) {
if (row.getLastCellNum() > lastCol) {
lastCol = row.getLastCellNum();
}
sheetTo.setDefaultRowHeight(sheetFrom.getDefaultRowHeight());
}
}
for (int j = 0; j < lastCol; j++) {
sheetTo.setColumnWidth(j, sheetFrom.getColumnWidth(j));
}
//copy contents from source sheet to destination sheet
CellRangeAddress cellAddresses = new CellRangeAddress(0, lastRow, 0, lastCol);
xssfRangeCopier.copyRange(cellAddresses, cellAddresses, true, true);
workbookTo.write(new FileOutputStream(new File("/path/to/worksheetTo.xlsx")));
How to access cell value from pivot table from excel sheet using Apache POI?
I tried using XSSFPivotTable.getPivotTables, but not able to access cell value.
Book1.xlsx is the excel workbook which has a pivot table on sheet Sheet1.
FileInoutStream input = new FileInputStream(new File(Book1.xlsx));
XSSFWorkbook wb = new XSSFWorkbook(input);
XSSFSheet sh = wb.getSheet("Sheet1");
XSSFPivotTable pt = sh.getPivotTables().get(0);
Not able to access the cells in pt pivot table ahead of this.
Below a custom way to access to pivot table header and data , im not sure but i couldnt find a way to access to the data via library , searching on line i read something about, which says it is not supported yet .
Lets see what i did :
Input file :
Tranform letters in numbers for columns:
Map<String, Integer> map = new HashMap<String, Integer>() {
{
int index =1;
for (char ch = 'A'; ch <= 'Z'; ++ch) {
put(String.valueOf(ch), index);
index++;
}
}
};
Getting table object
java.util.List<XSSFPivotTable> l = sh.getPivotTables();
Below the code which will make a trick for the result
XML Debug view :
<xml-fragment name="PivotTable7" cacheId="24" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Values" updatedVersion="6" minRefreshableVersion="3" useAutoFormatting="1" itemPrintTitles="1" createdVersion="6" indent="0" outline="1" outlineData="1" multipleFieldFilters="0" xmlns:main="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<main:location ref="F6:G7" firstHeaderRow="0" firstDataRow="1" firstDataCol="0"/>
<main:pivotFields count="2">
<main:pivotField dataField="1" subtotalTop="0" showAll="0">
<main:items count="2">
<main:item x="0"/>
<main:item t="default"/>
</main:items>
</main:pivotField>
<main:pivotField dataField="1" subtotalTop="0" showAll="0"/>
</main:pivotFields>
<main:rowItems count="1">
<main:i/>
</main:rowItems>
<main:colFields count="1">
<main:field x="-2"/>
</main:colFields>
<main:colItems count="2">
<main:i>
<main:x/>
</main:i>
<main:i i="1">
<main:x v="1"/>
</main:i>
</main:colItems>
<main:dataFields count="2">
<main:dataField name="A" fld="0" baseField="0" baseItem="1"/>
<main:dataField name="B" fld="1" baseField="0" baseItem="1"/>
</main:dataFields>
<main:pivotTableStyleInfo name="PivotStyleLight16" showRowHeaders="1" showColHeaders="1" showRowStripes="0" showColStripes="0" showLastColumn="1"/>
<main:extLst>
<main:ext uri="{962EF5D1-5CA2-4c93-8EF4-DBF5C05439D2}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
<x14:pivotTableDefinition hideValuesRow="1" xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main"/>
</main:ext>
<main:ext uri="{747A6164-185A-40DC-8AA5-F01512510D54}" xmlns:xpdl="http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout">
<xpdl:pivotTableDefinition16 SubtotalsOnTopDefault="0"/>
</main:ext>
</main:extLst>
</xml-fragment>
Looking at ref="F6:G7" i know the range which will make the trick
String range = l.get(0).getCTPivotTableDefinition().getLocation().getRef(); //F6:G7 rows/cols reference - case of our sheet
//determinate range of table
int firstcol = map.get(range.substring(0, 1));
int firstrow = Integer.parseInt(range.substring(1, 2));
int lastcol = map.get(range.substring(3, 4));
int lastrow = Integer.parseInt(range.substring(4, 5));
The complete code :
public static void main(String[] args) {
//tranform letters in numbers for columns
Map<String, Integer> map = new HashMap<String, Integer>() {
{
int index =1;
for (char ch = 'A'; ch <= 'Z'; ++ch) {
put(String.valueOf(ch), index);
index++;
}
}
};
try {
FileInputStream input = new FileInputStream(new File("C:\\Desktop\\ook.xlsx"));
XSSFWorkbook wb = new XSSFWorkbook(input);
XSSFSheet sh = wb.getSheet("Sheet1");
Iterator<Row> rowIterator = sh.iterator();
ArrayList columndata = new ArrayList<>();
java.util.List<XSSFPivotTable> l = sh.getPivotTables();
String range = l.get(0).getCTPivotTableDefinition().getLocation().getRef(); //F6:G7 rows/cols reference - case of our sheet
//determinate range of table
int firstcol = map.get(range.substring(0, 1));
int firstrow = Integer.parseInt(range.substring(1, 2));
int lastcol = map.get(range.substring(3, 4));
int lastrow = Integer.parseInt(range.substring(4, 5));
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
if(checkrightrowcol(row.getRowNum()+1, firstrow, lastrow)){
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
if(checkrightrowcol(cell.getColumnIndex()+1,firstcol,lastcol)){
switch(cell.getCellType()){
case Cell.CELL_TYPE_NUMERIC: // numeric value
System.out.println(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING: // String Value
System.out.println(cell.getStringCellValue());
break;
//..add more
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
Explanation of checkrightrowcol
public static boolean checkrightrowcol(int n , int start, int end){
while (start!=end){
if(n == start || n == end)
return true;
start++;
}
return false;
}
If it returns true im in the table data , in the main i use "+1" because rows and columns indexes start from "0"
Result :
I wants to open xlsx files stored in a folder (one by one) and copy that sheet data column by column (if column name matches) to another file stored in other folder.
Column name mapping data is stored in a sheet.
Suppose sheet 1 contains column name mapping. using this mapping, I want to copy data of each column from each sheet stored in a particular folder to another file stored in another folder.
I tried with this code given below, but I am able to read and write compare headers, but I am unable to read from file one by one.
Code:
public class Read {
public static void main(String[] args) throws IOException{
//Create blank workbook
HSSFWorkbook workbook1 = new HSSFWorkbook();
HSSFSheet spreadsheet = workbook1.createSheet(" Info ");
//Create row object
// HSSFRow row1;
ArrayList<String> lst = new ArrayList<String>();
Read read = new Read();
String x ="Name";
//int columnIndex = 0;
lst = read.extractExcelContentByColumnIndex(x);
//int rowid = 0;
//row1 = spreadsheet.createRow(rowid++);
//Object [] objectArr = empinfo.get(key);
//int cellid = 0;
//int i=0;
for(int RowNum=0; RowNum<lst.size();RowNum++){
HSSFRow row1 = spreadsheet.createRow(RowNum);
for(int ColNum=0; ColNum<1;ColNum++){
HSSFCell cell = row1.createCell(ColNum);
cell.setCellValue(lst.get(RowNum).toString());
}
}
//Write the workbook in file system
FileOutputStream out = new FileOutputStream(new File("Writesheet.xls"));
// System.out.println(lst);
workbook1.write(out);
out.close();
}
public ArrayList<String> extractExcelContentByColumnIndex( String colName)
{
ArrayList<String> columndata = null;
int columnIndex= 0;
int flag=0;
try {
File f = new File("abc.xlsx");
FileInputStream ios = new FileInputStream(f);
XSSFWorkbook workbook = new XSSFWorkbook(ios);
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
columndata = new ArrayList<String>();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell1 = cellIterator.next();
String temp=cell1.getStringCellValue().toString();
//System.out.println(temp);
if(temp.equals(colName)){
columnIndex=cell1.getColumnIndex();
flag=1;
break;
}
}
if(flag==1)
{
flag = 0;
break;
}
}
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
// System.out.println(row.getRowNum());
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
if(row.getRowNum() > 0){
//To filter column headings
if(cell.getColumnIndex() == columnIndex){
// To match column index
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
columndata.add(cell.getNumericCellValue()+"");
break;
case Cell.CELL_TYPE_STRING:
columndata.add(cell.getStringCellValue());
break;
}
}
}
}
}
ios.close();
System.out.println(colName);
for(String ele : columndata){
System.out.println(ele);
}
} catch (Exception e) {
e.printStackTrace();
}
return columndata;
}
}
For reading files one by one you can use java.io.File.listFiles() method.
The method returns the array of abstract pathnames defining the
files in the directory denoted by this abstract pathname.
Sample code
File folder = new File(path / up / to / folder);
File[] listOfFiles = folder.listFiles();
for (File file: listOfFiles) {
if (file.isFile() && file.getName().contains(".xlsx")) {
// if you want to read only xlsx files
// Your logic
}
}
I am reading data from an arraylist and writing this to an excel sheet. The problem is my excel is getting overwritten each time. Here is my code. I can't figure out what is wrong here :( Can someone please help?
public static void main( String[] args ) throws Exception
{
List<String> fileData = new ArrayList<String>();
for(File file:files) {
fileData.add(readFileContents(file.getAbsolutePath()));
}
for(String fileContent:fileData) {
//do some stuff that in turn calls the writeDataToExcel method
}
}
private static void writeDataToExcel(String test,Map<String,String> dataMap,Object object) throws IOException {
File file = new File("input/data.xls");
Map<String,Object[]> data = new LinkedHashMap<String,Object[]>();
XSSFWorkbook workbook = null;
int count = 0;
XSSFSheet sheet = null;
if(file.exists()) {
workbook = new XSSFWorkbook(new FileInputStream(file));
sheet = workbook.getSheet("Data Sheet");
}
else {
workbook = new XSSFWorkbook();
sheet = workbook.createSheet("Data Sheet");
//count = sheet.getLastRowNum();
}
data.put("1", new Object[]{"Id","Name","Field","Description","Value"});
for(Map.Entry<String, String> dataMp:dataMap.entrySet()) {
data.put(Integer.toString(count+2), new Object[]{id,object.getClass().getSimpleName(),dataMp.getKey(),dataMp.getValue(),"null"});
count++;
}
Set<String> keyset = data.keySet();
int rownum = 0;
for (String key : keyset) {
Row row = sheet.createRow(rownum++);
Object [] objArr = data.get(key);
int cellnum = 0;
for (Object obj : objArr) {
Cell cell = row.createCell(cellnum++);
if(obj instanceof String)
cell.setCellValue((String)obj);
}
}
FileOutputStream fis = new FileOutputStream("input/data.xls");
workbook.write(fis);
if(fis!=null)
fis.close();
}
I think problem is at line
int rownum = 0;
this will set rowNUm to zero each time and sheet will be written from zero row
You need to persist this rowNum value if you want to append data in the sheet