Apache POI formatting double numbers in Excel files - java

I am using apache-poi for creating some reports. I have an issue with the decimal separator. Right now I have the following displayed in the excel file:
For 111.2343 -> 111.23
For 111.23 -> 111.23
For 111.2 -> 111.2
For 111 -> 111. (see the dot at the end)
The problem is with 111 number. I don't want to see the trailing dot (or comma, depending on language).
Here is my current code to format the cells. Can this be achieved using apache-poi?
Thank you,
Iulian
PS: Is there a way to use java.text.Format in poi? I see this has DecimalFormat setDecimalSeparatorAlwaysShown method which does what I want.
private void createColumnStyle(XSSFSheet sheet, int maxRows,int col)
{
XSSFWorkbook wb = sheet.getWorkbook();
XSSFFont font = wb.createFont();
font.setFontHeightInPoints((short)10);
font.setFontName("Calibri");
XSSFCellStyle colStyle = wb.createCellStyle();
colStyle.setFont(font);
colStyle.setAlignment(HorizontalAlignment.RIGHT);
colStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
colStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
colStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
colStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
CreationHelper createHelper = wb.getCreationHelper();
colStyle.setDataFormat(createHelper.createDataFormat().getFormat("#,##0.##"));
for (int i=3; i<maxRows; i++ )
{
XSSFCell cell = sheet.getRow(i).createCell(col);
cell.setCellStyle(colStyle);
}
}

Using DecimalFormat works fine for all the cases:
DecimalFormat dec = new DecimalFormat("#.00");
double cellValue = Double.valueOf(dec.format(111));
XSSFCell cell = sheet.createRow(0).createCell(0);
cell.setCellValue(cellValue);
this set the cell value to 111 only.

Related

Set Cellstyle of a org.apache.poi.ss.usermodel.Cell to boolean

I would like to write a boolean-value into an excel-cell, but instead of setting the cellStyle to "logic" the cellStyle will become "number" instead.
private void writeToDocument(XSSFWorkbook workbook) {
Sheet sheet = workbook.createSheet("testSheet");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue(true);
}
I already tryied
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setDataFormat([short s]);
cell.setCellStyle(cellStyle);
but no short s between 0 and 49 did the job.
When appropriate overloaded version of setCellValue is used the cell types will be assigned automatically, for example
cell.setCellValue(true);
System.out.println(cell.getCellType());
prints BOOLEAN
Checked on org.apache.poi:poi:4.1.1
You can use the following:
Row row = sheet.createRow(lineNumber);
Cell cell = row.createCell(1, CellType.BOOLEAN);
This will create a cell styled to persist boolean.
Use below code for Boolean value
private void writeToDocument(XSSFWorkbook workbook) {
Sheet sheet = workbook.createSheet("testSheet");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellType(HSSFCell.CELL_TYPE_BOOLEAN);
cell.setCellValue((Boolean) true);
}
This is how to customize a date, potentially you may try it with boolean
final XSSFCellStyle date = sheet.getWorkbook().createCellStyle();
date.setDataFormat(
sheet.getWorkbook()
.getCreationHelper()
.createDataFormat()
.getFormat(pattern)
);
cell = row.createCell(index);
cell.setCellStyle(date);

I am getting Null Pointer Exception when Accessing the Cell Which has the Value?

I am using the Apache POI Library to get the data from EXCEL Sheet. I have attached the EXCEL Sheet which has the yellow part highlighted. I am trying to extract the all the data from EXCEL Sheet but I am not getting the data from the highlighted part. It gives the null pointer exception when trying to access these cells.
SAMPLE Document :
Document
SAMPLE Code.
FileInputStream inputStream = new FileInputStream(file);
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = workbook.getSheetAt(0);
Iterator<Row> iterator = firstSheet.iterator();
while (iterator.hasNext()) {
Row nextRow = iterator.next();
Iterator<Cell> cellIterator = nextRow.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
System.out.print(cell.getStringCellValue());
System.out.print(",");
}
System.out.println();
}
workbook.close();
inputStream.close();
When you run the above program you will get some fields are not extracted from the excel sheet(Highlighted Part). When you explicitly try to access those cells you will get the null pointer exception.
Cannot reproduce the behavior. If System.out.print(cell.getStringCellValue()); throws a NPE, then cell must be null. But cell cannot be null according to your code since the Row.cellIterator iterates over cells only which are present and not null.
Have downloaded your SAMPLE.xlsx and used the code from Busy Developers' Guide - Getting the cell contents. This code reads all cells without problems.
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import java.io.FileInputStream;
class ReadExcelExampleDataFormatter {
public static void main(String[] args) throws Exception {
Workbook wb = WorkbookFactory.create(new FileInputStream("SAMPLE.xlsx"));
DataFormatter formatter = new DataFormatter();
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
CellReference cellRef = new CellReference(row.getRowNum(), cell.getColumnIndex());
System.out.print(cellRef.formatAsString());
System.out.print(" - ");
// get the text that appears in the cell by getting the cell value and applying any data formats (Date, 0.00, 1.23e9, $1.23, etc)
String text = formatter.formatCellValue(cell);
System.out.println(text);
}
}
wb.close();
}
}
Part of the result (your first yellow range):
A15 - Report
Summary
B15 - Real Estate
C15 - Count
D15 - 3
E15 - 0
F15 - 2
A16 -
B16 -
C16 - Balance
D16 - $94,263.00
E16 - $0.00
F16 - $94,263.00
A17 -
B17 -
C17 - Current
D17 - 2
E17 - 0
F17 - 2
A18 -
B18 -
C18 - Delinquent
D18 - 0
E18 - 0
F18 - 0

How to evaluate this formula right in apache poi?

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);
}

Missing cell policy of Apache POI Java

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);
}

DataFormatter on cell containing date renders two digits years

I needed to get cell data from Excel files as they look like and bumped to DataFormatter class of Apache PO. This works like a charm except for cells containing date. Below is my code:
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
StringBuilder rowDataBuilder = new StringBuilder();
int iCellCount = row.getLastCellNum();
for (int i = 0; i < iCellCount; i++)
{
Cell cell = row.getCell(i, Row.CREATE_NULL_AS_BLANK);
rowDataBuilder.append(dataFormatter.formatCellValue(cell));
rowDataBuilder.append(" | ");
}
_LOG.info("-----> row data: " + rowDataBuilder.toString());
}
For example, a cell contains 5/3/2013, I only get 5/3/13. Would there be any solutions for this?
For fetching the date in desired format you can use following:
SimpleDateFormat DtFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date=Test.getRow(RowNum).getCell(CellNum).getDateCellValue();
System.out.println(DtFormat.format(date).toString());
And now if the cell value is 05/03/2013, it will give o/p as 05/03/2013. I hope this will resolve your problem.

Categories

Resources