In this section you will see how you can customize result workbook during XLS transformation. For example you may want to change style of some cells dynamically depending on exported data. Or you may want to change values of some bean properties for example to scale them or do something else.
Many of this can be done using Excel conditional formatting or macros. jXLS provides alternative way to do this with custom cell and row processors.
You may implement RowProcessor
interface if you need to set style for some row
dynamically. The interface contains single method
void processRow(Row row, Map namedCells)
.
XLSTransformer invokes this method for every registered CellProcessor and passes to it two parameters:
Row row
- contains all information about the current processed row
Map namedCells
- contains all named cells that were found during processing of previous cells
With Row
object you have access to related POI
objects to modify cell style if required.
Let's take a look at StyleRowProcessor
class from Row Style sample.
This class allows to highlight some rows containing employee information for all employees with payment greater than 2000.
public class StyleRowProcessor implements RowProcessor { String collectionName; String styleCellLabel = "customRow"; public StyleRowProcessor(String collectionName) { this.collectionName = collectionName; } public void processRow(Row row, Map namedCells) { // check if processed row has a parent row if( row.getParentRow()!=null ){ // Processed row has parent row. It means we are processing some collection item RowCollection rowCollection = row.getParentRow().getRowCollectionByCollectionName( collectionName ); if( rowCollection.getIterateObject() instanceof Employee){ Employee employee = (Employee) rowCollection.getIterateObject(); if( employee.getPayment().doubleValue() >= 2000 ){ if( namedCells.containsKey( styleCellLabel ) ){ Cell customCell = (Cell) namedCells.get( styleCellLabel ); for (int i = 0; i < row.getCells().size(); i++) { Cell cell = (Cell) row.getCells().get(i); org.apache.poi.ss.usermodel.Cell hssfCell = cell.getHssfCell(); if( hssfCell!=null ){ copyStyle( row.getHssfWorkbook(), customCell.getHssfCell(), hssfCell ); } } } } } } } }
You can see that in processRow()
method we check does current row have parent row
// check if processed row has a parent row if( row.getParentRow()!=null ){ ....
The point is that for every row that is being processed as collection item XLSTransformer
sets parentRow
property with information about base row containing current collection details.
Then we get RowCollection
object related to our collection in question using
getRowCollectionByCollectionName( collectionName )
method of Row
class
// Processed row has parent row. It means we are processing some collection item RowCollection rowCollection = row.getParentRow().getRowCollectionByCollectionName( collectionName );
After that we check that current iterated object is of required type and cast current collection item
to Employee
class. And then we check its payment property
if( rowCollection.getIterateObject() instanceof Employee){ Employee employee = (Employee) rowCollection.getIterateObject(); if( employee.getPayment().doubleValue() >= 2000 ){ ... }
Then we trying to find named cell with name styleCellLabel
that is equal to "customRow"
if( namedCells.containsKey( styleCellLabel ) ){ Cell customCell = (Cell) namedCells.get( styleCellLabel );
Then we walk through all Cell
objects for current row and copy
cell style from named cell to current cell
for (int i = 0; i < row.getCells().size(); i++) { Cell cell = (Cell) row.getCells().get(i); org.apache.poi.ss.usermodel.Cell hssfCell = cell.getHssfCell(); if( hssfCell!=null ){ copyStyle( row.getHssfWorkbook(), customCell.getHssfCell(), hssfCell ); } }
Method copyStyle(..)
is rather simple and just copies cell style from one cell to another.
See Row Style sample for the actual code.