sheet.getLastRowNum() function gives invalid count with Apache POI 3.9 [duplicate] - java

This question already has answers here:
How to get row count in an Excel file using POI library?
(7 answers)
Closed 6 years ago.
I am using Apache POI 3.9 for xls and xlsx file processing.
As per the logic, I want to iterate over each row and want to collect data for further processing. For that I am using sheet.getLastRowNum() to retrieve number of rows in the xls sheet.
But it seems that sheet.getLastRowNum() gives wrong count if number of records are more than 10.
It works fine if total number of rows are 10. Otherwise it gives result deducted by one.
i.e If there are 15 row in the sheet then It gives 14 as Last Row number.
Can Anyone suggest me,How to solve this problem ??
Here is the code that i am using to collect the data ...
public static List<LinkedList<String>> populateExcelSheetContentWithHeader(Sheet sheet,int columnsCount,int rowsCount) throws Exception{
Row row = null;
List<LinkedList<String>> excelFileRecordsList = new LinkedList<LinkedList<String>>();
int emptyColCount = 0;
String freeTextData = null;
LinkedList<String> excelFileDataList =null;
int actualRows = sheet.getLastRowNum();
if (actualRows < rowsCount) {
rowsCount = actualRows;
}
///ITERATE OVER EACH ROW AND POPULATE THE DATA
for(int index=0;index<rowsCount;index++){
row = sheet.getRow(index);
if(row!=null){
emptyColCount = 0;
excelFileDataList =new LinkedList<String>();
for(int colIndex=0;colIndex<columnsCount;colIndex++){
freeTextData = "";
if(isEmptyCell(row.getCell(colIndex))){
emptyColCount++;
}else{
freeTextData = getCellValue(row.getCell(colIndex),false);
}
//ADD TEXT DETILS TO THE LIST
excelFileDataList.add(freeTextData);
}
//CHECK FOR END OF FILE
if(emptyColCount != columnsCount){
excelFileRecordsList.add(excelFileDataList);
}else{
break;
}
}
}
return excelFileRecordsList;
}
Any suggestion is appreciated .

it is possible that you are converting from CSV or you did any kind of modifications (copy or paste) inside your xls? I had the same exact behaviour when I did some changes like I mentioned. To fix it I had to copy the original again. Sorry for not providing a real solution, I just say what happened.
Maybe that helped

Related

How parse this excel? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 10 months ago.
Improve this question
I have an excel file, i have to parse to list of objects:
excel:
excel
my pojo:
my service:
public List<RegisterModel> parse(MultipartFile file) throws IOException {
Workbook workbook = new HSSFWorkbook(file.getInputStream());
Sheet worksheet = workbook.getSheetAt(0);
List<RegisterModel> registerModelList = new ArrayList<>();
RegisterModel registerModel = new RegisterModel();
for (int i = 3; i < worksheet.getPhysicalNumberOfRows(); i++) {
Row row = worksheet.getRow(i);
String headers = String.valueOf(row.getCell(0));
String values = String.valueOf(row.getCell(1));
if (headers.equals("OPERDAY")){
registerModel.setDate(values);
}
if (headers.equals("SUIP")){
registerModel.setSuip(values);
}
if (headers.equals("STATE")){
registerModel.setSuip(values);
}
if (headers.equals("NOM_OPER")){
registerModel.setTransactionID(values);
}
registerModelList.add(registerModel);
}
System.out.println(registerModelList);
return registerModelList;
}
but it is not works(
result: values are duplicate
[RegisterModel(date=2022-03-01T23:48:47, suip=Проведён, state=null, transactionID=1888314188),
RegisterModel(date=2022-03-01T23:48:47, suip=Проведён, state=null, transactionID=1888314188),
RegisterModel(date=2022-03-01T23:48:47, suip=Проведён, state=null, transactionID=1888314188)]
The issue is caused by only creating a single instance of registerModel outside of your for loop. You just keep editing that object over and over instead of creating new instances of it. The way to solve this is to create a new instance of registerModel every time a previous object is completed or before a new object is started.
There are multiple ways to achieve this by using nested loops or incrimenting your for loop by 5 at a time (rows in your order) and specifically keeping track of where items are at. However, if we assume that the last bit of data in an order is the "NOM_OPER" row then we can do the following quick and easy solution.
This is the code that has been changed:
if (headers.equals("NOM_OPER")){
registerModel.setTransactionID(values);
//Now that the object is complete we can add it to the list (moved here from below)
registerModelList.add(registerModel);
//The lastly we NEED to create a new instance of registerModel for the next order to use
registerModel = new RegisterModel();
}
//Remove the below line after the if statements.
//You should only add the model to the list once the object is complete. Don't add it on every row.
//registerModelList.add(registerModel);
And the complete method looks like this:
public List<RegisterModel> parse(MultipartFile file) throws IOException {
Workbook workbook = new HSSFWorkbook(file.getInputStream());
Sheet worksheet = workbook.getSheetAt(0);
List<RegisterModel> registerModelList = new ArrayList<>();
RegisterModel registerModel = new RegisterModel();
for (int i = 3; i < worksheet.getPhysicalNumberOfRows(); i++) {
Row row = worksheet.getRow(i);
String headers = String.valueOf(row.getCell(0));
String values = String.valueOf(row.getCell(1));
if (headers.equals("OPERDAY")){
registerModel.setDate(values);
}
if (headers.equals("SUIP")){
registerModel.setSuip(values);
}
if (headers.equals("STATE")){
registerModel.setSuip(values);
}
if (headers.equals("NOM_OPER")){
registerModel.setTransactionID(values);
//Now that the object is complete we can add it to the list (moved here from below)
registerModelList.add(registerModel);
//The lastly we NEED to create a new instance of registerModel for the next order to use
registerModel = new RegisterModel();
}
//Remove the below line after the if statements.
//You should only add the model to the list once the object is complete. Don't add it on every row.
//registerModelList.add(registerModel);
}
System.out.println(registerModelList);
return registerModelList;
}

Content overwritten on top of another when formula is applied to excel cell using Apache poi

I am getting an issue of content being overwritten on top of another i.e old value and new values overlap after applying formula. And this issue only occurs Microsoft Excel 2010. How do I handle this?
I have tried refreshing the formulas for entire workbook using formula evaluator but still the issue persists.
private String applyTtlAvlFormula(final int colId, final int hrsColId)
{
String ttlFormulaString = "";
for( int i = ttlAvlContentRow; i < tableHeadStartRow+1; i++) {
String colName1 = CellReference.convertNumToColString(hrsColId);
String colName2 = CellReference.convertNumToColString(colId);
ttlFormulaString += "("+colName1+String.valueOf(i)+ "*$"+colName2 +"$"+String.valueOf(i)+")";
if (i != tableHeadStartRow){
ttlFormulaString += "+";
}
}
return ttlFormulaString;
}
cell.setCellFormula(applyTtlAvlFormula(j,hrsCol));
Following are pre and post shots of the issue.
From the images it can be seen that 40 and 32 gets overlapped after applying the formula. How can this issue be resolved.

Apache POI : Update cells in a named range

I am using Apache POI library to read/write to xlsx. In my original xlsx, I have a namedrange "XYZ".
I want to update the values of cells within this name range. How can I do that?
I did this:
XSSFName name = workbook.getName("XYZ");
String formula = name.getRefersToFormula();
System.out.println("Formula = " + formula);
Now, I dont know how to get a handle to individual cell in this named range.
Can anyone please point me to the correct API that I can use?
Rgds
Sapan
There is an example from the Busy Developers' Guide for retrieving the cells in the range. Then you can use Cell.setCellValue() to update.
// setup code
String cname = "TestName";
Workbook wb = getMyWorkbook(); // retrieve workbook
// retrieve the named range
int namedCellIdx = wb.getNameIndex(cname);
Name aNamedCell = wb.getNameAt(namedCellIdx);
// retrieve the cell at the named range and test its contents
AreaReference aref = new AreaReference(aNamedCell.getRefersToFormula());
CellReference[] crefs = aref.getAllReferencedCells();
for (int i=0; i<crefs.length; i++) {
Sheet s = wb.getSheet(crefs[i].getSheetName());
Row r = s.getRow(crefs[i].getRow());
Cell c = r.getCell(crefs[i].getCol());
// extract the cell contents based on cell type etc.
}

last row is not merged in ms word table using aspose word for java

i have created a table in ms word by aspose.word using node. Now i need table in which 2nd column will be merged except first row
I got the merge column, but first and last row is not merging. First row is okay, because it was coded for that. But I cannot find out why last row is not merged.
I have not enough reputation to attach image. So, I have to describe details of my output
Here is my code:
Document doc=new Document();
Table table = new Table(doc);
// Add the table to the document.
doc.getFirstSection().getBody().appendChild(table);//add table
Row row[]= new Row[4];Cell cell[] = new Cell[3];
for (int i = 0; i < row.length; i++) {
row[i]=new Row(doc);table.appendChild(row[i]);
table.autoFit(AutoFitBehavior.AUTO_FIT_TO_WINDOW);//if I set this here last row not //merge
for (int j = 0; j < cell.length; j++) {
cell[j]=new Cell(doc);
row[i].appendChild(cell[j].deepClone(false));//cell creation
// but in this position table.autoFit(AutoFitBehavior.AUTO_FIT_TO_WINDOW) create //no problem
row[i].getLastCell().appendChild(new Paragraph(doc));
if(row[i]==table.getFirstRow())
{
}
else
{
if(j==1)
{
if(i==1)
{
row[i].getCells().get(j).getCellFormat().setVerticalMerge(CellMerge.FIRST);
}
else
{
row[i].getCells().get(j).getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
}
}
}
}
}
I am getting the following output by running your code. Kindly make sure that you are using the latest version of Aspose.Words for Java. If you are having same issue with latest version too, please share your environment details so that I can reproduce it at my side.
Download the latest version by visiting Aspose.Words for Java or directly download the Jar file from our Maven repository.
Disclosure: I am a developer at Aspose.

Excel formula not updating on row delete from java application using Apache POI

I'm using Apache POI in my application to write data to an excel file. I've an excel file template and a few formulas are also there in it. In my application, i use the excel template, write into it ,then delete unused rows and calculate formulas in the end. I'm using SUM formula in the file. The problem is when rows are deleted, the SUM formula is not updating,due to which error values are coming up in excel.
Example : the formula being used is : for cell B215 : SUM(B15:B214). in the application,after writing to the file i delete unused rows. now I've data till 70th row in the file.All other rows have been deleted. So my formula should get updated to : SUM(B15:B69) for cell B70. But in the file it's still showing the formula as SUM(B15:B214). Hence the value of that cell is "VALUE#
Code snippet :
File file = new File(path)
InputStream is = new FileInputStream(file)
POIFSFileSystem fs = new POIFSFileSystem(is)
HSSFWorkbook wb = new HSSFWorkbook(fs)
HSSFSheet excelSheet
int[] indexArray = populateSheet(excelSheet)
//indexArray is array with 3 values as startrow, lastrow, and first empty row.
removeBlankRows(excelSheet,indexArray)
//evaluate formula
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator()
for(HSSFRow r : excelSheet) {
for(HSSFCell c : r) {
if(c.getCellType() == Cell.CELL_TYPE_FORMULA) {
String formula = c.getCellFormula();
evaluator.evaluateFormulaCell(c)
}
}
}
private void removeBlankRows(HSSFSheet sheet, int[] shiftInfo){
for(int i = shiftInfo[2]; i <= shiftInfo[1]; ++i) {
sheet.removeRow(sheet.getRow(i))
}
//Shift up the rows
def startRow = shiftInfo[1]+1
def endRow = sheet.getLastRowNum()
def rowCount = -1* (shiftInfo[1] - shiftInfo[2] + 1)
sheet.shiftRows(startRow, endRow, rowCount)
}
This is an Excel bug. I've dealt with this in the past by doing the following:
Label the sum cell BSUM
We need a stable range that won't be affected by inserts/deletes.
Add a formula to a safe (one that won't get deleted) cell, for this example D15: ="B15:B"&ROW(BSUM)-1
This will produce a stable range.
Use INDIRECT in the BSUM cell like so:
=SUM(INDIRECT(D15))

Categories