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.
Related
I was trying to read data from an excel sheet that contains empty cells consider the following code:
File src = new File(path to your file);
FileInputStream fis = new FileInputStream(src);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet1 = wb.getSheet("Sheet1");
int rowCount = sheet1.getLastRowNum();
System.out.println("total number of rows is: " + rowCount);
for(int i = 1; i < rowCount; i++) {
//getcell returns row num and starts from 1
//Also my sheet column contains data in numeric form
int data = (int) sheet1.getRow(i).getCell(1).getNumericCellValue();
System.out.println(data);
}
However, my code also reads the empty cells and displays the value as 0 (The cells have numeric value). How do I make my script read-only cells that are filled and display them while ignoring the ones that are empty?
Thank you in advance
Just update the for loop with an if condition which will check for the value which is getting retrieved from the Cell. PFB the updated for loop.
For Apache POI version 4.x you can try below-
for(int i = 1; i < rowCount; i++) {
//getcell returns row num and starts from 1
//Also my sheet column contains data in numeric form
Cell cell = sheet1.getRow(i).getCell(1);
int data = (int) sheet1.getRow(i).getCell(1).getNumericCellValue();
if(c.getCellType() == CellType.Blank)
{
continue;
}
else{
System.out.println(data);
}
}
For Apache POI version 3.x you can try below-
for(int i = 1; i < rowCount; i++) {
//getcell returns row num and starts from 1
//Also my sheet column contains data in numeric form
Cell cell = sheet1.getRow(i).getCell(1);
int data = (int) sheet1.getRow(i).getCell(1).getNumericCellValue();
if(cell.getCellType() == Cell.CELL_TYPE_BLANK)
{
continue;
}
else{
System.out.println(data);
}
}
Cannot iterate the full extent of rows in my XLS spreadsheet. The code {sheet.getPhysicalNumberOfRows} returns 33492 without raising exception, but there are about 43,000 rows??.
If I supply the right number manually the loop executes without complaint.
It must be simple answer but I cannot find one anywhere. can somebody help?
try {
POIFSFileSystem fs = new POIFSFileSystem(new
FileInputStream(fileLocation));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row;
HSSFCell cell;
int rows; // No of rows
rows = sheet.getPhysicalNumberOfRows(); //Gets => 33494
int cols = 1; // No of columns
int tmp = 0;
for (int r = 0; r < rows; r++) {
row = sheet.getRow(r);
if (row != null) {
cell = row.getCell(0);
if (cell != null) {
System.out.println("Line number: " + r " = " + cell);
}
}
}
} catch(Exception ioe) {
ioe.printStackTrace();
}
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();
}
}
}
}
This question already has an answer here:
Parse Excel by poi and target cell is empty sometimes parse ok sometimes throw nullpointexception
(1 answer)
Closed 6 years ago.
I have written below mentioned snippet of code for reading excel file and this is working fine for non empty excel file but for excel file it is throwing NULLPOINTEREXCEPTION.
ArrayList<String> dataList = new ArrayList<String>();
XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
int rowNum = xssfSheet.getLastRowNum() + 1;
int startRow = 0, startCol = 0, colNum;
for (int r = startRow; r < rowNum; r++) {
XSSFRow row = xssfSheet.getRow(r);
colNum = xssfSheet.getRow(r).getLastCellNum();
String data = "";
for (int c = startCol; c < colNum; c++) {
XSSFCell cell = row.getCell(c,XSSFRow.CREATE_NULL_AS_BLANK);
data += cell.toString() + ", ";
}
dataList.add(data);
}
closeFile();
I'm getting exception in this line for an empty file:
colNum = xssfSheet.getRow(r).getLastCellNum(); The issue is getLastCellNum() return value as 0 for no record as well as for one record. So while retrieving getLastCellNum() i'm getting null pointer exception.
You should use rowIterator() and cellIterator() to iterate over rows and columns.
XSSFRow row;
XSSFCell cell;
Iterator rows = sheet.rowIterator();
while (rows.hasNext()){
row=(XSSFRow) rows.next();
Iterator cells = row.cellIterator();
while (cells.hasNext())
{
cell=(XSSFCell) cells.next();
cIndex=cell.getColumnIndex();
data += cell.toString() + ", ";
}
dataList.add(data);
}
Actually I tried to store some data in HSSFCell using java but i got an error like
java.lang.IllegalArgumentException: The maximum length of cell contents (text) i
s 32,767 characters
at org.apache.poi.hssf.usermodel.HSSFCell.setCellValue(HSSFCell.java:559
)
at org.apache.poi.hssf.usermodel.HSSFCell.setCellValue(HSSFCell.java:533
)
at application.ExtractUI.datatoexcel(ExtractUI.java:272)
at application.ExtractUI$3.getData(ExtractUI.java:208)
at application.ExtractUI$3.handle(ExtractUI.java:198)
at application.ExtractUI$3.handle(ExtractUI.java:1)
can anyone suggest me a method to increase the cell length ie more than 32767 characters???
I used the following code for which I got the above error
public void datatoexcel(ResultSet rs) {
try {
int iter = 0;
ResultSetMetaData rmeta = rs.getMetaData();
int col = rmeta.getColumnCount();
HSSFWorkbook workbook = new HSSFWorkbook();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy HHmmss");
String pa = pth + "\\" + sdf.format(date) + ".xlsx";
System.out.println(pa);
FileOutputStream out = new FileOutputStream(new File(pa));
HSSFSheet sheet = workbook.createSheet();
HSSFRow myRow = null;
HSSFCell myCell = null;
// Font style for headers
HSSFFont boldFont = workbook.createFont();
boldFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
boldFont.setColor(HSSFFont.COLOR_RED);
HSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFont(boldFont);
while (rs.next()) {
// limit the data to 1000 anad create a new sheet
if (iter == 1000) {
sheet = workbook.createSheet();
iter = 0;
}
// Adding header to the first row
if (iter == 0) {
myRow = sheet.createRow(iter);
for (int k = 1, j = 0; k <= col && j < col; k++) {
myCell = myRow.createCell( j);
myCell.setCellValue(rmeta.getColumnName(k));
// set style to font
myCell.setCellStyle(cellStyle);
j++;
}
iter++;
}
// Adding data from 2nd Row
myRow = sheet.createRow(iter);
for (int k = 1, j = 0; k <= col && j < col; k++) {
myRow.createCell( j).setCellValue(
rs.getString(rmeta.getColumnName(k)));
j++;
}
iter++;
}
workbook.write(out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
any suggestions??
Your only option is to switch file formats. There's a hard limit in both the .xls and .xlsx file formats of 32,767 characters. Apache POI is simply enforcing the file format + Excel limit. You can see details of those limits in the Microsoft documentation, and also captured nicely in this Apache POI javadoc page
If you really need text that long, you'll need to switch to another file format such as CSV
Or you can truncate your string length to the specified maximum length minus one
private void writeIssueDataForEachRow(Issue issue, Row row, CellStyle style,
List<ColumnIndex> customFieldDefinitions) {
Cell cell = row.createCell(0);
cell.setCellValue(issue.getId()); // 編號
cell.setCellStyle(style);
cell = row.createCell(1);
cell.setCellValue(issue.getSubject()); // 主旨
cell.setCellStyle(style);
// substring 的原因是要避開 The maximum length of cell contents (text) is 32,767 characters
cell = row.createCell(2);
cell.setCellValue(StringUtils.substring(issue.getDescription(), 0, 32767)); // 敘述
cell.setCellStyle(style);
}