Use Java to iterate between given placeholders in Excel - java

Here is an example of what i could like to do:
Is there a way to output all the cells between startprint and end_print, i've got like 3 sheet in excel with same place holder, and i want to view only the data between startprint and endprint, for now all i can do is print out all the 3 sheet with all the content, here is my code:
public class ReadInvoices {
private static final String NAME = "C:\\Users\\........\\excelfile.xlsx";
public static void main(String[] args) {
try {
FileInputStream file = new FileInputStream(new File(NAME));
Workbook workbook = new XSSFWorkbook(file);
DataFormatter dataFormatter = new DataFormatter();
Iterator<Sheet> sheets = workbook.sheetIterator();
while(sheets.hasNext()) {
Sheet sh = sheets.next();
System.out.println("Sheet name is "+sh.getSheetName());
System.out.println("---------");
Iterator<Row> iterator = sh.iterator();
while(iterator.hasNext()) {
Row row = iterator.next();
Iterator<Cell> cellIterator = row.iterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
String cellValue = dataFormatter.formatCellValue(cell);
System.out.print(cellValue+"\t");
}
System.out.println();
}
}
workbook.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
}

I don't have a spreadsheet to test this code.
The processLines method tests for the start print row and the end print row. When we're in between the start print and end print rows, we print the rows.
I'm not sure if this line is correct. I'm trying to get the cell from column A.
String text = row.getColumnObject(0);
Edit: Maybe this will work.
Iterator<Cell> cellIterator = row.iterator();
Cell cell = cellIterator.next();
String text = dataFormatter.formatCellValue(cell);
Here's the example code.
public class ReadInvoices {
private static final String NAME = "C:\\Users\\.......\excelfilename.xlsx";
public static void main(String[] args) {
try {
FileInputStream file = new FileInputStream(new File(NAME));
Workbook workbook = new XSSFWorkbook(file);
DataFormatter dataFormatter = new DataFormatter();
Iterator<Sheet> sheets = workbook.sheetIterator();
while (sheets.hasNext()) {
Sheet sh = sheets.next();
System.out.println("Sheet name is " + sh.getSheetName());
System.out.println("---------");
processLines(dataFormatter, sh);
}
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void processLines(DataFormatter dataFormatter, Sheet sh) {
boolean printLine = false;
Iterator<Row> iterator = sh.iterator();
while (iterator.hasNext()) {
Row row = iterator.next();
Iterator<Cell> cellIterator = row.iterator();
Cell cell = cellIterator.next();
String text = dataFormatter.formatCellValue(cell);
if (printLine && text.equals("End_print")) {
printLine = false;
}
if (printLine) {
printRow(dataFormatter, row);
}
if (!printLine && text.equals("StartPrint")) {
printLine = true;
}
}
}
private static void printRow(DataFormatter dataFormatter, Row row) {
Iterator<Cell> cellIterator = row.iterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
String cellValue = dataFormatter.formatCellValue(cell);
System.out.print(cellValue + "\t");
}
System.out.println();
}
}

Related

Can I traverse through an excel file using Indexes when working with Apache POI?

Please excuse me if I am not clear. English is not my first language.
I'm trying to write a code where I can traverse through the first row of an excel file until I find the column labeled 'Comments'. I want to run some action on the text in that column and then save the result in a new column at the end of the file. Can I traverse the xlsx file in a manner similar to indexes? And if so, how can I jump straight to a cell using that cell's coordinates?
public static void main(String[] args) throws IOException {
File myFile = new File("temp.xlsx");
FileInputStream fis = null;
try {
fis = new FileInputStream(myFile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
#SuppressWarnings("resource")
XSSFWorkbook myWorkBook = new XSSFWorkbook (fis);
XSSFSheet mySheet = myWorkBook.getSheetAt(0);
Iterator<Row> rowIterator = mySheet.iterator();
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
String comment = cell.toString();
if (comment.equals("Comments"))
{
System.out.println("Hello");
}
}
}
}
For the question "Wanted to go to the second column's 3rd row I could use coordinates like (3, 2)?":
Yes this is possible using CellUtil. Advantages over the methods in Sheet and Row are that CellUtil methods are able getting the cell if it exists already or creating the cell if it not already exists. So existing cells will be respected instead simply new creating them and so overwriting them.
Example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellUtil;
import java.util.concurrent.ThreadLocalRandom;
public class CreateExcelCellsByIndex {
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
//put content in R3C2:
Cell cell = CellUtil.getCell(CellUtil.getRow(3-1, sheet), 2-1); //-1 because apache poi's row and cell indexes are 0 based
cell.setCellValue("R3C2");
//put content in 10 random cells:
for (int i = 1; i < 11; i++) {
int r = ThreadLocalRandom.current().nextInt(4, 11);
int c = ThreadLocalRandom.current().nextInt(1, 6);
cell = CellUtil.getCell(CellUtil.getRow(r-1, sheet), c-1);
String cellcontent = "";
if (cell.getCellTypeEnum() == CellType.STRING) {
cellcontent = cell.getStringCellValue() + " ";
}
cell.setCellValue(cellcontent + i + ":R"+r+"C"+c);
}
workbook.write(new FileOutputStream("CreateExcelCellsByIndex.xlsx"));
workbook.close();
}
}
FileInputStream file = new FileInputStream(new File(fileLocation));
Workbook workbook = new XSSFWorkbook(file);
Sheet sheet = workbook.getSheetAt(0);
Map<Integer, List<String>> data = new HashMap<>();
int i = 0;
for (Row row : sheet) {
data.put(i, new ArrayList<String>());
for (Cell cell : row) {
switch (cell.getCellTypeEnum()) {
case STRING: ... break;
case NUMERIC: ... break;
case BOOLEAN: ... break;
case FORMULA: ... break;
default: data.get(new Integer(i)).add(" ");
}
}
i++;
}
I'm not sure what you mean by 2D index, but a Cell knows which column it belongs to so something like this should work:
...
Cell cell = cellIterator.next();
String comment = cell.toString();
int sourceColumnIndex = -1;
if (comment.equals("Comments")) {
System.out.println("Hello");
sourceColumnIndex = cell.getColumnIndex();
}
....
Similarly, define something like int targetColumnIndex to represent the column which will have the result from processing all the cells from the sourceColumnIndex column.

how to write on specific column?

i have an excel file with 3 columns. i already store the "B" columns to array list and check it if the value is duplicate or not. now i have problem to write the "Duplicate" value to "C" columns. how to write on specific columns?
here is my code
FileInputStream file = new FileInputStream(new File(
"file name"));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
ArrayList<String> col = new ArrayList<String>();
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(cell.getColumnIndex()==1) {
col.add(cell.getStringCellValue());
System.out.print(cell.toString());
}
}
System.out.println();
}
for(int a = 0; a < 14; a++) {
if(col.get(a).equals("Order ID")) {
if(col.get(a).equals(col.get(a+1))) {
System.out.println("ROW no "+a+"Double Order");
}
} else {
if(col.get(a).equals(col.get(a+1)) || col.get(a).equals(col.get(a-1))) {
if(col.get(a).trim().length()>0) {
System.out.println("ROW no "+a+"Double Order");
col.add("Double");
}
}
}
}
FileOutputStream fileOut = new FileOutputStream("file name");
workbook.write(fileOut);
fileOut.close();
You do not need to iterate twice to identify and write against duplicate rows separately. You can do it like following:
private static void identifyDuplicateOrders() throws IOException {
FileInputStream file = new FileInputStream(new File("D:\\home\\test_in.xlsx"));
final FileOutputStream fileOut = new FileOutputStream("D:\\home\\test_out.xlsx");
XSSFWorkbook workbook = null;
try {
workbook = new XSSFWorkbook(file);
final XSSFSheet sheet = workbook.getSheetAt(0);
final Iterator<Row> rowIterator = sheet.iterator();
final Set<String> orderIds = new HashSet<String>();
while (rowIterator.hasNext()) {
final Row row = rowIterator.next();
final int rowNumber = row.getRowNum();
// SKIP HEADER
if (rowNumber == 0) {
continue;
}
System.out.print("Row " + rowNumber);
// GET ORDER ID CELL
final Cell cell = row.getCell(1);
if (!orderIds.add(cell.getStringCellValue())) {
// CREATE DOUBLE ORDER CELL
row.createCell(2).setCellValue("Duplicate");
System.out.println(" " + cell.toString() + " is Duplicate.");
} else {
System.out.println(" Order is Unique");
}
}
workbook.write(fileOut);
} finally {
workbook.close();
file.close();
fileOut.close();
}
}
You can write the word Duplicate in a loop iterating rows, you don't need to hold array of values. To check duplicates you can use Set and check if add returns false.
e.g.
public static void main(String... args) throws IOException {
try (FileInputStream file = new FileInputStream(new File(args[0]));
XSSFWorkbook workbook = new XSSFWorkbook(file)) {
Set<String> orders = new HashSet<>(20);
XSSFSheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
// skip header if needed
if (row.getRowNum() == 0) {
continue;
}
// 1 for OrderId as in example
Cell orderCell = row.getCell(1);
if (!orders.add(getValue(orderCell))) {
Cell infoCell = row.getCell(2);
if (infoCell == null) {
infoCell = row.createCell(2);
}
infoCell.setCellValue("Duplicate");
}
}
// write result in new file
workbook.write(new FileOutputStream(new File(args[0] + ".result.xlsx")));
}
}
private static String getValue(Cell orderCell) {
switch (orderCell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
return Double.toString(orderCell.getNumericCellValue());
case Cell.CELL_TYPE_STRING:
return orderCell.getStringCellValue();
}
return null;
}

How do i write list data to existing xlsx file in particular column without overwriting using java

I have two 'xlsx' files 'sss.xlsx' and 'abc.xlsx'.
In 'sss.xlsx' file there are some Headers (columns only, doesn't contain any data) and in 'abc.xlsx' file there is data.
I wants to copy data from 'abc' file to 'sss' file column by column by checking column names. If column name matches then copy that column data to "sss.xlsx"
In same column (keep column as it is given in sss file).
I tried with below code. I am able to write but while writing header gets deleted. I am not getting where I went wrong.
Code:
public class Read {
private static int flag;
public static void main(String[] args) throws IOException{
//Create blank workbook
HSSFWorkbook workbook1 = new HSSFWorkbook();
//Create a blank sheet
HSSFSheet spreadsheet = workbook1.createSheet(
" Info ");
ArrayList<String> lst = new ArrayList<String>();
Read read = new Read();
File f2 = new File("sss.xlsx");
FileInputStream ios2 = new FileInputStream(f2);
XSSFWorkbook workbook2 = new XSSFWorkbook(ios2);
XSSFSheet sheet2 = workbook2.getSheetAt(0);
int noOfColumns = sheet2.getRow(0).getLastCellNum();
System.out.println(noOfColumns);
//String temp2=f.getSheet();
Iterator<Row> rowIterator = sheet2.iterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator <Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell1 = cellIterator.next();
String temp2=cell1.getStringCellValue().toString();
System.out.print(cell1.getStringCellValue() + "\n");
lst = read.extractExcelContentByColumnIndex(temp2);
File f3 = new File("sss.xlsx");
FileInputStream ios = new FileInputStream(f3);
XSSFWorkbook workbook3 = new XSSFWorkbook(ios);
String temp1=f3.getName();
//String colName="Mob No";
XSSFSheet sheet3 = workbook3.getSheetAt(0);
//String temp2=f.getSheet();
int columnIndex1=0;
Iterator<Row> rowIterator3 = sheet3.iterator();
//columndata = new ArrayList<String>();
while (rowIterator3.hasNext()) {
Row row3 = rowIterator3.next();
Iterator<Cell> cellIterator3 = row3.cellIterator();
while (cellIterator3.hasNext()) {
Cell cell3 = cellIterator3.next();
String temp5=cell3.getStringCellValue().toString();
//System.out.println(temp);
if(temp5.equals(temp2)){
columnIndex1 = cell1.getColumnIndex();
System.out.println(columnIndex1);
flag=1;
break;
}
}
if(flag==1)
{
flag = 0;
break;
}
}
while (rowIterator.hasNext()) {
Row row6 = rowIterator.next();
// System.out.println(row.getRowNum());
Iterator<Cell> cellIterator6 = row6.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
if(row.getRowNum() > 0){ //To filter column headings
if(cell.getColumnIndex() == columnIndex1){// To match column index
// }
}
}
}
}
for(int RowNum=0; RowNum<lst.size();RowNum++){
HSSFRow row1 = spreadsheet.createRow(RowNum+1);
HSSFCell cell6 = row1.createCell(columnIndex1);
cell6.setCellValue(lst.get(RowNum).toString());
}
}
//Write the workbook in file system
FileOutputStream out = new FileOutputStream(new File("sss.xlsx"));
// 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);
String temp1=f.getName();
XSSFSheet sheet = workbook.getSheetAt(0);
//String temp2=f.getSheet();
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() > -1){ //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;
}
}
Thanks in advance!

How to get the whole row for a if specific column has a certain text with POI

I need to filter my excel spreadsheet for the word "GHH" anywhere in the text of a cell in a specific column. I have managed to do this by I then need to have returned the whole row that this text is found in. This I can't do as there doesnt seem to be a way of using the getRowIndex method to then display the whole row.
Here is my code:
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream(new File("myfile.xls"));
HSSFWorkbook workBook = new HSSFWorkbook(fis);
HSSFSheet sheet = workBook.getSheetAt(0);
Iterator < Row > rows = sheet.rowIterator();
while (rows.hasNext()) {
HSSFRow row = (HSSFRow) rows.next();
Iterator < Cell > cells = row.cellIterator();
while (cells.hasNext()) {
HSSFCell cell = (HSSFCell) cells.next();
if (cell.toString().contains("GHH")) {
String key = cell.getStringCellValue();
int RI = cell.getRowIndex();
}
}
}
workBook.close();
}
You could try to use a List<HSSFRow> to save filtered rows as bellow:
List<HSSFRow> filteredRows = new ArrayList<HSSFRow>();
Iterator<Row> rows= sheet.rowIterator();
while (rows.hasNext ()){
HSSFRow row = (HSSFRow) rows.next ();
Iterator<Cell> cells = row.cellIterator ();
while (cells.hasNext ()){
HSSFCell cell = (HSSFCell) cells.next ();
if (cell.toString().contains("GHH")) {
String key = cell.getStringCellValue();
int RI=cell.getRowIndex();
filteredRows.add(row);
break;
}
}
// then use filteredRows
You probably want to have two bits of logic, one for handling a "matched" row, one for matching. Something like:
DataFormatter formatter = new DataFormatter();
public void matchingRow(Row row) {
System.out.println("Row " + (row.getRowNum()+1) + " matched:");
for (Cell c : row) {
System.out.println(" " + formatter.formatCellValue(cell));
}
}
public void handleFile(File excel) throws Exception {
Workbook wb = WorkbookFactory.create(excel);
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
boolean matched = false;
for (Cell cell : row) {
if (matched) continue;
if (formatter.formatCellValue(cell).contains("GHH")) {
matchingRow(row);
matched = true;
}
}
}
}
That will check every cell in the first sheet, and if the text of a cell in a row matches GHH will then print out the row's contents. If a row has that in twice, it'll only print it once

Unable to read all the cell values in a row when using Apache POI library

I am facing a problem while iterating all the cells in a row, I am able to read first 4 cells properly rest all coming as null. Any help appreciated
//Below is the code I am using
InputStream is = new FileInputStream(new File(fileName));
Workbook workbook = new XSSFWorkbook(is);
int numberOfSheets = workbook.getNumberOfSheets();
for (int i = 0; i < numberOfSheets; i++) {
Sheet sheet = workbook.getSheetAt(i);
String name = sheet.getSheetName();
if (name.equals(sheetName)) {
Iterator<Row> rowItr = sheet.rowIterator();
while (rowItr.hasNext()) {
Row eachRow = rowItr.next();
QuestionObjBuilder builder = new QuestionObjBuilder();
Iterator<Cell> cellItr = eachRow.cellIterator();
int index = 1;
while (cellItr.hasNext()) {
Cell eachCell = cellItr.next();
int cellType = eachCell.getCellType();
String label = "";
if (cellType == Cell.CELL_TYPE_STRING) {
label = eachCell.getStringCellValue();
} else if (cellType == Cell.CELL_TYPE_NUMERIC) {
int value = (int) eachCell.getNumericCellValue();
label = String.valueOf(value);
}
builder = builder.set(index, label);
index++;
if (index > 10) {
break;
}
}
}
}
}
workbook.close();
If your goal is to read all cells from the excel you can use this code,
FileInputStream fileInputStream = new FileInputStream(fileName);
HSSFWorkbook workbook = new HSSFWorkbook(fileInputStream);
HSSFSheet worksheet = workbook.getSheet(sheetName);
Iterator<Row> it = worksheet.rowIterator();
while(it.hasNext()){
HSSFRow r = (HSSFRow) it.next();
Iterator<Cell> it1=r.cellIterator();
while(it1.hasNext()){
HSSFCell cell = (HSSFCell)it1.next();
System.out.println("Row: "+cell.getRowIndex()+" ,Column: "+cell.getColumnIndex());
System.out.println(cell);
}
System.out.println();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

Categories

Resources