in extensions/vw/tabular/excel/src/main/java/org/apache/causeway/extensions/tabular/excel/exporter/CellStyleProvider.java [39:250]
record CellStyleProvider(
@NonNull Workbook workbook,
@NonNull CellStyle primaryHeaderStyle,
@NonNull CellStyle secondaryHeaderStyle,
@NonNull CellStyle dateStyle,
@NonNull CellStyle multilineStyle,
@NonNull CellStyle[] blueStyles,
@NonNull CellStyle[] greenStyles,
@NonNull CellStyle[] indigoStyles,
@NonNull CellStyle[] warningStyles,
@NonNull CellStyle[] dangerStyles,
ExcelFileWriter.@NonNull Options options) {
static CellStyleProvider create(final Workbook wb, final ExcelFileWriter.@Nullable Options options) {
var styleIndexList = new StyleIndexList();
return new CellStyleProvider(wb,
createPrimaryHeaderRowStyle(wb),
createSecondaryHeaderRowStyle(wb),
createDateFormatCellStyle(wb, styleIndexList, "yyyy-mm-dd"),
createMultilineCellStyle(wb, styleIndexList),
createColoredStyles(wb, styleIndexList, new Color(0x6ea8fe)), // blue-300 (6ea8fe)
createColoredStyles(wb, styleIndexList, new Color(0x75b798)), // green-300 (75b798)
createColoredStyles(wb, styleIndexList, new Color(0xa370f7)), // indigo-300 (a370f7)
createColoredStyles(wb, styleIndexList, new Color(0xffcd39)), // warning yellow-400 (ffcd39)
createColoredStyles(wb, styleIndexList, new Color(0xe35d6a)), // danger red-400 (e35d6a)
options!=null
? options
: ExcelFileWriter.Options.builder().build());
}
/**
* Applies a custom cell style to given {@link Cell}
* based on whether any of the cellStyleFunctions is available
* and if so, whether any of the cellStyleFunctions returns a non-null CellStyle.
* @implNote we are doing this distinction of cases for performance reasons,
* that is, minimize the number of style function calls;
* otherwise code could be simplified
*/
void applyCustomStyle(final TabularRow tabularRow, final Iterable<Cell> cells) {
switch (StylePolicy.get(options)) {
case NONE: return;
case ROW_ONLY: {
var customRowStyle = CustomCellStyle.nullToDefault(
options.rowStyleFunction().apply(tabularRow));
if(customRowStyle.isDefault()) return;
for(var cell : cells) {
applyCustomCellStyle(cell, customRowStyle);
}
return;
}
case CELL_ONLY: {
int cellIndex = 0;
for(var cell : cells) {
var customCellStyle = CustomCellStyle.nullToDefault(
options.cellStyleFunction().apply(tabularRow.getCell(cellIndex++)));
applyCustomCellStyle(cell, customCellStyle);
}
return;
}
case CELL_AND_ROW: {
CustomCellStyle customRowStyle = null; // only calculate if needed
int cellIndex = 0;
for(var cell : cells) {
var customCellStyle = CustomCellStyle.nullToDefault(
options.cellStyleFunction().apply(tabularRow.getCell(cellIndex++)));
if(!customCellStyle.isDefault()) {
applyCustomCellStyle(cell, customCellStyle);
} else {
if(customRowStyle==null) {
customRowStyle = CustomCellStyle.nullToDefault(
options.rowStyleFunction().apply(tabularRow));
}
applyCustomCellStyle(cell, customRowStyle);
}
}
return;
}
}
}
Cell applyDateStyle(final Cell cell) {
cell.setCellStyle(dateStyle());
return cell;
}
Cell applyMultilineStyle(final Cell cell) {
cell.setCellStyle(multilineStyle());
return cell;
}
private void applyCustomCellStyle(final Cell cell, final CustomCellStyle customCellStyle) {
if(customCellStyle==null
|| customCellStyle.isDefault()) return;
final int ordinal = valueKindOf(cell).ordinal();
cell.setCellStyle(
switch (customCellStyle) {
case BLUE -> blueStyles()[ordinal];
case GREEN -> greenStyles()[ordinal];
case INDIGO -> indigoStyles()[ordinal];
case WARNING -> warningStyles()[ordinal];
case DANGER -> dangerStyles()[ordinal];
case DEFAULT -> throw new UnsupportedOperationException("unexpected code reach");
});
}
private enum ValueKind {
DEFAULT,
DATE,
MULTILINE;
}
private ValueKind valueKindOf(final Cell cell) {
if(cell.getCellStyle().getIndex() == dateStyle.getIndex()) return ValueKind.DATE;
if(cell.getCellStyle().getIndex() == multilineStyle.getIndex()) return ValueKind.MULTILINE;
return ValueKind.DEFAULT;
}
/**
* Creates a colored variant for each {@link ValueKind}.
* @param styleIndexList
*/
private static CellStyle[] createColoredStyles(final Workbook wb, final StyleIndexList styleIndexList, final Color color) {
var valueKinds = ValueKind.values();
var cellStyles = new CellStyle[valueKinds.length];
for(var valueKind : valueKinds) {
var cellStyle = cellStyles[valueKind.ordinal()] = wb.createCellStyle();
switch (valueKind) {
case DEFAULT -> {}
case DATE -> cellStyle.cloneStyleFrom(wb.getCellStyleAt(styleIndexList.dateStyleIndex));
case MULTILINE -> cellStyle.cloneStyleFrom(wb.getCellStyleAt(styleIndexList.multilineStyleIndex));
}
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(createColor(color));
}
return cellStyles;
}
private static CellStyle createPrimaryHeaderRowStyle(final Workbook wb) {
var font = wb.createFont();
font.setBold(true);
var cellStyle = wb.createCellStyle();
cellStyle.setFont(font);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(createColor(new Color(0xc0c0c0)));
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
return cellStyle;
}
private static CellStyle createSecondaryHeaderRowStyle(final Workbook wb) {
var font = wb.createFont();
font.setFontHeightInPoints((short) 10);
var cellStyle = wb.createCellStyle();
cellStyle.setFont(font);
cellStyle.setWrapText(true);
cellStyle.setVerticalAlignment(VerticalAlignment.TOP);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(createColor(new Color(0xeeeeee)));
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.NONE);
cellStyle.setBorderBottom(BorderStyle.MEDIUM);
return cellStyle;
}
private static CellStyle createDateFormatCellStyle(final Workbook wb, final StyleIndexList styleIndexList, final String dateFormat) {
var cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(wb.getCreationHelper().createDataFormat().getFormat(dateFormat));
styleIndexList.dateStyleIndex = cellStyle.getIndex();
return cellStyle;
}
private static CellStyle createMultilineCellStyle(final Workbook wb, final StyleIndexList styleIndexList) {
var cellStyle = wb.createCellStyle();
cellStyle.setVerticalAlignment(VerticalAlignment.TOP);
cellStyle.setWrapText(true);
styleIndexList.multilineStyleIndex = cellStyle.getIndex();
return cellStyle;
}
private static XSSFColor createColor(final Color color) {
return new XSSFColor(color, new DefaultIndexedColorMap());
}
private static class StyleIndexList {
short dateStyleIndex = -1;
short multilineStyleIndex = -1;
}
private enum StylePolicy {
NONE,
CELL_ONLY,
ROW_ONLY,
CELL_AND_ROW;
static StylePolicy get(final ExcelFileWriter.Options options) {
return options.rowStyleFunction()!=null
? options.cellStyleFunction()!=null
? StylePolicy.CELL_AND_ROW
: StylePolicy.ROW_ONLY
: options.cellStyleFunction()!=null
? StylePolicy.CELL_ONLY
: StylePolicy.NONE;
}
}
}