diff --git a/src/main/java/com/github/jlangch/venice/impl/util/excel/ExcelSheet.java b/src/main/java/com/github/jlangch/venice/impl/util/excel/ExcelSheet.java index 50291f896..7ac79b529 100644 --- a/src/main/java/com/github/jlangch/venice/impl/util/excel/ExcelSheet.java +++ b/src/main/java/com/github/jlangch/venice/impl/util/excel/ExcelSheet.java @@ -39,16 +39,19 @@ import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellValue; import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.ConditionalFormattingRule; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.FormulaEvaluator; +import org.apache.poi.ss.usermodel.PatternFormatting; import org.apache.poi.ss.usermodel.Picture; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row.MissingCellPolicy; import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.SheetConditionalFormatting; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellAddress; import org.apache.poi.ss.util.CellRangeAddress; @@ -68,6 +71,7 @@ import com.github.jlangch.venice.util.excel.chart.LineDataSeries; import com.github.jlangch.venice.util.excel.chart.PieDataSeries; import com.github.jlangch.venice.util.excel.chart.Position; +import com.github.jlangch.venice.util.pdf.HtmlColor; /** @@ -298,6 +302,34 @@ public void copyCellStyle( } } + public void conditionalBackgroundColor( + final String condRule, // "ISBLANK(A1)" + final String condRegion, // "A1:B1" + final String bgColorHtml // "#CC636A" + ) { + // Create a conditional formatting rule for blank cells + final SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); + + // Define a conditional formatting rule using a formula (ISBLANK(A1)) + final ConditionalFormattingRule rule = sheetCF.createConditionalFormattingRule(condRule); + + // Create a pattern formatting object + final PatternFormatting fill = rule.createPatternFormatting(); + + final Color bg = HtmlColor.getColor(bgColorHtml); + byte[] rgb = new byte[]{(byte)bg.getRed(), (byte)bg.getGreen(), (byte)bg.getBlue()}; + + fill.setFillBackgroundColor(new XSSFColor(rgb, null)); + fill.setFillPattern(PatternFormatting.SOLID_FOREGROUND); + + + // Define the range of cells to apply the rule + final CellRangeAddress[] regions = { CellRangeAddress.valueOf(condRegion) }; + + // Apply the conditional formatting rule to the sheet + sheetCF.addConditionalFormatting(regions, rule); + } + public Object getValue(final int row, final int col) { final Cell cell = getCell(row, col); return getValue(cell); @@ -666,7 +698,7 @@ public Map getCellStyleInfo(final int row, final int col) { if (cell != null) { final CellStyle style = cell.getCellStyle(); if (style != null) { - // Cell type + // Cell type info.put("cell.type", getCellType(cell.getCellType())); info.put("cell.col", col); info.put("cell.row", row); @@ -881,7 +913,7 @@ private Object getValue(final Cell cell) { final CellValue cellValue = evaluator.evaluate(cell); if (cellValue == null) { - return null; + return null; } switch (cellValue.getCellType()) { @@ -912,7 +944,7 @@ private String getString(final Cell cell) { final CellValue cellValue = evaluator.evaluate(cell); if (cellValue == null) { - return null; + return null; } switch (cellValue.getCellType()) { @@ -941,7 +973,7 @@ private Boolean getBoolean(final Cell cell) { final CellValue cellValue = evaluator.evaluate(cell); if (cellValue == null) { - return null; + return null; } if (cellValue.getCellType() == CellType.BLANK) { @@ -965,7 +997,7 @@ private Long getInteger(final Cell cell) { final CellValue cellValue = evaluator.evaluate(cell); if (cellValue == null) { - return null; + return null; } if (cellValue.getCellType() == CellType.BLANK) { @@ -989,7 +1021,7 @@ private Double getFloat(final Cell cell) { final CellValue cellValue = evaluator.evaluate(cell); if (cellValue == null) { - return null; + return null; } if (cellValue.getCellType() == CellType.BLANK) { diff --git a/src/main/java/com/github/jlangch/venice/util/excel/ExcelSheetFacade.java b/src/main/java/com/github/jlangch/venice/util/excel/ExcelSheetFacade.java index df94c38af..fd336229a 100644 --- a/src/main/java/com/github/jlangch/venice/util/excel/ExcelSheetFacade.java +++ b/src/main/java/com/github/jlangch/venice/util/excel/ExcelSheetFacade.java @@ -160,6 +160,14 @@ public void copyCellStyle( sheet.copyCellStyle(cellRowFrom1-1, cellColFrom1-1, cellRowTo1-1, cellColTo1-1); } + public void conditionalBackgroundColor( + final String condRule, // "ISBLANK(A1)" + final String condRegion, // "A1:B1" + final String bgColorHtml // "#CC636A" + ) { + sheet.conditionalBackgroundColor(condRule, condRegion, bgColorHtml); + } + public ExcelSheetFacade noHeader() { this.noHeader = true; return this; diff --git a/src/main/resources/com/github/jlangch/venice/excel.venice b/src/main/resources/com/github/jlangch/venice/excel.venice index 6fd376b97..418193d53 100644 --- a/src/main/resources/com/github/jlangch/venice/excel.venice +++ b/src/main/resources/com/github/jlangch/venice/excel.venice @@ -672,7 +672,7 @@ (defn ^{ :arglists '( "(copy-row sheet row-from row-to)" - "(copy-row sheet row copy-value copy-style)") + "(copy-row sheet row-from row-to copy-value copy-style)") :doc "Copies a specific row in a sheet." :examples '( @@ -817,6 +817,36 @@ (. sheet :copyCellStyle cell-from-row cell-from-col cell-to-row cell-to-col)) +(defn + ^{ :arglists '( + "(conditional-bg-color sheet rule region bg-color-html)") + :doc "Conditional background color" + :examples '( + """ + (do + (load-module :excel) + (let [wbook (excel/create :xlsx) + sheet (excel/add-sheet wbook "Sheet 1")] + (excel/write-values sheet 1 1 "John" "Doe" 28) + (excel/write-values sheet 2 1 "Sue" "Ford" 26) + (excel/conditional-bg-color sheet "ISBLANK(B1)" "B1:B99" "#CC636A") + (excel/auto-size-columns sheet) + (excel/write->file wbook "sample.xlsx"))) + """ ) + :see-also '( + "excel/clear-row", "excel/delete-row", + "excel/copy-row", "excel/copy-row-to-end", + "excel/write-items", "excel/write-item", "excel/cell-formula", + "excel/auto-size-columns", "excel/auto-size-column", + "excel/row-height") } + + conditional-bg-color [sheet rule region bg-color-html] + + { :pre [(instance-of? :ExcelSheetFacade sheet)] } + + (. sheet :conditionalBackgroundColor rule region bg-color-html)) + + ;; ----------------------------------------------------------------------------- ;; Images