Apache POI - Writing to Excel template without overwriting existing cell formatting - java

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.

Related

JXLS 2.0 Conditional Formatting Forumla not updated per row

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.

How to set existing excel file data format 'text' using java

We have an excel file which may be large.
We want to set cell format to 'text' to avoid issue like '=cmd', which may run 'cmd'.
Does there have any high efficient way to keep excel data format as text but keep other format like backgroud color or font-size?
To set the cell type, you can use:
Cell cell = row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell.setCellType(CellType.STRING);
This should avoid using formulas in the cells, unless you specifically set the type to CellType.FORMULA.

Not able to distinguish between hidden cells and others. Using POI 3.8 and xls/xlsx format

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

Apache POI preserve existing Excel formatting style

I'm using Apache POI to read an existing template excel file and would like to copy the existing styles in some header rows and apply them to new cells.
It seems like the existing formatting is not being applied (IE, Date, Currency, Percentage etc).
The code is pretty basic:
//read existing style
Row existingRow = sheet.getRow(headerRowIndex);
Cell existingCell = existingRow.getCell(0);
CellStyle currentStyle = existingCell.getCellStyle();
//apply date style here
Date date = StringUtil.toDate(map.get(column.getHeaderName()));
cell.setCellValue(date);
//apply previous style
cell.setCellStyle(currentStyle);
It does copy the font and background color etc but it seems like the formatting is lost (all cells have "general" formatting applied).
Also when I do this:
currentStyle.getDataFormat(); // always 0
So it makes me think that I'm not reading the formatting correctly. Any ideas on how to accomplish this?
OK I figured it out, it was my mistake. I was reading the style from the first cell in the row and applying it to all, instead of reading from each cell.
This fixes it
Cell existingCell = existingRow.getCell(i);

Apache POI excel cell style update

Using Apache Poi I'm exporting my table to an excel sheet. I extended ExcelExport class, override the getCellStyle method and customized my cell styles.
Now what i want is when a user edits any cell in the excel document i want that cell to change its color, so anyone later reviewing the document can easily see what has been changed.
Is there way to achieve this?
One solution could be to add conditional formatting to the cells use Apache POI's HSSFSheetConditionalFormatting.
For example, if the cell value written by your program is 5 then your conditional formatting could set the cell background to yellow if the value wasn't equal to 5

Categories