Skip to content

Commit

Permalink
fix: apply colors from conditional formatting (#6824) (CP: 24.5)
Browse files Browse the repository at this point in the history
Co-authored-by: Sascha Ißbrücker <[email protected]>
  • Loading branch information
vaadin-bot and sissbruecker authored Nov 18, 2024
1 parent f40b91b commit 2334160
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ public class ColorConverterUtil implements Serializable {

public static String toRGBA(byte[] argb) {
int rgba[] = new int[3];
for (int i = 1; i < argb.length; i++) {
boolean hasAlpha = argb.length == 4;
float alpha = hasAlpha ? argb[0] : 1.0f;
int channelOffset = hasAlpha ? 1 : 0;

for (int i = channelOffset; i < argb.length; i++) {
int x = argb[i];
if (x < 0) {
x += 256;
}
rgba[i - 1] = x;
rgba[i - channelOffset] = x;
}

float x = argb[0];
return buildRgba(rgba, x);
return buildRgba(rgba, alpha);
}

public static String toRGBA(String hexARGB) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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()) {
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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
} catch (Exception e) {
LOGGER.debug(e.getMessage());
return null;
Expand Down
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");
}
}

0 comments on commit 2334160

Please sign in to comment.