]> source.dussan.org Git - poi.git/commitdiff
#58130 Support for creating CF Color Scale Formattings
authorNick Burch <nick@apache.org>
Mon, 20 Jul 2015 02:49:12 +0000 (02:49 +0000)
committerNick Burch <nick@apache.org>
Mon, 20 Jul 2015 02:49:12 +0000 (02:49 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1691866 13f79535-47bb-0310-9956-ffa450edef68

src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java
src/java/org/apache/poi/hssf/record/CFRule12Record.java
src/java/org/apache/poi/hssf/record/cf/ColorGradientThreshold.java
src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java
src/java/org/apache/poi/ss/usermodel/ExtendedColor.java
src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java

index dd1398b8607ca427df85d62f74ca93dcad3489d7..fa01148cea4a1c743070496fc2d60b41c24209d5 100644 (file)
@@ -56,8 +56,9 @@ public class ConditionalFormats {
         shadeAlt(wb.createSheet("Shade Alt"));\r
         shadeBands(wb.createSheet("Shade Bands"));\r
         iconSets(wb.createSheet("Icon Sets"));\r
+        colourScales(wb.createSheet("Colour Scales"));\r
         \r
-        // TODO Add colour scales, data bars etc, see bug #58130\r
+        // TODO Add data bars, see bug #58130\r
 \r
         // Write the output to a file\r
         String file = "cf-poi.xls";\r
@@ -439,7 +440,7 @@ public class ConditionalFormats {
         r.createCell(1).setCellValue(10);\r
         r.createCell(2).setCellValue(10);\r
         r.createCell(3).setCellValue(10);\r
-                \r
+\r
         SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
         \r
         CellRangeAddress[] regions = { CellRangeAddress.valueOf("B1:B4") };\r
@@ -476,4 +477,68 @@ public class ConditionalFormats {
         im3.getThresholds()[2].setValue(7d);\r
         sheetCF.addConditionalFormatting(regions, rule3);\r
     }\r
+    \r
+    /**\r
+     * Color Scales / Colour Scales / Colour Gradients allow you shade the\r
+     *  background colour of the cell based on the values, eg from Red to\r
+     *  Yellow to Green.\r
+     */\r
+    static void colourScales(Sheet sheet) {\r
+        sheet.createRow(0).createCell(0).setCellValue("Colour Scales");\r
+        Row r = sheet.createRow(1);\r
+        r.createCell(0).setCellValue("Red-Yellow-Green");\r
+        for (int i=1; i<=7; i++) {\r
+            r.createCell(i).setCellValue((i-1)*5);\r
+        }\r
+        r = sheet.createRow(2);\r
+        r.createCell(0).setCellValue("Red-White-Blue");\r
+        for (int i=1; i<=9; i++) {\r
+            r.createCell(i).setCellValue((i-1)*5);\r
+        }\r
+        r = sheet.createRow(3);\r
+        r.createCell(0).setCellValue("Blue-Green");\r
+        for (int i=1; i<=16; i++) {\r
+            r.createCell(i).setCellValue((i-1));\r
+        }\r
+        sheet.setColumnWidth(0, 5000);\r
+        \r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+        \r
+        CellRangeAddress[] regions = { CellRangeAddress.valueOf("B2:H2") };\r
+        ConditionalFormattingRule rule1 =\r
+                sheetCF.createConditionalFormattingColorScaleRule();\r
+        ColorScaleFormatting cs1 = rule1.getColorScaleFormatting();\r
+        cs1.getThresholds()[0].setRangeType(RangeType.MIN);\r
+        cs1.getThresholds()[1].setRangeType(RangeType.PERCENTILE);\r
+        cs1.getThresholds()[1].setValue(50d);\r
+        cs1.getThresholds()[2].setRangeType(RangeType.MAX);\r
+        ((ExtendedColor)cs1.getColors()[0]).setARGBHex("FFF8696B");\r
+        ((ExtendedColor)cs1.getColors()[1]).setARGBHex("FFFFEB84");\r
+        ((ExtendedColor)cs1.getColors()[2]).setARGBHex("FF63BE7B");\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+        \r
+        regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B3:J3") };\r
+        ConditionalFormattingRule rule2 =\r
+                sheetCF.createConditionalFormattingColorScaleRule();\r
+        ColorScaleFormatting cs2 = rule2.getColorScaleFormatting();\r
+        cs2.getThresholds()[0].setRangeType(RangeType.MIN);\r
+        cs2.getThresholds()[1].setRangeType(RangeType.PERCENTILE);\r
+        cs2.getThresholds()[1].setValue(50d);\r
+        cs2.getThresholds()[2].setRangeType(RangeType.MAX);\r
+        ((ExtendedColor)cs2.getColors()[0]).setARGBHex("FFF8696B");\r
+        ((ExtendedColor)cs2.getColors()[1]).setARGBHex("FFFCFCFF");\r
+        ((ExtendedColor)cs2.getColors()[2]).setARGBHex("FF5A8AC6");\r
+        sheetCF.addConditionalFormatting(regions, rule2);\r
+        \r
+        regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B4:Q4") };\r
+        ConditionalFormattingRule rule3=\r
+                sheetCF.createConditionalFormattingColorScaleRule();\r
+        ColorScaleFormatting cs3 = rule3.getColorScaleFormatting();\r
+        cs3.setNumControlPoints(2);\r
+        cs3.getThresholds()[0].setRangeType(RangeType.MIN);\r
+        cs3.getThresholds()[1].setRangeType(RangeType.MAX);\r
+        ((ExtendedColor)cs3.getColors()[0]).setARGBHex("FF5A8AC6");\r
+        ((ExtendedColor)cs3.getColors()[1]).setARGBHex("FF63BE7B");\r
+        sheetCF.addConditionalFormatting(regions, rule3);\r
+    }\r
 }\r
index 80a31b321349fb1b1afa2897bab3e403e8777885..359f6c3a8f6deb5d3eb00f19d145b4219a38de48 100644 (file)
@@ -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; i<ts.length; i++) {
+            ts[i] = new ColorGradientThreshold();
+            colors[i] = new ExtendedColor();
+        }
+        
+        CFRule12Record r = new CFRule12Record(CONDITION_TYPE_COLOR_SCALE, 
+                                              ComparisonOperator.NO_COMPARISON);
+        ColorGradientFormatting cgf = r.createColorGradientFormatting();
+        cgf.setNumControlPoints(numPoints);
+        cgf.setThresholds(ts);
+        cgf.setColors(colors);
+        return r;
+    }
+    // TODO Static creators for Data Bars
 
     public CFRule12Record(RecordInputStream in) {
         futureHeader = new FtrHeader(in);
index 934cb68e57b2e618da57182de148cd3b2a65c370..32eba56e4c713ddbc1a494547a297f9640ca4925 100644 (file)
@@ -32,7 +32,7 @@ public final class ColorGradientThreshold extends Threshold {
         position = 0d;
     }
 
-    /** Creates new Ico Multi-State Threshold */
+    /** Creates new Color Gradient Threshold */
     public ColorGradientThreshold(LittleEndianInput in) {
         super(in);
         position = in.readDouble();
index deca836a0c98a8e168ab409d2cace86e00334131..13032c2fbcae63c3c8f7e0bf0ce996a5431cd67d 100644 (file)
@@ -106,7 +106,36 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
         return new HSSFConditionalFormattingRule(_sheet, rr);
     }
 
-    // TODO Support types beyond CELL_VALUE_IS and FORMULA and ICONs
+    /**
+     * Create a Color Scale / Color Gradient conditional formatting rule.
+     * <p>The 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.
+     * <p>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
index 30f296fd11d08c38773b50e13aab0592ee67861c..eaab553ace9375c646e73cba464be7b7617766c4 100644 (file)
@@ -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<rgb.length; i++) {
+                String part = argb.substring(i*2,(i+1)*2);
+                rgb[i] = (byte)Integer.parseInt(part, 16);
+            }
+            setRGB(rgb);
+        } else {
+            throw new IllegalArgumentException("Must be of the form 112233 or FFEEDDCC");
+        }
+    }
 
     private static byte applyTint(int lum, double tint){
         if(tint > 0){
index a28c342a74a3364e5b9667905c29d58b9f80d19b..e8f7ea4d7390108439b749f38bbf4f0785f516da 100644 (file)
@@ -146,7 +146,31 @@ public interface SheetConditionalFormatting {
      */\r
     ConditionalFormattingRule createConditionalFormattingRule(IconSet iconSet);\r
 \r
-    // TODO Support types beyond CELL_VALUE_IS and FORMULA and ICONs\r
+    /**\r
+     * Create a Color Scale / Color Gradient conditional formatting rule.\r
+     * <p>The thresholds and colours for it will be created, but will be \r
+     *  empty and require configuring with \r
+     *  {@link ConditionalFormattingRule#getColorScaleFormatting()}\r
+     *  then\r
+     *  {@link ColorScaleFormatting#getThresholds()}\r
+     *  and\r
+     *  {@link ColorScaleFormatting#getColors()}\r
+     */\r
+    ConditionalFormattingRule createConditionalFormattingColorScaleRule();\r
+    \r
+    /**\r
+     * Create a Databar conditional formatting rule.\r
+     * <p>The thresholds and colour for it will be created, but will be \r
+     *  empty and require configuring with \r
+     *  {@link ConditionalFormattingRule#getDataBarFormatting()}\r
+     *  then\r
+     *  {@link DataBarFormatting#getMinThreshold()}\r
+     *  and \r
+     *  {@link DataBarFormatting#getMaxThreshold()}\r
+     *  and\r
+     *  {@link DataBarFormatting#getColor()}\r
+     */\r
+    ConditionalFormattingRule createConditionalFormattingDataBarRule();\r
     \r
     /**\r
     * Gets Conditional Formatting object at a particular index\r
index afd8885e1b1ae9206c6011848b71277e6e329add..ae77b02d04cca84a547b3cc7deec96471f99e620 100644 (file)
@@ -138,7 +138,41 @@ public class XSSFSheetConditionalFormatting implements SheetConditionalFormattin
         return rule;\r
     }\r
 \r
-    // TODO Support types beyond CELL_VALUE_IS and FORMULA and ICONs\r
+    /**\r
+     * Create a Color Scale / Color Gradient conditional formatting rule.\r
+     * <p>The thresholds and colours for it will be created, but will be \r
+     *  empty and require configuring with \r
+     *  {@link XSSFConditionalFormattingRule#getColorScaleFormatting()}\r
+     *  then\r
+     *  {@link XSSFColorScaleFormatting#getThresholds()}\r
+     *  and\r
+     *  {@link XSSFColorScaleFormatting#getColors()}\r
+     */\r
+    public XSSFConditionalFormattingRule createConditionalFormattingColorScaleRule() {\r
+        XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet);\r
+        \r
+        // Have it setup, with suitable defaults\r
+        rule.createColorScaleFormatting();\r
+        \r
+        // All done!\r
+        return rule;\r
+    }\r
+    \r
+    /**\r
+     * Create a Databar conditional formatting rule.\r
+     * <p>The thresholds and colour for it will be created, but will be \r
+     *  empty and require configuring with \r
+     *  {@link XSSFConditionalFormattingRule#getDataBarFormatting()}\r
+     *  then\r
+     *  {@link XSSFDataBarFormatting#getMinThreshold()}\r
+     *  and \r
+     *  {@link XSSFDataBarFormatting#getMaxThreshold()}\r
+     *  and\r
+     *  {@link XSSFDataBarFormatting#getColor()}\r
+     */\r
+    public XSSFConditionalFormattingRule createConditionalFormattingDataBarRule() {\r
+        throw new IllegalStateException("Not Implemented Yet!"); // TODO Implement\r
+    }\r
     \r
     @SuppressWarnings("deprecation")\r
     public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) {\r
index 191e703898b8fc642e9c322f65fddac54ad2681a..241a2efcb0b381ea6bed4cdb6a33decf1aa3ea70 100644 (file)
@@ -1048,6 +1048,7 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
         ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);\r
         assertEquals(1, cf.getNumberOfRules());\r
         rule1 = cf.getRule(0);\r
+        assertEquals(ConditionType.ICON_SET, rule1.getConditionTypeType());\r
         iconFmt = rule1.getMultiStateFormatting();\r
         \r
         assertEquals(IconSet.GYRB_4_TRAFFIC_LIGHTS, iconFmt.getIconSet());\r
@@ -1066,8 +1067,49 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
     }\r
     \r
     public void testCreateColorScaleFormatting() {\r
-        // TODO Implement then test\r
+        Workbook workbook = _testDataProvider.createWorkbook();\r
+        Sheet sheet = workbook.createSheet();\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+        ConditionalFormattingRule rule1 = \r
+                sheetCF.createConditionalFormattingColorScaleRule();\r
+        ColorScaleFormatting clrFmt = rule1.getColorScaleFormatting();\r
+        \r
+        assertEquals(3, clrFmt.getNumControlPoints());\r
+        assertEquals(3, clrFmt.getColors().length);\r
+        assertEquals(3, clrFmt.getThresholds().length);\r
+        \r
+        clrFmt.getThresholds()[0].setRangeType(RangeType.MIN);\r
+        clrFmt.getThresholds()[1].setRangeType(RangeType.NUMBER);\r
+        clrFmt.getThresholds()[1].setValue(10d);\r
+        clrFmt.getThresholds()[2].setRangeType(RangeType.MAX);\r
+        \r
+        CellRangeAddress [] regions = { CellRangeAddress.valueOf("A1:A5") };\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+        \r
+        // Save, re-load and re-check\r
+        workbook = _testDataProvider.writeOutAndReadBack(workbook);\r
+        sheetCF = sheet.getSheetConditionalFormatting();\r
+        assertEquals(1, sheetCF.getNumConditionalFormattings());\r
+        \r
+        ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);\r
+        assertEquals(1, cf.getNumberOfRules());\r
+        rule1 = cf.getRule(0);\r
+        clrFmt = rule1.getColorScaleFormatting();\r
+        assertEquals(ConditionType.COLOR_SCALE, rule1.getConditionTypeType());\r
+        \r
+        assertEquals(3, clrFmt.getNumControlPoints());\r
+        assertEquals(3, clrFmt.getColors().length);\r
+        assertEquals(3, clrFmt.getThresholds().length);\r
+\r
+        assertEquals(RangeType.MIN,    clrFmt.getThresholds()[0].getRangeType());\r
+        assertEquals(RangeType.NUMBER, clrFmt.getThresholds()[1].getRangeType());\r
+        assertEquals(RangeType.MAX,    clrFmt.getThresholds()[2].getRangeType());\r
+        assertEquals(null, clrFmt.getThresholds()[0].getValue());\r
+        assertEquals(10d,  clrFmt.getThresholds()[1].getValue());\r
+        assertEquals(null, clrFmt.getThresholds()[2].getValue());\r
     }\r
+    \r
     public void testCreateDataBarFormatting() {\r
         // TODO Implement then test\r
     }\r