From 0a23c86b927b565c5504c2751ff06734dba71359 Mon Sep 17 00:00:00 2001 From: jlangch Date: Wed, 4 Sep 2024 20:02:14 +0200 Subject: [PATCH] enhanced excel module --- .../com/github/jlangch/venice/Venice.java | 22 +++++-- .../venice/impl/util/excel/ExcelSheet.java | 52 ++++++++++++--- .../venice/util/excel/ExcelSheetFacade.java | 21 ++++++- .../com/github/jlangch/venice/excel.venice | 63 +++++++++++++++++-- 4 files changed, 140 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/github/jlangch/venice/Venice.java b/src/main/java/com/github/jlangch/venice/Venice.java index b7f8c34ed9..d6f13726c2 100644 --- a/src/main/java/com/github/jlangch/venice/Venice.java +++ b/src/main/java/com/github/jlangch/venice/Venice.java @@ -53,6 +53,7 @@ import com.github.jlangch.venice.impl.types.concurrent.Agent; import com.github.jlangch.venice.impl.util.MeterRegistry; import com.github.jlangch.venice.impl.util.StringUtil; +import com.github.jlangch.venice.impl.util.io.ClassPathResource; import com.github.jlangch.venice.javainterop.AcceptAllInterceptor; import com.github.jlangch.venice.javainterop.IInterceptor; import com.github.jlangch.venice.util.FunctionExecutionMeter; @@ -118,6 +119,9 @@ public IPreCompiled precompile( throw new IllegalArgumentException("A 'script' must not be blank"); } + + final String scriptEff = resolveScript(script); + final long startTime = System.currentTimeMillis(); final ThreadContext tc = ThreadContext.get(); @@ -133,7 +137,7 @@ public IPreCompiled precompile( .setStderrPrintStream(null) .setStdinReader(null); - VncVal ast = venice.READ(script, scriptName); + VncVal ast = venice.READ(scriptEff, scriptName); if (macroexpand) { ast = venice.MACROEXPAND(ast, env); } @@ -146,7 +150,7 @@ public IPreCompiled precompile( return new PreCompiled( scriptName, - script, + scriptEff, ast, macroexpand, // remember for runtime nsRegistry, @@ -311,6 +315,7 @@ public Object eval( throw new IllegalArgumentException("A 'script' must not be blank"); } + final String scriptEff = resolveScript(script); final long nanos = System.nanoTime(); @@ -329,7 +334,7 @@ public Object eval( meterRegistry.reset(); // no metrics for creating env and loading modules meterRegistry.record("venice.setup", System.nanoTime() - nanos); - final VncVal result = venice.RE(script, scriptName, env); + final VncVal result = venice.RE(scriptEff, scriptName, env); final Object jResult = result.convertToJavaObject(); meterRegistry.record("venice.total", System.nanoTime() - nanos); @@ -579,8 +584,17 @@ private SymbolTable getCoreSystemGlobalSymbols() { } return symbols; - } + } + private String resolveScript(final String script) { + if (script.startsWith("classpath:")) { + return new ClassPathResource(script.substring("classpath:".length())) + .getResourceAsString("UTF-8"); + } + else { + return script; + } + } private static ManagedCachedThreadPoolExecutor mngdExecutor = new ManagedCachedThreadPoolExecutor("venice-timeout-pool", 100); 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 e8afebbb72..9be65e9020 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 @@ -50,6 +50,7 @@ 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.FontFormatting; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.PatternFormatting; import org.apache.poi.ss.usermodel.Picture; @@ -312,31 +313,68 @@ public void copyCellStyle( public void addConditionalBackgroundColor( final String condRule, // "ISBLANK(A1)" - final String bgColorHtml, // "#CC636A" + final String colorHtml, // "#CC636A" final int regionFirstRow, final int regionLastRow, final int regionFirstCol, final int regionLastCol ) { + if (!(sheet instanceof XSSFSheet)) { + throw new RuntimeException("conditional background colors are available for XLSX documents only!"); + } // Create a conditional formatting rule for blank cells final SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); - // Define a conditional formatting rule using a formula (ISBLANK(A1)) + // 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()}; + final Color color = HtmlColor.getColor(colorHtml); + byte[] rgbColor = new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()}; - fill.setFillBackgroundColor(new XSSFColor(rgb, null)); + fill.setFillBackgroundColor(new XSSFColor(rgbColor, null)); fill.setFillPattern(PatternFormatting.SOLID_FOREGROUND); // Define the range of cells to apply the rule final CellRangeAddress[] regions = { new CellRangeAddress( - regionFirstRow, regionLastRow, - regionFirstCol, regionLastCol) }; + regionFirstRow, regionLastRow, + regionFirstCol, regionLastCol) }; + + // Apply the conditional formatting rule to the sheet + sheetCF.addConditionalFormatting(regions, rule); + } + + public void addConditionalFontColor( + final String condRule, // "$A$1 > 5" + final String colorHtml, // "#CC636A" + final int regionFirstRow, + final int regionLastRow, + final int regionFirstCol, + final int regionLastCol + ) { + if (!(sheet instanceof XSSFSheet)) { + throw new RuntimeException("conditional font colors are available for XLSX documents only!"); + } + + // Create a conditional formatting rule for blank cells + final SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); + + // Define a conditional formatting rule using a formula "$A$1 > 5" + final ConditionalFormattingRule rule = sheetCF.createConditionalFormattingRule(condRule); + + FontFormatting fontFmt = rule.createFontFormatting(); + + final Color color = HtmlColor.getColor(colorHtml); + byte[] rgbColor = new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()}; + + fontFmt.setFontColor(new XSSFColor(rgbColor, null)); + + // Define the range of cells to apply the rule + final CellRangeAddress[] regions = { new CellRangeAddress( + regionFirstRow, regionLastRow, + regionFirstCol, regionLastCol) }; // Apply the conditional formatting rule to the sheet sheetCF.addConditionalFormatting(regions, rule); 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 d39e3a02d9..1abf7859c1 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 @@ -162,7 +162,7 @@ public void copyCellStyle( public void addConditionalBackgroundColor( final String condRule, // "ISBLANK(A1)" - final String bgColorHtml, // "#CC636A" + final String colorHtml, // "#CC636A" final int regionFirstRow1, final int regionLastRow1, final int regionFirstCol1, @@ -170,7 +170,24 @@ public void addConditionalBackgroundColor( ) { sheet.addConditionalBackgroundColor( condRule, - bgColorHtml, + colorHtml, + regionFirstRow1-1, + regionLastRow1-1, + regionFirstCol1-1, + regionLastCol1-1); + } + + public void addConditionalFontColor( + final String condRule, // "$A$1 > 5" + final String colorHtml, // "#CC636A" + final int regionFirstRow1, + final int regionLastRow1, + final int regionFirstCol1, + final int regionLastCol1 + ) { + sheet.addConditionalFontColor( + condRule, + colorHtml, regionFirstRow1-1, regionLastRow1-1, regionFirstCol1-1, diff --git a/src/main/resources/com/github/jlangch/venice/excel.venice b/src/main/resources/com/github/jlangch/venice/excel.venice index 873eee7d09..87b24df568 100644 --- a/src/main/resources/com/github/jlangch/venice/excel.venice +++ b/src/main/resources/com/github/jlangch/venice/excel.venice @@ -822,7 +822,7 @@ """ (add-conditional-bg-color sheet rule - bg-color-html + color-html region-first-row region-last-row region-first-col @@ -849,22 +849,75 @@ "excel/row-height") } add-conditional-bg-color [sheet - rule bg-color-html - region-first-row region-last-row - region-first-col region-last-col] + rule color-html + region-first-row region-last-row + region-first-col region-last-col] { :pre [(instance-of? :ExcelSheetFacade sheet) + (string? rule) + (string? color-html) (long? region-first-row) (pos? region-first-row) (long? region-last-row) (pos? region-last-row) (long? region-first-col) (pos? region-first-col) (long? region-last-col) (pos? region-last-col)] } (. sheet :addConditionalBackgroundColor rule - bg-color-html + color-html region-first-row region-last-row region-first-col region-last-col)) +(defn + ^{ :arglists '( + """ + (add-conditional-font-color sheet + rule + color-html + region-first-row + region-last-row + region-first-col + region-last-col) + """) + :doc "Add a conditional font 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" 45) + (excel/write-values sheet 2 1 "Sue" "Ford" 26) + (excel/add-conditional-font-color sheet "C1 > 30" "#CC636A" 1 1 3 3) + (excel/add-conditional-font-color sheet "C2 > 30" "#CC636A" 2 2 3 3) + (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") } + + add-conditional-font-color [sheet + rule color-html + region-first-row region-last-row + region-first-col region-last-col] + + { :pre [(instance-of? :ExcelSheetFacade sheet) + (string? rule) + (string? color-html) + (long? region-first-row) (pos? region-first-row) + (long? region-last-row) (pos? region-last-row) + (long? region-first-col) (pos? region-first-col) + (long? region-last-col) (pos? region-last-col)] } + + (. sheet :addConditionalFontColor rule + color-html + region-first-row region-last-row + region-first-col region-last-col)) + + (defn ^{ :arglists '( """