From: Nick Burch Date: Mon, 20 Jul 2015 02:49:12 +0000 (+0000) Subject: #58130 Support for creating CF Color Scale Formattings X-Git-Tag: REL_3_13_FINAL~221 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=85da2c3069abbf5404f43b31e7d5dc576ec26b53;p=poi.git #58130 Support for creating CF Color Scale Formattings git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1691866 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java b/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java index dd1398b860..fa01148cea 100644 --- a/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java +++ b/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java @@ -56,8 +56,9 @@ public class ConditionalFormats { shadeAlt(wb.createSheet("Shade Alt")); shadeBands(wb.createSheet("Shade Bands")); iconSets(wb.createSheet("Icon Sets")); + colourScales(wb.createSheet("Colour Scales")); - // TODO Add colour scales, data bars etc, see bug #58130 + // TODO Add data bars, see bug #58130 // Write the output to a file String file = "cf-poi.xls"; @@ -439,7 +440,7 @@ public class ConditionalFormats { r.createCell(1).setCellValue(10); r.createCell(2).setCellValue(10); r.createCell(3).setCellValue(10); - + SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); CellRangeAddress[] regions = { CellRangeAddress.valueOf("B1:B4") }; @@ -476,4 +477,68 @@ public class ConditionalFormats { im3.getThresholds()[2].setValue(7d); sheetCF.addConditionalFormatting(regions, rule3); } + + /** + * Color Scales / Colour Scales / Colour Gradients allow you shade the + * background colour of the cell based on the values, eg from Red to + * Yellow to Green. + */ + static void colourScales(Sheet sheet) { + sheet.createRow(0).createCell(0).setCellValue("Colour Scales"); + Row r = sheet.createRow(1); + r.createCell(0).setCellValue("Red-Yellow-Green"); + for (int i=1; i<=7; i++) { + r.createCell(i).setCellValue((i-1)*5); + } + r = sheet.createRow(2); + r.createCell(0).setCellValue("Red-White-Blue"); + for (int i=1; i<=9; i++) { + r.createCell(i).setCellValue((i-1)*5); + } + r = sheet.createRow(3); + r.createCell(0).setCellValue("Blue-Green"); + for (int i=1; i<=16; i++) { + r.createCell(i).setCellValue((i-1)); + } + sheet.setColumnWidth(0, 5000); + + SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); + + CellRangeAddress[] regions = { CellRangeAddress.valueOf("B2:H2") }; + ConditionalFormattingRule rule1 = + sheetCF.createConditionalFormattingColorScaleRule(); + ColorScaleFormatting cs1 = rule1.getColorScaleFormatting(); + cs1.getThresholds()[0].setRangeType(RangeType.MIN); + cs1.getThresholds()[1].setRangeType(RangeType.PERCENTILE); + cs1.getThresholds()[1].setValue(50d); + cs1.getThresholds()[2].setRangeType(RangeType.MAX); + ((ExtendedColor)cs1.getColors()[0]).setARGBHex("FFF8696B"); + ((ExtendedColor)cs1.getColors()[1]).setARGBHex("FFFFEB84"); + ((ExtendedColor)cs1.getColors()[2]).setARGBHex("FF63BE7B"); + sheetCF.addConditionalFormatting(regions, rule1); + + regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B3:J3") }; + ConditionalFormattingRule rule2 = + sheetCF.createConditionalFormattingColorScaleRule(); + ColorScaleFormatting cs2 = rule2.getColorScaleFormatting(); + cs2.getThresholds()[0].setRangeType(RangeType.MIN); + cs2.getThresholds()[1].setRangeType(RangeType.PERCENTILE); + cs2.getThresholds()[1].setValue(50d); + cs2.getThresholds()[2].setRangeType(RangeType.MAX); + ((ExtendedColor)cs2.getColors()[0]).setARGBHex("FFF8696B"); + ((ExtendedColor)cs2.getColors()[1]).setARGBHex("FFFCFCFF"); + ((ExtendedColor)cs2.getColors()[2]).setARGBHex("FF5A8AC6"); + sheetCF.addConditionalFormatting(regions, rule2); + + regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B4:Q4") }; + ConditionalFormattingRule rule3= + sheetCF.createConditionalFormattingColorScaleRule(); + ColorScaleFormatting cs3 = rule3.getColorScaleFormatting(); + cs3.setNumControlPoints(2); + cs3.getThresholds()[0].setRangeType(RangeType.MIN); + cs3.getThresholds()[1].setRangeType(RangeType.MAX); + ((ExtendedColor)cs3.getColors()[0]).setARGBHex("FF5A8AC6"); + ((ExtendedColor)cs3.getColors()[1]).setARGBHex("FF63BE7B"); + sheetCF.addConditionalFormatting(regions, rule3); + } } diff --git a/src/java/org/apache/poi/hssf/record/CFRule12Record.java b/src/java/org/apache/poi/hssf/record/CFRule12Record.java index 80a31b3213..359f6c3a8f 100644 --- a/src/java/org/apache/poi/hssf/record/CFRule12Record.java +++ b/src/java/org/apache/poi/hssf/record/CFRule12Record.java @@ -20,9 +20,11 @@ package org.apache.poi.hssf.record; import java.util.Arrays; import org.apache.poi.hssf.record.cf.ColorGradientFormatting; +import org.apache.poi.hssf.record.cf.ColorGradientThreshold; import org.apache.poi.hssf.record.cf.IconMultiStateFormatting; import org.apache.poi.hssf.record.cf.IconMultiStateThreshold; import org.apache.poi.hssf.record.cf.Threshold; +import org.apache.poi.hssf.record.common.ExtendedColor; import org.apache.poi.hssf.record.common.FtrHeader; import org.apache.poi.hssf.record.common.FutureRecord; import org.apache.poi.hssf.usermodel.HSSFSheet; @@ -129,14 +131,34 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord { ts[i] = new IconMultiStateThreshold(); } - CFRule12Record r = new CFRule12Record(CONDITION_TYPE_COLOR_SCALE, + CFRule12Record r = new CFRule12Record(CONDITION_TYPE_ICON_SET, ComparisonOperator.NO_COMPARISON); IconMultiStateFormatting imf = r.createMultiStateFormatting(); imf.setIconSet(iconSet); imf.setThresholds(ts); return r; } - // TODO Static creators for the other record types + /** + * Creates a new Color Scale / Color Gradient formatting + */ + public static CFRule12Record createColorScale(HSSFSheet sheet) { + int numPoints = 3; + ExtendedColor[] colors = new ExtendedColor[numPoints]; + ColorGradientThreshold[] ts = new ColorGradientThreshold[numPoints]; + for (int i=0; iThe thresholds and colours for it will be created, but will be + * empty and require configuring with + * {@link HSSFConditionalFormattingRule#getColorScaleFormatting()} + * then + * {@link HSSFColorScaleFormatting#getThresholds()} + * and + * {@link HSSFColorScaleFormatting#getColors()} + */ + public HSSFConditionalFormattingRule createConditionalFormattingColorScaleRule() { + CFRule12Record rr = CFRule12Record.createColorScale(_sheet); + return new HSSFConditionalFormattingRule(_sheet, rr); + } + + /** + * Create a Databar conditional formatting rule. + *

The thresholds and colour for it will be created, but will be + * empty and require configuring with + * {@link HSSFConditionalFormattingRule#getDataBarFormatting()} + * then + * {@link HSSFDataBarFormatting#getMinThreshold()} + * and + * {@link HSSFDataBarFormatting#getMaxThreshold()} + * and + * {@link HSSFDataBarFormatting#getColor()} + */ + public HSSFConditionalFormattingRule createConditionalFormattingDataBarRule() { + throw new IllegalStateException("Not Implemented Yet!"); // TODO Implement + } /** * Adds a copy of HSSFConditionalFormatting object to the sheet diff --git a/src/java/org/apache/poi/ss/usermodel/ExtendedColor.java b/src/java/org/apache/poi/ss/usermodel/ExtendedColor.java index 30f296fd11..eaab553ace 100644 --- a/src/java/org/apache/poi/ss/usermodel/ExtendedColor.java +++ b/src/java/org/apache/poi/ss/usermodel/ExtendedColor.java @@ -79,7 +79,7 @@ public abstract class ExtendedColor implements Color { */ public abstract void setRGB(byte[] rgb); - protected byte[] getRGBOrARGB() { + protected byte[] getRGBOrARGB() { byte[] rgb = null; if (isIndexed() && getIndex() > 0) { @@ -97,7 +97,7 @@ public abstract class ExtendedColor implements Color { // Grab the colour rgb = getStoredRBG(); return rgb; - } + } /** * Standard Red Green Blue ctColor value (RGB) with applied tint. @@ -138,6 +138,23 @@ public abstract class ExtendedColor implements Color { } return sb.toString().toUpperCase(); } + + /** + * Sets the ARGB value from hex format, eg FF0077FF. + * Only works for regular (non-indexed) colours + */ + public void setARGBHex(String argb) { + if (argb.length() == 6 || argb.length() == 8) { + byte[] rgb = new byte[argb.length()/2]; + for (int i=0; i 0){ diff --git a/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java b/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java index a28c342a74..e8f7ea4d73 100644 --- a/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java +++ b/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java @@ -146,7 +146,31 @@ public interface SheetConditionalFormatting { */ ConditionalFormattingRule createConditionalFormattingRule(IconSet iconSet); - // TODO Support types beyond CELL_VALUE_IS and FORMULA and ICONs + /** + * Create a Color Scale / Color Gradient conditional formatting rule. + *

The thresholds and colours for it will be created, but will be + * empty and require configuring with + * {@link ConditionalFormattingRule#getColorScaleFormatting()} + * then + * {@link ColorScaleFormatting#getThresholds()} + * and + * {@link ColorScaleFormatting#getColors()} + */ + ConditionalFormattingRule createConditionalFormattingColorScaleRule(); + + /** + * Create a Databar conditional formatting rule. + *

The thresholds and colour for it will be created, but will be + * empty and require configuring with + * {@link ConditionalFormattingRule#getDataBarFormatting()} + * then + * {@link DataBarFormatting#getMinThreshold()} + * and + * {@link DataBarFormatting#getMaxThreshold()} + * and + * {@link DataBarFormatting#getColor()} + */ + ConditionalFormattingRule createConditionalFormattingDataBarRule(); /** * Gets Conditional Formatting object at a particular index diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java index afd8885e1b..ae77b02d04 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java @@ -138,7 +138,41 @@ public class XSSFSheetConditionalFormatting implements SheetConditionalFormattin return rule; } - // TODO Support types beyond CELL_VALUE_IS and FORMULA and ICONs + /** + * Create a Color Scale / Color Gradient conditional formatting rule. + *

The thresholds and colours for it will be created, but will be + * empty and require configuring with + * {@link XSSFConditionalFormattingRule#getColorScaleFormatting()} + * then + * {@link XSSFColorScaleFormatting#getThresholds()} + * and + * {@link XSSFColorScaleFormatting#getColors()} + */ + public XSSFConditionalFormattingRule createConditionalFormattingColorScaleRule() { + XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet); + + // Have it setup, with suitable defaults + rule.createColorScaleFormatting(); + + // All done! + return rule; + } + + /** + * Create a Databar conditional formatting rule. + *

The thresholds and colour for it will be created, but will be + * empty and require configuring with + * {@link XSSFConditionalFormattingRule#getDataBarFormatting()} + * then + * {@link XSSFDataBarFormatting#getMinThreshold()} + * and + * {@link XSSFDataBarFormatting#getMaxThreshold()} + * and + * {@link XSSFDataBarFormatting#getColor()} + */ + public XSSFConditionalFormattingRule createConditionalFormattingDataBarRule() { + throw new IllegalStateException("Not Implemented Yet!"); // TODO Implement + } @SuppressWarnings("deprecation") public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) { diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java index 191e703898..241a2efcb0 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java @@ -1048,6 +1048,7 @@ public abstract class BaseTestConditionalFormatting extends TestCase { ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0); assertEquals(1, cf.getNumberOfRules()); rule1 = cf.getRule(0); + assertEquals(ConditionType.ICON_SET, rule1.getConditionTypeType()); iconFmt = rule1.getMultiStateFormatting(); assertEquals(IconSet.GYRB_4_TRAFFIC_LIGHTS, iconFmt.getIconSet()); @@ -1066,8 +1067,49 @@ public abstract class BaseTestConditionalFormatting extends TestCase { } public void testCreateColorScaleFormatting() { - // TODO Implement then test + Workbook workbook = _testDataProvider.createWorkbook(); + Sheet sheet = workbook.createSheet(); + + SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); + ConditionalFormattingRule rule1 = + sheetCF.createConditionalFormattingColorScaleRule(); + ColorScaleFormatting clrFmt = rule1.getColorScaleFormatting(); + + assertEquals(3, clrFmt.getNumControlPoints()); + assertEquals(3, clrFmt.getColors().length); + assertEquals(3, clrFmt.getThresholds().length); + + clrFmt.getThresholds()[0].setRangeType(RangeType.MIN); + clrFmt.getThresholds()[1].setRangeType(RangeType.NUMBER); + clrFmt.getThresholds()[1].setValue(10d); + clrFmt.getThresholds()[2].setRangeType(RangeType.MAX); + + CellRangeAddress [] regions = { CellRangeAddress.valueOf("A1:A5") }; + sheetCF.addConditionalFormatting(regions, rule1); + + // Save, re-load and re-check + workbook = _testDataProvider.writeOutAndReadBack(workbook); + sheetCF = sheet.getSheetConditionalFormatting(); + assertEquals(1, sheetCF.getNumConditionalFormattings()); + + ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0); + assertEquals(1, cf.getNumberOfRules()); + rule1 = cf.getRule(0); + clrFmt = rule1.getColorScaleFormatting(); + assertEquals(ConditionType.COLOR_SCALE, rule1.getConditionTypeType()); + + assertEquals(3, clrFmt.getNumControlPoints()); + assertEquals(3, clrFmt.getColors().length); + assertEquals(3, clrFmt.getThresholds().length); + + assertEquals(RangeType.MIN, clrFmt.getThresholds()[0].getRangeType()); + assertEquals(RangeType.NUMBER, clrFmt.getThresholds()[1].getRangeType()); + assertEquals(RangeType.MAX, clrFmt.getThresholds()[2].getRangeType()); + assertEquals(null, clrFmt.getThresholds()[0].getValue()); + assertEquals(10d, clrFmt.getThresholds()[1].getValue()); + assertEquals(null, clrFmt.getThresholds()[2].getValue()); } + public void testCreateDataBarFormatting() { // TODO Implement then test }