Can somebody please explain about the Missing cell policy of Apache POI ? What are exactly missing cells ? I didn't find the Apache POI docs link to be self-explanatory on what exactly are missing cells.
Did you read the Apache POI Excel Busy Developer's Guide?
In some cases, when iterating, you need full control over how missing or blank rows and cells are treated, and you need to ensure you visit every cell and not just those defined in the file. (The CellIterator will only return the cells defined in the file, which is largely those with values or stylings, but it depends on Excel).
In cases such as these, you should fetch the first and last column information for a row, then call getCell(int, MissingCellPolicy) to fetch the cell. Use a MissingCellPolicy to control how blank or null cells are handled.
If you're iterating over columns in a row, some cells that are blank may not even exist, which may causing unsuspecting code to throw a NullPointerException. A MissingCellPolicy, when passed to getCell, guides and simplifies code that tells Apache POI how to handle these kinds of cells.
CREATE_NULL_AS_BLANK - If the Cell returned doesn't exist, instead of returning null, create a new Cell with a cell type of "blank". This can help avoid NullPointerExceptions conveniently.
RETURN_BLANK_AS_NULL - Even if the cell exists but has a cell type of "blank", return null. This can allow you ignore blank cells that do exist easily.
RETURN_NULL_AND_BLANK - Don't modify the existing structure; return null for cells that don't really exist and return the blank Cell if it exists but its cell type is blank. This is the behavior of the getCell overload that doesn't take a MissingCellPolicy.
I'm using the code in java as below, it's working good for me :) hope it helps.
ArrayList<ArrayList<String>> cellArrayListHolder = new ArrayList<ArrayList<String>>();
FileInputStream excelFile = new FileInputStream(new File(fileName));
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet datatypeSheet = workbook.getSheetAt(0);
Iterator<Row> iterator = datatypeSheet.iterator();
while (iterator.hasNext())
{
ArrayList<String> cellStoreArrayList = new ArrayList<String>();
Row currentRow = iterator.next();
Iterator<Cell> cellIterator = currentRow.iterator();
int column_counting = 0;
int patched_count = 0;
while (cellIterator.hasNext() && column_counting < read_column_size) {
column_counting ++;
Cell currentCell = cellIterator.next();
int missed_column = 1 - column_counting + currentCell.getColumnIndex() - patched_count;
for(int i=0; i<missed_column; i++){
cellStoreArrayList.add("");
patched_count++;
}
switch (currentCell.getCellType()){
case Cell.CELL_TYPE_STRING:
cellStoreArrayList.add(String.valueOf(currentCell).trim());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(currentCell)) {
DateFormat db_df = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy");
cellStoreArrayList.add(db_df.format(currentCell.getDateCellValue()));
} else {
cellStoreArrayList.add(String.valueOf(currentCell.getNumericCellValue()));
}
break;
case Cell.CELL_TYPE_BOOLEAN:
cellStoreArrayList.add(String.valueOf(currentCell.getBooleanCellValue()));
break;
default:
cellStoreArrayList.add("");
break;
}
}
cellArrayListHolder.add(cellStoreArrayList);
}
Related
I am reading cells from an Excel spreadsheet. I am reading the first cell in each row, and comparing them to a String object that I have passed into the function. The function correctly iterates over all rows and accesses the first cell in each row, but when comparing them to the String object parameter, the IF statement does not execute, despite both the value obtained from the cell and the String parameter printing the same thing. I have used '==' operators, as well as .equals() but nothing seems to let the IF statement execute.
public static ArrayList<Integer> returnCurrency(String currency, String fileName) throws IOException
{
FileInputStream excelFile = new FileInputStream(newFile(fileName));
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet sheet = workbook.getSheetAt(0);
Iterator<Row> iterator = sheet.iterator();
ArrayList<Double> currencyRateArray = new ArrayList<Double>();
for( int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++)
{
Row row = sheet.getRow(rowNum);
Cell tempCell = row.getCell(0);
System.out.printf("temp cell has value of:%s\n",tempCell.getStringCellValue());
System.out.printf("currency variable is: %s\n", currency);
if(currency.equals(tempCellString))
{
System.out.println("Found the currency\n");
}
}
}
When I pass the parameter String as "USD", both print statements print "USD", but it will never print "Found the currency" as that IF statement does not execute. Any help would be appreciated :)
Found the answer - the cell in the database had the value 'USD ' instead of 'USD'.
I am trying to parse an excel file where i have to read the header and the data Parallelly.I need a check ,while parsing the header if blank cell is found the i have to immediately skip the cell and pick up the next value but this can not be done in another iteration.Here i have tried but in my code i am getting no value in the skipped cell ,
while (cellIterator.hasNext() && cellIteratorTotal.hasNext()) {
cellCount++;
Cell currentCell = cellIterator.next();
Cell currentCellTotal = cellIteratorTotal.next();
currentRow = sheet.getRow(currentRowTotal.getRowNum() + 1); // here i am trying to hold the current row value
String cellValue = excelManager.evalCell(currentCell);
String cellValueTotal = excelManager.evalCell(currentCellTotal);
if(currentRow!=null) {
String value = currentRow.getCell(currentCellTotal.getColumnIndex(), Row.CREATE_NULL_AS_BLANK).getStringCellValue(); // here i am trying to get the next cell value
}
Can anyone help me with the correct approach please, Thanks in advance
Below code can help you. Please check.
if (cell == null || c.getCellType() == Cell.CELL_TYPE_BLANK) {
}
In Microsoft Office Excel,I set this formula in a cell.=YEAR("2017-01-01").The result is 2017.
In apache-poi,I do the same.
cell.setCellFormula("YEAR(\"2017-01-01\")");
But I get a wrong result.
#VALUE!
How to get the correct result?
Code
HSSFWorkbook hssfworkbook = new HSSFWorkbook();
HSSFSheet sheet = hssfworkbook.createSheet("Sheet1");
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellFormula("YEAR(\"2017-01-01\")");
CreationHelper creationHelper = hssfworkbook.getCreationHelper();
FormulaEvaluator evaluator = creationHelper.createFormulaEvaluator();
System.out.println(evaluator.evaluate(cell));
Console
org.apache.poi.ss.usermodel.CellValue [#VALUE!]
use apache-poi 3.16
From Interface FormulaEvaluator docs
If cell contains formula, it evaluates the formula, and puts the formula result back into the cell, in place of the old formula. Else if cell does not contain formula, this method leaves the cell unchanged. Note that the same instance of Cell is returned to allow chained calls like:
int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
if (cell.getCellType() == Cell.CELL_TYPE_FORMULA)
{
cell = evaluator.evaluateInCell(cell);
}
I have a worksheet with data in it, I am trying to create a pivot table with report filter. I want to set default value to the report filter.
pivotTable.addReportFilter(13);
column contains 0's and 1's, I would like to set 0 as my default value in the report filter.
At first this question is not answerable in that general context as it is asked now. Creating pivot tables using apache poi is in beta state until now. So we need not only the high level apache poi API but also the underlying low level objects. And we need exactly to know which kind of data shall be in the pivot table. To be general able creating pivot tables from all kind of data, as Excel can do, there is much more effort necessary. Microsoft has programmed this in decades with big teams of programmers. From this apache poi is far away.
Until now apache poi adds as much pivot field items of type "default" (<item t="default"/>) as rows are present in the data range, if the pivot fields where used as axis fields.
This is because they don't want to have a look at the data, and so they are assuming as much different values as rows where in the data.
This is fine because Excel will rebuild its pivot cache while opening. But if we want preselect items, then this is not fine. Then we must know what items there are that can be preselected.
So we need at least as much items, as we want preselecting, as numbered items: <item x="0"/><item x="1"/><item x="2"/>...
And we need to build a cache definition which has shared elements for those items.
Example:
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import java.util.Random;
import java.io.*;
class PivotTableTest4 {
private static void setCellData(Sheet sheet) {
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("Name");
cell = row.createCell(1);
cell.setCellValue("Value1");
cell = row.createCell(2);
cell.setCellValue("Value2");
cell = row.createCell(3);
cell.setCellValue("City");
for (int r = 1; r < 15; r++) {
row = sheet.createRow(r);
cell = row.createCell(0);
cell.setCellValue("Name " + ((r-1) % 4 + 1));
cell = row.createCell(1);
cell.setCellValue(r * new java.util.Random().nextDouble());
cell = row.createCell(2);
cell.setCellValue(r * new java.util.Random().nextDouble());
cell = row.createCell(3);
cell.setCellValue("City " + ((r-1) % 3 + 1));
}
}
public static void main(String[] args) {
try {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
//Create some data to build the pivot table on
setCellData(sheet);
XSSFPivotTable pivotTable = sheet.createPivotTable(
new AreaReference(new CellReference("A1"), new CellReference("D15")), new CellReference("H5"));
//Configure the pivot table
//Use first column as row label
pivotTable.addRowLabel(0);
//Sum up the second column
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1);
//Avarage the third column
pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 2);
//Add fourth column as page filter
pivotTable.addReportFilter(3);
/*
Apache poi adds 15 pivot field items of type "default" (<item t="default"/>) here.
This is because there are 15 rows (A1:D15) and, because they don't have a look at the data,
they are assuming max 15 different values. This is fine because Excel will rebuild its pivot cache while opening.
But if we want preselect items, then this is not fine. Then we must know what items there are that can be preselected.
So we need at least as much items as we want preselecting as numbered items: <item x="0"/><item x="1"/><item x="2"/>...
And we must build a cache definition which has shared elements for those items.
*/
for (int i = 0; i < 3; i++) {
//take the first 3 items as numbered items: <item x="0"/><item x="1"/><item x="2"/>
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(i).unsetT();
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(i).setX((long)i);
//build a cache definition which has shared elements for those items
//<sharedItems><s v="City 1"/><s v="City 2"/><s v="City 3"/></sharedItems>
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(3).getSharedItems().addNewS().setV("City " + (i+1));
}
//Now we can predefinite a page filter. Second item, which is "City 2", in this case.
pivotTable.getCTPivotTableDefinition().getPageFields().getPageFieldArray(0).setItem(1);
FileOutputStream fileOut = new FileOutputStream("PivotTableTest4.xlsx");
wb.write(fileOut);
fileOut.close();
wb.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This needs the full jar of all of the schemas, ooxml-schemas-1.3.jar, as mentioned in the FAQ.
I am trying to read an Excel file and get the value of a particular column.
I used row.getCell(0),toString() to get the first column value. Instead of using the column index, I wanted to use the Column Name. How can I do this ? getCell allows only the index to be entered. how can I pass the column name. Something like row.getCell(COLUMN_NAME)
Looks like you are utilizing apache-poi for your purpose. You can use a util class CellReference, sample usage below:
XSSFSheet ws = wb.getSheet("Sheet1");
CellReference cellReference = new CellReference("A11");
XSSFRow row = sheet.getRow(cellReference.getRow());
if (row != null) {
XSSFCell cell = row.getCell(cellReference.getCol());
}