Write sheet data from workbook n number of times - java

I am reading data from excel workbook with multiple sheets.
I am able to read data from multiple sheets, but i am trying to print particular sheet data "n" number of times.
For Example : My workbook contains 10 sheets numbered from 1-10, and i want to print "sheet 1" data 3 times, "Sheet 2" data 3 times..
Similarly, i will be printing every sheet data "n" number of times.
Variables: name-contains sheet names,occurances-contains number of times sheet data to be printed.
String[] name = { "a", "b", "c" };
int[] occurances = { 2, 3, 4 };
int c1 = 0;
int c2 = 0;
Excel file Reading code :
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
Sheet datatypeSheet = workbook.getSheetAt(i);
Iterator<Row> iterator = datatypeSheet.iterator();
if (datatypeSheet.getSheetName().equals(name[c1])) {
c1++;
for (int d = 0; d < occurances[c2]; d++) {
c2++;
while (iterator.hasNext()) {
Row currentRow = iterator.next();
Iterator<Cell> cellIterator = currentRow.iterator();
while (cellIterator.hasNext()) {
Cell currentCell = cellIterator.next();
if (currentCell.getCellTypeEnum() == CellType.STRING) {
System.out.print(currentCell
.getStringCellValue() + "--");
}
}
System.out.println();
}
}
}
}
I tried, but am getting all sheet data printed for 1 time.
Please HELP!

There are a couple of problems with your code. Best way to understand why your code is not working is debugging (either through IDE or through logging).
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
// if your sheets are not in 'a', 'b', 'c' order this code
// will not work. think why
Sheet datatypeSheet = workbook.getSheetAt(i);
if (datatypeSheet.getSheetName().equals(name[c1])) {
c1++;
// you need this variable to be fixed for your loop
int occurancesForSheet = occurances[c2++];
for (int d = 0; d < occurancesForSheet; d++) {
// you need a new iterator each time
Iterator<Row> iterator = datatypeSheet.iterator();
while (iterator.hasNext()) {
Row currentRow = iterator.next();
Iterator<Cell> cellIterator = currentRow.iterator();
while (cellIterator.hasNext()) {
Cell currentCell = cellIterator.next();
if (currentCell.getCellTypeEnum() == CellType.STRING) {
System.out.print(currentCell
.getStringCellValue() + "--");
}
}
System.out.println();
}
}
}
}

Related

Arraylist and Iteration

I have an Excel File with Values in the Ranges C17:C40, D17:D40 and E17:E40.
Now I read with Apache Poi the first Range with a for each loop. My Problem is I want to include a Code something like this:
If C17 is empty go to the next range (in this case D17) and check if D17 ist empty. If not read every Cell from the List and put it into a new Array list.
I hope some of you understand me. Here is my code:
public static ArrayList<String> list = new ArrayList<>();
public static ArrayList<String> ForEachLoop() throws EncryptedDocumentException, FileNotFoundException, IOException {
Workbook readWorkbook = WorkbookFactory.create(new FileInputStream(FileChooser.FileChoose()) );
Sheet sheet = readWorkbook.getSheetAt(4);
DataFormatter dataFormatter = new DataFormatter();
String cellValue = null;
for (int i = 16; i < 40; i++) { //Statt 20 soll hier 40
Row row = sheet.getRow(i);
if(row == null) {
continue;
}
for (int j = 2; j < 4; j++) {
Cell cell = row.getCell(j);
list.add(dataFormatter.formatCellValue(cell));
if(cell == null) {
continue;
}
// cellValue = dataFormatter.formatCellValue(cell);
// System.out.print(cellValue + "\n");
}
}
return list;
}

apache poi indexoutofbound exception

Excel File (test1.xlsx)
Name Gender Age Resign Date
Ali M 20
Abu M 25
Siti F 30
Code
public class ReadExcel {
public static ArrayList<String> record;
public static void main(String[] args) throws FileNotFoundException, IOException {
//---Read file---
FileInputStream in = new FileInputStream("test1.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(in);
XSSFSheet spreadsheet = workbook.getSheetAt(0);
XSSFRow row;
Cell cell;
Iterator<Row> rowIterator = spreadsheet.iterator();
while(rowIterator.hasNext()){
record = new ArrayList<String>();
row = (XSSFRow)rowIterator.next();
if(row.getRowNum()==0) {
continue;
}
for(int k = 0; k < row.getLastCellNum();k++){
cell = row.getCell(k, Row.CREATE_NULL_AS_BLANK);
}
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext()){
cell = cellIterator.next();
cell.setCellType(Cell.CELL_TYPE_STRING);
switch(cell.getCellType()){
case Cell.CELL_TYPE_STRING:
record.add(cell.getStringCellValue());
System.out.print(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
Double value = cell.getNumericCellValue();
Long longValue = value.longValue();
record.add(Double.toString(cell.getNumericCellValue()));
System.out.print(cell.getNumericCellValue());
break;
}
}
System.out.println();
String name = record.get(0);
String gender = record.get(1);
String age = record.get(2);
String dateLeave = record.get(3); //[ERROR]
System.out.println(name + gender + age + dateLeave);
}
}
}
However, from my above program, I get this exception:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at ibguobform.ReadExcel.main(ReadExcel.java:66)
Java Result: 1
What is the errors that I made?
Your code is trying to reference the fourth element of a collection that has only three elements:
record.get(3)
Since there's only three elements, trying to reference the fourth one produces an error.
Why are there only three elements?
Well, look at the data:
Ali M 20
Abu M 25
Siti F 30
Three elements per line.
What appears to be happening is the code is dynamically checking for the last "element":
for(int k = 0; k < row.getLastCellNum(); k++){
cell = row.getCell(k, Row.CREATE_NULL_AS_BLANK);
}
It would seem that row.getLastCellNum() is telling the code that there are only three cells. (Because, well, there are only three cells with data in them.) If the fourth cell is valid even when there's no data, explicitly note that in the code by always using four elements:
for(int k = 0; k < 4; k++){
cell = row.getCell(k, Row.CREATE_NULL_AS_BLANK);
}

Creating multiple sheets using Apache poi and servlets

When i am creating multiple sheets using Apache poi and servlets. It is creating the sheet but not writing the data to file. I am trying to write the first 1000 records to sheet1 and next 1000 to sheet2 through below code, but not working
private void writeDataToExcelFile(String string,
ArrayList<ArrayList<String>> excelData, OutputStream outputStream) {
HSSFWorkbook myWorkBook = new HSSFWorkbook();
String sheetName = "";
sheetName = "Document-" + 0;
HSSFSheet mySheet = myWorkBook.createSheet();
HSSFRow myRow = null;
HSSFCell myCell = null;
for (int rowNum = 0; rowNum < excelData.size(); rowNum++) {
ArrayList<String> rowData = excelData.get(rowNum);
if(rowNum>0 && rowNum%1000 == 0)
{
sheetName = "Document-" + (rowNum/1000);
mySheet = myWorkBook.createSheet();
}
myRow = mySheet.createRow(rowNum);
for (int cellNum = 0; cellNum < rowData.size(); cellNum++) {
myCell = myRow.createCell(cellNum);
myCell.setCellValue(rowData.get(cellNum));
}
}
System.out.println("Last row:" + mySheet.getLastRowNum());
System.out.println("Row number:" + mySheet.rowIterator().next().getRowNum());
try {
myWorkBook.write(outputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
What is wrong with my logic.Please do the needful help.
Thanks
When you loop through the dataset, you are wanting to split at row 1000 to start a new sheet, which is fine, however when you start the new sheet, the next row you create is row 1001 (the outer loop index variable)
myRow = mySheet.createRow(rowNum);
To get the effect you wish, change the loop to be something like this:
int currentRow = 0;
for (int rowNum = 0; rowNum < excelData.size(); rowNum++)
{
ArrayList<String> rowData = excelData.get(rowNum);
if(currentRow == 1000)
{
sheetName = "Document-" + (rowNum/1000);
mySheet = myWorkBook.createSheet();
currentRow = 0;
}
myRow = mySheet.createRow(currentRow);
for (int cellNum = 0; cellNum < rowData.size(); cellNum++)
{
myCell = myRow.createCell(cellNum);
myCell.setCellValue(rowData.get(cellNum));
}
currentRow++;
}
I haven't compiled this, so I don't know if it'll work right away, but it should point you in the right direction.
HTH
Edit
Thinking about this further, you could get the same effect from making a 1 line change to the original application (albeit losing a little bit of clarity):
myRow = mySheet.createRow(rowNum%1000);

How deal with blank cells in excel files java

I am making a program where I am reading data from excel files and store them in tables. I have made the program using Apache POI and works fine. But when files have blank cells as the one here I have some problems. The program skip the blanks and read the next data. Could anyone help me how I would do it? I know that there are several posts for this issue but I have not found something useful for me.
The code for reading the data from excel file is the below. As you can see I have 3 types of data. How i would give the option for BLANK CELL?
// Create an ArrayList to store the data read from excel sheet.
List sheetData = new ArrayList();
FileInputStream fis = null;
try {
// Create a FileInputStream that will be use to read the
// excel file.
fis = new FileInputStream(strfullPath);
// Create an excel workbook from the file system
HSSFWorkbook workbook = new HSSFWorkbook(fis);
// Get the first sheet on the workbook.
HSSFSheet sheet = workbook.getSheetAt(0);
// store the data read on an ArrayList so that we can printed the
// content of the excel to the console.
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
HSSFRow row = (HSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
while (cells.hasNext()) {
HSSFCell cell = (HSSFCell) cells.next();
data.add(cell);
}
sheetData.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
fis.close();
}
}
showExcelData(sheetData);
}
private static void showExcelData(List sheetData) {
// LinkedHashMap<String, String> tableFields = new LinkedHashMap();
for (int i = 0; i < sheetData.size(); i++) {
List list = (List) sheetData.get(i);
for (int j = 0; j < list.size(); j++) {
Cell cell = (Cell) list.get(j);
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
System.out.print(cell.getNumericCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
System.out.print(cell.getRichStringCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
System.out.print(cell.getBooleanCellValue());
} else if (cell.getCellType()== Cell.CELL_TYPE_BLANK ){
System.out.print(cell.toString());
}
if (j < list.size() - 1) {
System.out.print(", ");
}
}
System.out.println("");
}
}
}
Also I have read about workbook.setMissingCellPolicy(HSSFRow.RETURN_NULL_AND_BLANK);. Could this help me with my problem?
int maxNumOfCells = sheet.getRow(0).getLastCellNum(); // The the maximum number of columns
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
HSSFRow row = (HSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
for( int cellCounter = 0
; cellCounter < maxNumOfCells
; cellCounter ++){ // Loop through cells
HSSFCell cell;
if( row.getCell(cellCounter ) == null ){
cell = row.createCell(cellCounter);
} else {
cell = row.getCell(cellCounter);
}
data.add(cell);
}
sheetData.add(data);
YOUR METHOD:
public static void showExcelData(List sheetData) {
// LinkedHashMap<String, String> tableFields = new LinkedHashMap();
for (int i = 0; i < sheetData.size(); i++) {
List list = (List) sheetData.get(i);
for (int j = 0; j < list.size(); j++) {
Cell cell = (Cell) list.get(j);
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
System.out.print(cell.getNumericCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
System.out.print(cell.getRichStringCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
System.out.print(cell.getBooleanCellValue());
} else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
System.out.print("THIS IS BLANK");
}
if (j < list.size() - 1) {
System.out.print(", ");
}
}
System.out.println("");
}
}
Explanation:
int maxNumOfCells = sheet.getRow(0).getLastCellNum(); - This line will make sure that you were able to get the number of columns. Using the Row's method .getLastCellNum() on the next rows will result to unexpected number. Example on your on row 3 of your spreadsheet, the method will return 2 since the next value is null.
for( int cellCounter = 0
; cellCounter < maxNumOfCells
; cellCounter ++){ // Loop through cells
HSSFCell cell;
if( row.getCell(cellCounter ) == null ){
cell = row.createCell(cellCounter);
} else {
cell = row.getCell(cellCounter);
}
data.add(cell);
}
Looping through the cells. From cell 0 (Base 0) to the last cell number. If the cell was found null, basically, it would create the cell with a blank value. Lastly, adding the cell to your List.
Another solution if you don't know the size of your spreadsheet is to loop through row and column and compare the index of row and column with the previous one you parsed. If the increment is more than one you will create the missing intermediate cells.

POI Appending .0 while reading numeric data from excel

I am using POI HSSF to read excel data and I am using JUnit to check the data against database proc RefCursor.
The Junit test fails as the numeric data from the Refcursor for example 100 are compared against the data in the excel sheet 100 but it fails as the POI reads it as 100.0.
InputStream fileInputStream = Testdb.class.getClassLoader().getResourceAsStream(fileName);
//retrieve number of columns and rows
int numRows=0, numCols=0, i, j, minColIndex=0, maxColIndex=0;
POIFSFileSystem fsFileSystem = new POIFSFileSystem(fileInputStream);
HSSFWorkbook workBook = new HSSFWorkbook(fsFileSystem);
HSSFSheet hssfSheet = workBook.getSheetAt(0);
Iterator rowIterator = hssfSheet.rowIterator();
while (rowIterator.hasNext())
{
numRows++;
HSSFRow hssfRow = (HSSFRow) rowIterator.next();
Iterator iterator = hssfRow.cellIterator();
List cellTempList = new ArrayList();
if (numRows == 1)
{
minColIndex = hssfRow.getFirstCellNum();
maxColIndex = hssfRow.getLastCellNum();
numCols = maxColIndex;
}
for(int colIndex = minColIndex; colIndex < maxColIndex; colIndex++)
{
HSSFCell hssfCell = hssfRow.getCell(colIndex);
cellTempList.add(hssfCell);
}
cellDataList.add(cellTempList);
}
String expected[][] = new String[numRows][numCols];
String[] tableColumns = new String[numCols];
System.out.println("Rows : " + numRows + "Columns : " + numCols);
System.out.println("Min Col Index : " +minColIndex + "Max Col Index : " + maxColIndex);
for (i=0; i<numRows; i++)
{
List cellTempList = (List) cellDataList.get(i);
for (j=0; j < numCols; j++)
{
HSSFCell hssfCell = (HSSFCell) cellTempList.get(j);
if (i == 0)
{
tableColumns[j] = hssfCell.toString();
System.out.print(tableColumns[j] + "\t");
}
else
{
if(hssfCell != null)
{
expected[i-1][j] = hssfCell.toString();
}
else
{
expected[i-1][j] = null;
}
System.out.print(expected[i-1][j] + "\t");
}
}
System.out.println();
}
This is a generic framework program which I am building so the framework should be intelligent enough to disregard the ".0".
Any inputs on how to resolve this?
This is virtually identical to a number of other questions here, such as returning decimal instead of string (POI jar)
The answer is the same as the one I gave here:
POI is giving you the exact value that Excel has stored in the File. Generally, if you write a number in an Excel cell, Excel will store that as a number with formatting. POI provides support to do that formatting for you if you want it (most people don't - they want the numbers as numbers so they can use them)
The class you're looking for is DataFormatter. Your code would be something like
DataFormatter fmt = new DataFormatter();
for (Row r : sheet) {
for (Cell c : r) {
CellReference cr = new CellRefence(c);
System.out.println("Cell " + cr.formatAsString() + " is " +
fmt.formatCellValue(c) );
}
}
Hi my solution was just to put the symbol:
'
in front of every number. Then the number is processed as text.
After you do that you would see little green triangle and warning:
For me this is not a problem, because it works.

Categories

Resources