-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: apply colors from conditional formatting #6824
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
import org.apache.poi.ss.usermodel.BorderFormatting; | ||
import org.apache.poi.ss.usermodel.CellStyle; | ||
import org.apache.poi.ss.usermodel.ConditionalFormattingRule; | ||
import org.apache.poi.ss.usermodel.IndexedColors; | ||
import org.apache.poi.xssf.model.ThemesTable; | ||
import org.apache.poi.xssf.usermodel.XSSFBorderFormatting; | ||
import org.apache.poi.xssf.usermodel.XSSFCellStyle; | ||
|
@@ -24,7 +25,6 @@ | |
import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder.BorderSide; | ||
import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill; | ||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; | ||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule; | ||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; | ||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxf; | ||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; | ||
|
@@ -288,6 +288,11 @@ public String getBackgroundColorCSS(ConditionalFormattingRule rule) { | |
|
||
// CF rules have tint in bgColor but not the XSSFColor. | ||
return styleColor(themeColor, bgColor.getTint()); | ||
} else if (bgColor.isSetIndexed()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This allows using an indexed color as font / background color. |
||
XSSFColor mappedColor = new XSSFColor( | ||
IndexedColors.fromInt((int) bgColor.getIndexed()), | ||
workbook.getStylesSource().getIndexedColors()); | ||
return styleColor(mappedColor, bgColor.getTint()); | ||
} else { | ||
byte[] rgb = bgColor.getRgb(); | ||
return rgb == null ? null : ColorConverterUtil.toRGBA(rgb); | ||
|
@@ -320,6 +325,11 @@ public String getFontColorCSS(ConditionalFormattingRule rule) { | |
.getThemeColor((int) ctColor.getTheme()); | ||
|
||
return styleColor(themeColor, ctColor.getTint()); | ||
} else if (ctColor.isSetIndexed()) { | ||
XSSFColor mappedColor = new XSSFColor( | ||
IndexedColors.fromInt((int) ctColor.getIndexed()), | ||
workbook.getStylesSource().getIndexedColors()); | ||
return styleColor(mappedColor, ctColor.getTint()); | ||
} else { | ||
byte[] rgb = ctColor.getRgb(); | ||
return rgb == null ? null : ColorConverterUtil.toRGBA(rgb); | ||
|
@@ -405,16 +415,12 @@ private byte applyTint(int lum, double tint) { | |
*/ | ||
private CTDxf getXMLColorDataWithReflection( | ||
XSSFConditionalFormattingRule rule) { | ||
CTCfRule realRule = null; | ||
|
||
Method declaredMethod = null; | ||
try { | ||
declaredMethod = rule.getClass().getDeclaredMethod("getCTCfRule"); | ||
declaredMethod = rule.getClass().getDeclaredMethod("getDxf", | ||
boolean.class); | ||
declaredMethod.setAccessible(true); | ||
realRule = (CTCfRule) declaredMethod.invoke(rule); | ||
CTDxf dxf = workbook.getStylesSource().getCTStylesheet().getDxfs() | ||
.getDxfArray((int) realRule.getDxfId()); | ||
return dxf; | ||
return (CTDxf) declaredMethod.invoke(rule, false); | ||
Comment on lines
+420
to
+423
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the main part of the fix which allows to retrieve the font and background pattern config from the conditional formatting rule. |
||
} catch (Exception e) { | ||
LOGGER.debug(e.getMessage()); | ||
return null; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/** | ||
* Copyright 2000-2024 Vaadin Ltd. | ||
* | ||
* This program is available under Vaadin Commercial License and Service Terms. | ||
* | ||
* See {@literal <https://vaadin.com/commercial-license-and-service-terms>} for the full | ||
* license. | ||
*/ | ||
package com.vaadin.flow.component.spreadsheet.tests; | ||
|
||
import org.apache.poi.ss.usermodel.ComparisonOperator; | ||
import org.apache.poi.ss.usermodel.ConditionalFormattingRule; | ||
import org.apache.poi.ss.usermodel.IndexedColors; | ||
import org.apache.poi.xssf.usermodel.XSSFColor; | ||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; | ||
import org.junit.Assert; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import com.vaadin.flow.component.spreadsheet.Spreadsheet; | ||
import com.vaadin.flow.component.spreadsheet.XSSFColorConverter; | ||
|
||
public class XSSFColorConverterTest { | ||
|
||
private Spreadsheet spreadsheet; | ||
private XSSFColorConverter converter; | ||
|
||
@Before | ||
public void setUp() { | ||
spreadsheet = new Spreadsheet(); | ||
converter = new XSSFColorConverter( | ||
(XSSFWorkbook) spreadsheet.getWorkbook()); | ||
} | ||
|
||
@Test | ||
public void getFontColorCSS_withIndexedColor() { | ||
var rule = createRule(); | ||
var font = rule.createFontFormatting(); | ||
font.setFontColorIndex(IndexedColors.RED.index); | ||
|
||
var cssColor = converter.getFontColorCSS(rule); | ||
|
||
Assert.assertEquals("rgba(255, 0, 0, 1.0);", cssColor); | ||
} | ||
|
||
@Test | ||
public void getFontColorCSS_withRgbColor() { | ||
var rule = createRule(); | ||
var font = rule.createFontFormatting(); | ||
var color = new XSSFColor( | ||
new byte[] { (byte) 255, (byte) 128, (byte) 64 }); | ||
font.setFontColor(color); | ||
|
||
var cssColor = converter.getFontColorCSS(rule); | ||
|
||
Assert.assertEquals("rgba(255, 128, 64, 1.0);", cssColor); | ||
} | ||
|
||
@Test | ||
public void getBackgroundColorCSS_withIndexedColor() { | ||
var rule = createRule(); | ||
var pattern = rule.createPatternFormatting(); | ||
pattern.setFillBackgroundColor(IndexedColors.RED.index); | ||
|
||
var cssColor = converter.getBackgroundColorCSS(rule); | ||
|
||
Assert.assertEquals("rgba(255, 0, 0, 1.0);", cssColor); | ||
} | ||
|
||
@Test | ||
public void getBackgroundColorCSS_withRgbColor() { | ||
var rule = createRule(); | ||
var pattern = rule.createPatternFormatting(); | ||
var color = new XSSFColor( | ||
new byte[] { (byte) 255, (byte) 128, (byte) 64 }); | ||
pattern.setFillBackgroundColor(color); | ||
|
||
var cssColor = converter.getBackgroundColorCSS(rule); | ||
|
||
Assert.assertEquals("rgba(255, 128, 64, 1.0);", cssColor); | ||
} | ||
|
||
private ConditionalFormattingRule createRule() { | ||
var conditionalFormatting = spreadsheet.getActiveSheet() | ||
.getSheetConditionalFormatting(); | ||
return conditionalFormatting | ||
.createConditionalFormattingRule(ComparisonOperator.LT, "0"); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently XSSFColor can either hold a byte array with three elements for an RGB color or an array with four elements for an ARGB color. This fixes the logic to also handle RGB byte arrays.