I am reading a .xslx file using Apache POI in Java.The last row in it is having some borders missing around some cells.
when I am reading this then in the last row after reading "abc"(written in first cell) ,am directly reading "rule1"(written in third cell) and second column is empty and bottom border is missing for it.
So the value of second cell which is empty cell is lost.So how can I be able to know that whether I have skipped any cell due to this formatting problem?
Use Cell.getColumnIndex() to retrieve the current cell's index. With this information you will be able to exactly get its position, and thus also find out whether there were any groups.
Related
I have generated an Excel document with jxls and POI. Now POI has merged cell, half data is in page 1 & other half of merged cell in page 2. How can I prevent it?
Unfortunately you can't. That's a disadvantage of Excel. Excel does not provide a "keep merged cells on one page" feature. One need to set an explicit page break above of the row which shall the first on the new page.
Apache POI provides Sheet.setRowBreak to do so.
So you need to know what row is the first one having the merged cells split into two pages. Then set row break to the row above.
For example if first row index of the rows having the merged cells split into two pages is 25, then:
...
Sheet sheet ...
...
sheet.setRowBreak(24);
...
Of course this only can be used if the row positions on the page are static or if one knows how many rows fit to one page. I don't know any more dynamic solution.
Same is if merged columns split over two pages. Then manually set a column break is needed.
Apache POI provides Sheet.setColumnBreak to do so.
Of course this has same disadvantages as manually row break has.
Trying to create an JXLS excel template where it should be possible to copy conditional formatting from a cell on a specific row to the next generated row.
In the template, I create my formatting. If the value in the cell is equal to "yes" the row should be red.
Template
Conditional formatting
Formula: =$B2="yes"
Applies to: $A$2:$B$2
I know this formula works on an already populated excel sheet here is an example https://trumpexcel.com/highlight-rows-based-on-cell-value/
But when I do this with my excel template and JXLS 2.0 it fails. It copies the formula as it is to each new generated row. So instead of one condition for the whole sheet, there will now be as many as there are rows. The problem here is that it will copy it as is, which means that the formula in each condition will be based on the value in cell C2. So even if cell C3 is generated with the value "no" it will be red, since it is based on the value in C2.
Output excel
Condition Formatting output excel
Any tips on how to solve this directly in the template?
Using
jxls 2.9.0
jxls-poi 2.9.0
One approach is to modify the formula in the template to acheive what we want.
Formula: =INDIRECT("$B" & ROW())="yes"
Description:
ROW() returns the current row number.
"$B" & ROW() gives the cell reference. For example, at row 5, we will get B5
Finally, using INDIRECT(...) we get the value at cell reference and check if is "yes".
Output excel:
What you are experiencing is standard Excel behaviour. In order to achieve what you want you have 2 options: using a regular Range or a dynamic table. I would use the latter.
Using a regular Range
You need to start with at least 2 rows like this:
and then only insert rows after the first row and before the last row. Never before first or after last. The new rows are picking up the same formatting because the underlying range is expanding. For example, inserting 4 rows in between results in:
Using a dynamic table
Assuming you have headers (you don't need to), you select your start range and then format it as a table:
You will have the option to choose if the table has headers or not via a checkbox in the dialog that will appear.
Then you add the same conditional formatting:
The difference now is that when you add a new row, the conditional formatting will automatically expand. The table itself automatically expands so everyting else (formatting, validation, formulas etc.) are expanding with it.
Just make sure you have the auto expanding option on for tables under File/Options/Proofing/AutoCorrect Options/AutoFormat As You Type/Include new rows and columns in table. You can do that programatically as well (I know in VBA you need to set Application.AutoCorrect.AutoExpandListRange to True). The default is True by the way.
No matter how big your table will get, you will have the formatting expanded.
I am using Apache POI to write data to an Excel template. The template only contains headers on the first row, but I also applied specific styles to the entire column (e.g. Accounting and Percentage).
It would be nice to use these formats when I write data to the new cells. But if I use the createRow and createCell methods, the cell format is overwritten and I get General for all the cells. If I try to use getRow and getCell instead, I run into NullPointerExceptions retrieving the blank cell.
Is there a way to use the pre-existing cell formatting saved in the template? Or am I stuck setting the data format myself through the API?
Thanks for your help.
If you have applied specific styles to an entire column, then you can retrieve that CellStyle with Sheet's getColumnStyle method, passing it the 0-based column index. It retrieves a normal CellStyle object that can be used anywhere else CellStyles are accepted, such as in Cell's setCellStyle method.
For avoiding the NullPointerException, both getRow and getCell may return null if the row or cell doesn't exist, respectively. You will need to call createRow and/or createCell to create the Cell, on which you can always call setCellStyle.
cell.setCellStyle(sheet.getColumnStyle(index) works well.
Not able to distinguish between hidden cells and others. Using POI 3.8 and xls/xlsx format. baseRow.getZeroHeight(), baseCell.getCellStyle().getHidden(), baseSheetX.getColumnStyle(14).getHidden() all return false though entire column is hidden. Please guide.
If the entire column is hidden, Excel will just mark the column itself as hidden on the sheet. It won't go through that particular column index in all rows and change the cell styling just to make all the cells hidden, and it won't go through the column cell style either.
Try the method Sheet#isColumnHidden(int).
Get the hidden state for a given column
I'm getting this exception while getting a cell. This is what I'm doing:
if(versionToAdd.equals("15.6")) {
Cell X = wb.getSheetAt(0).getRow(28+j).getCell((short)7);
Cell Y = wb.getSheetAt(0).getRow(28+j).getCell((short)8);
X.setCellValue(x);
Y.setCellValue(y);
}
this code it's inside of a for loop (j), and every time I iterate over a List of values, i get a new cell dynamically.
The problem is that, whenever it gets to the first col:row (H:29), i get a NullPointerException.
NOTE: The cells in the xls file are in blank... could that be the problem?
I got a collection of X/Y values in java, starts reading it, but whenever it reaches a certain amount of values, I get a NullPointerException in this line:
Cell cellx = row.getCell(8);
The java list is fine.
If I put less X/Y pairs (i.e: 5 or 6 pairs), works great, but over a certain amount (let's say > 10), I get that exception.
Tried looking for the cells, everything seems to be fine
EDITED: Thanks people for your help! I started to use the XSSF/HSSF from POI. Tried to use it before, but I couldn't get it to run properly, but now I did and it works perfect by using the createRow-createCell methods :)
Both org.apache.poi.ss.usermodel.Sheet and org.apache.poi.ss.usermodel.Row are Iterable. If you use the iterator in nested for-each loops, as shown here, you should get only defined rows.
According to the POI documentation, if you ask for a row that is not defined, null is returned.
The same is true for getting a cell from a row. I would assume that either a row or a cell does not exist.
Also, notice that the short version of getCell is deprecated in favor of getCell(int)
POI Sheet
POI Row
You can use getLastRowNum to verify that the number of rows that you are expecting exists. Same it true for getLastCellNum.
If you are creating a sheet / row / cell, you need to use the create methods. Not the get methods.
Create Row
Create Cell
The first three items on the user's guide are: how to create workbook, how to create sheet, how to create cells. You should check the documentation prior to posting questions.
POI Guide