Write contents of excel into a text file - java

I need to read the contents of an excel file and dump the same into a text file. I am able to read the contents from the file.
I created a List excelData = new ArrayList(); which should hold the row data present in the excel sheet. But each column is of a different data type. How do I save the contents into the List ?
List excelData = new ArrayList();
try {
FileInputStream file = new FileInputStream(new File("H:\\Docs\\Medical Data Record\\MedicalRecord2015.xlsx"));
XSSFWorkbook wb = new XSSFWorkbook(file);
XSSFSheet ws = wb.getSheetAt(0);
Iterator<Row> itr = ws.iterator();
while (itr.hasNext()) {
Row row = itr.next();
Iterator<Cell> itrCell = row.cellIterator();
while (itrCell.hasNext()) {
Cell cell = itrCell.next();
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
double val = cell.getNumericCellValue();
break;
case Cell.CELL_TYPE_STRING:
String txtval = cell.getStringCellValue();
break;
}
}
}
Thanks

Seems you need not List, but List<List<Object>> here:
List<List<Object>> excelData = new ArrayList<>();
try {
//...
while (itr.hasNext()) {
Row row = itr.next();
List<Object> dataRow = new ArrayList<>();
excelData.add(dataRow);
Iterator<Cell> itrCell = row.cellIterator();
while (itrCell.hasNext()) {
Cell cell = itrCell.next();
if (cell == null) {
dataRow.add(null);
continue;
}
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
dataRow.add(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
dataRow.add(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN:
dataRow.add(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_BLANK:
dataRow.add("");
break;
default:
dataRow.add(cell);
}
}
}
Now, excelData contains List of rows represented as List<Object>, and can be easily saved to text file row by row. To achieve better consistency, you need also check another types of cell, like Cell.CELL_TYPE_BOOLEAN or null.

Related

Java logic not able to read formula based cell in excel

This is method for reading excel:
#SuppressWarnings("deprecation")
public static void readFromExcel(String file) throws IOException {
workbook = new XSSFWorkbook(file);
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
evaluator.evaluateAll();
XSSFSheet myExcelSheet = workbook.getSheetAt(2);
Iterator<Row> itr = myExcelSheet.iterator();
while (itr.hasNext()) {
Row row = itr.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_FORMULA:
System.out.print("formula:" + cell.getCellFormula() + "\t\t\t");
String value = evaluator.evaluate(cell).getStringValue();
System.out.print(value + "\t\t\t");
break;
case HSSFCell.CELL_TYPE_NUMERIC: // field that represents
// numeric cell type
// getting the value of the cell as a number
System.out.print(cell.getDateCellValue() + "\t\t\t");
break;
case HSSFCell.CELL_TYPE_STRING: // field that represents string
// cell type
// getting the value of the cell as a string
System.out.print(cell.getStringCellValue() + "\t\t\t");
break;
}
}
System.out.println();
}
}
I'm getting below output:
Date ME Balance
formula:'Tab1'!C1 null formula:EOMONTH(A2,0) null formula:'Tab1'!$D$3*1000 null
it's reading formula of the cell but not value.I have tried all methods for FormulaEvaluator. Can anyone please assist on this? I have attached the sample sheet image.SampleScenario.xlsx Tab1.xlsx Tab2.xlsx

Read data from excel and Write to List

I want to get data to List and display it.But out put display 4 times.
My excel file containing 4 data.
I want to get one record. My code is
public static List readDataFromExcel() throws IOException{
String filename = "path";
List sheetData = new ArrayList();
FileInputStream fis = null;
try {
fis = new FileInputStream(filename);
XSSFWorkbook workbook = new XSSFWorkbook(fis);
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
XSSFRow row = (XSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
while (cells.hasNext()) {
XSSFCell cell = (XSSFCell) cells.next();
String value=" ";
switch (cell.getCellType())
{
case Cell.CELL_TYPE_NUMERIC:
value = BigDecimal.valueOf(cell.getNumericCellValue()).toPlainString();
data.add(value);
break;
case Cell.CELL_TYPE_STRING:
value=cell.getStringCellValue();
data.add(value);
break;
case Cell.CELL_TYPE_BLANK:
value = " ".toString();
data.add(value);
break;
case Cell.CELL_TYPE_BOOLEAN:
value = Boolean.valueOf(cell.getBooleanCellValue()).toString();
data.add(value);
break;
}
sheetData.add(data);
}
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return sheetData;
}
Main methods
public static void main(String[] args) throws IOException {
List serverdetailsList = ReadDataFromExcel.readDataFromExcel();
List oneserverdetailsList = new ArrayList();
for (int i = 0; i < serverdetailsList.size(); i++) {
System.out.println(serverdetailsList.get(i));
}
}
Out put image
Excel ScrenShot
I see you are adding the inner ArrayList(data) to the main arrayList (sheetdata) as many as the number of times you find a cell.
The approach should have been
while (rows.hasNext()) {
XSSFRow row = (XSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
while (cells.hasNext()) {
XSSFCell cell = (XSSFCell) cells.next();
String value=" ";
switch (cell.getCellType())
{
case Cell.CELL_TYPE_NUMERIC:
value = BigDecimal.valueOf(cell.getNumericCellValue()).toPlainString();
data.add(value);
break;
case Cell.CELL_TYPE_STRING:
value=cell.getStringCellValue();
data.add(value);
break;
case Cell.CELL_TYPE_BLANK:
value = " ".toString();
data.add(value);
break;
case Cell.CELL_TYPE_BOOLEAN:
value = Boolean.valueOf(cell.getBooleanCellValue()).toString();
data.add(value);
break;
}
//sheetData.add(data);
}
sheetData.add(data);
fis.close();
}
You can use 2 for each loops
for(ArrayList innerList :serverdetailsList)
{for(Object cellData:innerList )
{
if(cellData.toString().equalsIgnoreCase("OS1")){
//Your operation
}
}
}
Hope this is what you are looking for!!

java excel read one column

I have a column (B) that I need to take all the values between B3 and B20
this is my code
try {
OPCPackage fs;
fs = OPCPackage.open(new File(getFilePath()));
XSSFWorkbook wb = new XSSFWorkbook(fs);
XSSFSheet sheet = wb.getSheet("Master column name - Used Car");
XSSFRow row;
CellReference cr = new CellReference("B3");
row = sheet.getRow(4);
System.out.println(row);
but as you see, i am getting one value, i didn't know how to get the values for cells B3 until B20
could you help please
have you tried replacing this line:
CellReference cr = new CellReference("B3");
with:
AreaReference ar = new AreaReference("B3:B20");
i.e.
AreaReference ar = new AreaReference("B3:B20");
for (cr : ar.getAllReferencedCells()) {
System.out.print(cr.formatAsString());
System.out.print(" - ");
}
System.out.println();
To read values of certain column or cell from excel you might try this
public static void readFromExcel2(){
try{
FileInputStream file = new FileInputStream(new File("java_excel.xlsx"));//place path of your excel file
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(1);//which sheet you want to read
Iterator<Row> rowIterator = sheet.iterator();
while(rowIterator.hasNext()){
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext()){
Cell cell = cellIterator.next();
if(cell.getColumnIndex()<2&&(cell.getRowIndex()>=3&&cell.getRowIndex()<=20)) {
{
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
System.out.print((int) cell.getNumericCellValue()+" \t" );
break;
case Cell.CELL_TYPE_BLANK:
System.out.print(" ");
break;
case Cell.CELL_TYPE_STRING: {
System.out.print(cell.getStringCellValue());
}
}
}
}
}
System.out.println(" ");
}
file.close();
}catch (Exception e){
e.printStackTrace();
}
}
}

Read integer from numeric cell using Apache POI in java

I have an application which reads xls sheet using apache poi. When the cell has numeric value, i read it by row.getCell(i).getNumericValue(). But it returns floating point digit. like if the cell value is 1, it returns 1.0. Can i convert it to int ? Any helpwould be appreciated. I tried Integer.parseInt(value)- but it throws NumberFormat exception.Any help is appreciated.Here is the pseudo code:
FileInputStream file = new FileInputStream(new File("C:\\test.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(file);
HSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch(cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
String value= String.valueOf(cell.getNumericCellValue());
int intVal = Integer.parseInt(value)-->>throws Exception
Numbers in Excel are (except for a few edge cases) stored as floating point numbers. Floating point numbers in Java, when formatted as a string, are printed with a trailing decimal point, as you're seeing
Assuming what you really wanted was "give me a string that looks like what Excel shows for this cell", then do not call cell.toString(). This will not give you what you want in most cases
Instead, you need to use the DataFormatter class, which provides methods which read the Excel format rules applied to a cell, then re-creates (as best it can) those in Java
Your code should be:
Workbook wb = WorkbookFactory.create(new File("c:/test.xls");
DataFormatter fmt = new DataFormatter();
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
Cell cell = row.getcell(0, Row.RETURN_BLANK_AS_NULL);
if(cell!=null) {
String value = fmt.formatCellValue(cell);
if (! value.trim().isEmpty()) {
System.out.println("Cell as string is " + value);
}
}
}
You may notice I've also fixed a bunch of other stuff as well....!
// to extract the exact numerical value either integer/double
DataFormatter fmt = new DataFormatter();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
//DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
fetchedRow.add(dateFormat.format(date));
} else {
fetchedRow.add(fmt.formatCellValue(cell));
}
rowEmpty = false;
break;
case STRING:
fetchedRow.add(cell.toString());
rowEmpty = false;
break;
case BOOLEAN:
fetchedRow.add(cell.toString());
rowEmpty = false;
break;
case FORMULA:
fetchedRow.add(Double.toString(cell.getNumericCellValue()));
rowEmpty = false;
break;
case BLANK:
fetchedRow.add("");
break;
}
}
if (!rowEmpty) {
allRows.add(fetchedRow.toArray(new String[0]));
count++;
}
if (count >= limit) {
break;
}
}
return allRows;
}
eaxmple to read limitted no.of rows on and use DataFormatter to give exact numeric value either integer/ double value. This will work.
Someone might find this hack useful:
cell.setCellType(CellType.STRING);
int value = Integer.parseInt(cell.getStringCellValue());
Remember you alter the cell type here, so be sure this does not cause any side effect. In a single-threaded app you can just read the type before and restore it after.
You can read int value as string apache poi using simple steps
First count rows in sheets using below method
private int getRowCount(Sheet currentSheet) {
int rowCount = 0;
Iterator<Row> rowIterator = currentSheet.iterator();
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
if(row == null || row.getCell(0) == null || row.getCell(0).getStringCellValue().trim().equals("") || row.getCell(0).toString().trim().equals("")
|| row.getCell(0).getCellType()==Cell.CELL_TYPE_BLANK){
break;
}
else
rowCount=rowCount + 1;
}
return rowCount;
}
Then use below code in your method
Workbook workbook = WorkbookFactory.create(new File("c:/test.xls");
Sheet marksSheet = (Sheet) workbook.getSheet("Sheet1");
int zoneLastCount = 0;
if(marksSheet !=null ) {
zoneLastCount = getRowCount(marksSheet);
}
int zone = zoneLastCount-1;
int column=1
for(int i = 0; i < zone; i++) {
Row currentrow = marksSheet.getRow(i);
double year = Double.parseDouble(currentrow.getCell(columnno).toString());
int year1 = (int)year;
String str = String.valueOf(year1);
}
You can just type cast float to int like :
String value = String.valueOf((int)cell.getNumericCellValue());
Cell cell = row.getCell(cellCpt);
String cellContent = "";
if (cell != null) {
cell.setCellType(CellType.STRING);
cellContent = fmt.formatCellValue(cell);
}
Try doing the following (to obtain a long):
long value = (long) currentCell.getNumericValue();
Below implementation worked for me:
private Object getValue(Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
return cell.getStringCellValue();
case Cell.CELL_TYPE_NUMERIC:
return String.valueOf((int) cell.getNumericCellValue());
case Cell.CELL_TYPE_BOOLEAN:
return cell.getBooleanCellValue();
case Cell.CELL_TYPE_ERROR:
return cell.getErrorCellValue();
case Cell.CELL_TYPE_FORMULA:
return cell.getCellFormula();
case Cell.CELL_TYPE_BLANK:
return null;
}
return null;
}

Passing a list of servlet values

Using apache poi, I am reading the first row values of an excel file like this
try
{
FileInputStream file = new FileInputStream(uploadedFile);
XSSFWorkbook workbook = new XSSFWorkbook(file);
for (int i =0; i < workbook.getNumberOfSheets(); i++)
{
XSSFSheet sheet = workbook.getSheetAt(i);
Iterator<Row> rowIterator = sheet.iterator();
String SheetName = "<span class='blue'><b>" +sheet.getSheetName()+ "<b></span><br>";
request.setAttribute("SheetName", SheetName);
Row row = rowIterator.next();
if(row.getRowNum() == 0)
{
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext())
{
Cell cell1 = cellIterator.next();
switch(cell1.getCellType())
{
case Cell.CELL_TYPE_STRING:
String strval = cell1.getStringCellValue();
request.setAttribute("Values2", strval);
break;
}
}
}
}
file.close();
}catch(NoSuchElementException e)
{}
Now, I want to pass a list of values the strval is only sending one value, how do I sent many values??
How to send an array of items to my jsp page?
You can send List as an attribute value. For example:
List<String> cellValues = new ArrayList<String>();
while(cellIterator.hasNext())
{
Cell cell1 = cellIterator.next();
switch(cell1.getCellType())
{
case Cell.CELL_TYPE_STRING:
String strval = cell1.getStringCellValue();
cellValues.add(strval);
break;
}
}
}
}
request.settAttribute("Values2", cellValues);

Categories