]> source.dussan.org Git - poi.git/commitdiff
#58130 Mostly there with CF Icon sets
authorNick Burch <nick@apache.org>
Sat, 18 Jul 2015 04:55:27 +0000 (04:55 +0000)
committerNick Burch <nick@apache.org>
Sat, 18 Jul 2015 04:55:27 +0000 (04:55 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1691679 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/aggregates/ConditionalFormattingTable.java
src/java/org/apache/poi/hssf/record/cf/Threshold.java
src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java
src/java/org/apache/poi/hssf/usermodel/HSSFIconMultiStateFormatting.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingThreshold.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFIconMultiStateFormatting.java
src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java

index 47f6f05a30ff8c2fb8b31b755a6187052c669522..dd1398b8607ca427df85d62f74ca93dcad3489d7 100644 (file)
@@ -21,6 +21,8 @@ package org.apache.poi.ss.examples;
 \r
 import org.apache.poi.hssf.usermodel.*;\r
 import org.apache.poi.ss.usermodel.*;\r
+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;\r
+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;\r
 import org.apache.poi.ss.util.CellRangeAddress;\r
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;\r
 \r
@@ -31,10 +33,9 @@ import java.io.IOException;
  * Excel Conditional Formatting -- Examples\r
  *\r
  * <p>\r
- *   Based on the code snippets from http://www.contextures.com/xlcondformat03.html\r
+ *   Partly based on the code snippets from \r
+ *   http://www.contextures.com/xlcondformat03.html\r
  * </p>\r
- *\r
- * @author Yegor Kozlov\r
  */\r
 public class ConditionalFormats {\r
 \r
@@ -54,8 +55,9 @@ public class ConditionalFormats {
         expiry(wb.createSheet("Expiry"));\r
         shadeAlt(wb.createSheet("Shade Alt"));\r
         shadeBands(wb.createSheet("Shade Bands"));\r
+        iconSets(wb.createSheet("Icon Sets"));\r
         \r
-        // TODO Add Icons, data bars etc, see bug #58130\r
+        // TODO Add colour scales, data bars etc, see bug #58130\r
 \r
         // Write the output to a file\r
         String file = "cf-poi.xls";\r
@@ -414,4 +416,64 @@ public class ConditionalFormats {
         sheet.createRow(0).createCell(1).setCellValue("Shade Bands of Rows");\r
         sheet.createRow(1).createCell(1).setCellValue("Condition: Formula Is  =MOD(ROW(),6)<2   (Light Grey Fill)");\r
     }\r
+    \r
+    /**\r
+     * Icon Sets / Multi-States allow you to have icons shown which vary\r
+     *  based on the values, eg Red traffic light / Yellow traffic light /\r
+     *  Green traffic light\r
+     */\r
+    static void iconSets(Sheet sheet) {\r
+        sheet.createRow(0).createCell(0).setCellValue("Icon Sets");\r
+        Row r = sheet.createRow(1);\r
+        r.createCell(0).setCellValue("Reds");\r
+        r.createCell(1).setCellValue(0);\r
+        r.createCell(2).setCellValue(0);\r
+        r.createCell(3).setCellValue(0);\r
+        r = sheet.createRow(2);\r
+        r.createCell(0).setCellValue("Yellows");\r
+        r.createCell(1).setCellValue(5);\r
+        r.createCell(2).setCellValue(5);\r
+        r.createCell(3).setCellValue(5);\r
+        r = sheet.createRow(3);\r
+        r.createCell(0).setCellValue("Greens");\r
+        r.createCell(1).setCellValue(10);\r
+        r.createCell(2).setCellValue(10);\r
+        r.createCell(3).setCellValue(10);\r
+                \r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+        \r
+        CellRangeAddress[] regions = { CellRangeAddress.valueOf("B1:B4") };\r
+        ConditionalFormattingRule rule1 =\r
+                sheetCF.createConditionalFormattingRule(IconSet.GYR_3_TRAFFIC_LIGHTS);\r
+        IconMultiStateFormatting im1 = rule1.getMultiStateFormatting();\r
+        im1.getThresholds()[0].setRangeType(RangeType.MIN);\r
+        im1.getThresholds()[1].setRangeType(RangeType.PERCENT);\r
+        im1.getThresholds()[1].setValue(33d);\r
+        im1.getThresholds()[2].setRangeType(RangeType.MAX);\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+        \r
+        regions = new CellRangeAddress[] { CellRangeAddress.valueOf("C1:C4") };\r
+        ConditionalFormattingRule rule2 =\r
+                sheetCF.createConditionalFormattingRule(IconSet.GYR_3_FLAGS);\r
+        IconMultiStateFormatting im2 = rule1.getMultiStateFormatting();\r
+        im2.getThresholds()[0].setRangeType(RangeType.PERCENT);\r
+        im2.getThresholds()[0].setValue(0d);\r
+        im2.getThresholds()[1].setRangeType(RangeType.PERCENT);\r
+        im2.getThresholds()[1].setValue(33d);\r
+        im2.getThresholds()[2].setRangeType(RangeType.PERCENT);\r
+        im2.getThresholds()[2].setValue(67d);\r
+        sheetCF.addConditionalFormatting(regions, rule2);\r
+        \r
+        regions = new CellRangeAddress[] { CellRangeAddress.valueOf("D1:D4") };\r
+        ConditionalFormattingRule rule3 =\r
+                sheetCF.createConditionalFormattingRule(IconSet.GYR_3_SYMBOLS_CIRCLE);\r
+        IconMultiStateFormatting im3 = rule1.getMultiStateFormatting();\r
+        im3.setIconOnly(true);\r
+        im3.getThresholds()[0].setRangeType(RangeType.MIN);\r
+        im3.getThresholds()[1].setRangeType(RangeType.NUMBER);\r
+        im3.getThresholds()[1].setValue(3d);\r
+        im3.getThresholds()[2].setRangeType(RangeType.NUMBER);\r
+        im3.getThresholds()[2].setValue(7d);\r
+        sheetCF.addConditionalFormatting(regions, rule3);\r
+    }\r
 }\r
index a44f81cd27de34e5a917c65788dc2565fe2fe453..c9d0f174b94cb69f6cd1412c0e52cfd691469b5b 100644 (file)
@@ -129,8 +129,9 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
         
         CFRule12Record r = new CFRule12Record(CONDITION_TYPE_COLOR_SCALE, 
                                               ComparisonOperator.NO_COMPARISON);
-        r.getMultiStateFormatting().setIconSet(iconSet);
-        r.getMultiStateFormatting().setThresholds(ts);
+        IconMultiStateFormatting imf = r.createMultiStateFormatting();
+        imf.setIconSet(iconSet);
+        imf.setThresholds(ts);
         return r;
     }
     // TODO Static creators for the other record types
index e5ea515e807e655f839376c114805afa5991b08a..e4721ca338b9d21cbcb62cf4bc3b39d9a16d68fb 100644 (file)
@@ -61,6 +61,7 @@ public final class ConditionalFormattingTable extends RecordAggregate {
         * @return index of the newly added CF header aggregate
         */
        public int add(CFRecordsAggregate cfAggregate) {
+           cfAggregate.getHeader().setID(_cfHeaders.size());
                _cfHeaders.add(cfAggregate);
                return _cfHeaders.size() - 1;
        }
index 52b89501de05003844ca0ec8e3e026da78548ba7..462027807c179ab4186db33a70bdcde9a4cab9be 100644 (file)
@@ -74,6 +74,9 @@ public final class Threshold {
     public void setType(byte type) {
         this.type = type;
     }
+    public void setType(int type) {
+        this.type = (byte)type;
+    }
 
     protected Formula getFormula() {
         return formula;
@@ -129,7 +132,7 @@ public final class Threshold {
 
     public void serialize(LittleEndianOutput out) {
         out.writeByte(type);
-        if (formula == null) {
+        if (formula.getTokens().length == 0) {
             out.writeShort(0);
         } else {
             formula.serialize(out);
index 5c97b68e28af9e301959584b3dc396e02ba70a0e..e5792770c0b1819ac8ac0be1e1f01d9f36d0a10d 100644 (file)
@@ -77,9 +77,6 @@ public final class HSSFConditionalFormatting  implements ConditionalFormatting {
     private final HSSFSheet sheet;
     private final CFRecordsAggregate cfAggregate;
 
-    // TODO Should this be assigning unique IDs to the rules
-    //  as they get added to the file?
-
     HSSFConditionalFormatting(HSSFSheet sheet, CFRecordsAggregate cfAggregate) {
         if(sheet == null) {
             throw new IllegalArgumentException("sheet must not be null");
index f15732c626eef50b1598d318496029d87116a9ee..e93d5c918f27a7afb5c0e35cff41471803fa375a 100644 (file)
@@ -58,7 +58,7 @@ public final class HSSFIconMultiStateFormatting implements org.apache.poi.ss.use
         iconFormatting.setReversed(reversed);
     }
 
-    public ConditionalFormattingThreshold[] getThresholds() {
+    public HSSFConditionalFormattingThreshold[] getThresholds() {
         Threshold[] t = iconFormatting.getThresholds();
         HSSFConditionalFormattingThreshold[] ht = new HSSFConditionalFormattingThreshold[t.length];
         for (int i=0; i<t.length; i++) {
@@ -74,4 +74,8 @@ public final class HSSFIconMultiStateFormatting implements org.apache.poi.ss.use
         }
         iconFormatting.setThresholds(t);
     }
+
+    public HSSFConditionalFormattingThreshold createThreshold() {
+        return new HSSFConditionalFormattingThreshold(new Threshold(), sheet);
+    }
 }
index 254e8c0a8f71c30a93c95cb328a9f1459c14b9ba..bfdd87807dadf6409ae16bd175adb849c5bc2d1d 100644 (file)
@@ -28,9 +28,17 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfvoType;
  */\r
 public class XSSFConditionalFormattingThreshold implements org.apache.poi.ss.usermodel.ConditionalFormattingThreshold {\r
     private CTCfvo cfvo;\r
+    \r
+    protected XSSFConditionalFormattingThreshold(CTCfvo cfvo) {\r
+        this.cfvo = cfvo;\r
+    }\r
+    \r
+    protected CTCfvo getCTCfvo() {\r
+        return cfvo;\r
+    }\r
 \r
     public RangeType getRangeType() {\r
-        return RangeType.valueOf(cfvo.getType().toString());\r
+        return RangeType.byName(cfvo.getType().toString());\r
     }\r
     public void setRangeType(RangeType type) {\r
         STCfvoType.Enum xtype = STCfvoType.Enum.forString(type.name);\r
index 526805d79341c7b5dab5704cb082efbf9d3e762e..81883bb0695e413dbc3f596b322313fc8fdbf6b9 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.poi.xssf.usermodel;
 \r
 import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold;\r
 import org.apache.poi.ss.usermodel.IconMultiStateFormatting;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfvo;\r
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIconSet;\r
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STIconSetType;\r
 \r
@@ -35,9 +36,8 @@ public class XSSFIconMultiStateFormatting implements IconMultiStateFormatting {
     }\r
 \r
     public IconSet getIconSet() {\r
-        return IconSet.valueOf(\r
-                _iconset.getIconSet().toString()\r
-        );\r
+        String set = _iconset.getIconSet().toString();\r
+        return IconSet.byName(set);\r
     }\r
     public void setIconSet(IconSet set) {\r
         STIconSetType.Enum xIconSet = STIconSetType.Enum.forString(set.name);\r
@@ -62,11 +62,24 @@ public class XSSFIconMultiStateFormatting implements IconMultiStateFormatting {
         _iconset.setReverse(reversed);\r
     }\r
 \r
+    @SuppressWarnings("deprecation")\r
     public XSSFConditionalFormattingThreshold[] getThresholds() {\r
-        // TODO Implement\r
-        return null;\r
+        CTCfvo[] cfvos = _iconset.getCfvoArray();\r
+        XSSFConditionalFormattingThreshold[] t = \r
+                new XSSFConditionalFormattingThreshold[cfvos.length];\r
+        for (int i=0; i<cfvos.length; i++) {\r
+            t[i] = new XSSFConditionalFormattingThreshold(cfvos[i]);\r
+        }\r
+        return t;\r
     }\r
     public void setThresholds(ConditionalFormattingThreshold[] thresholds) {\r
-        // TODO Implement\r
+        CTCfvo[] cfvos = new CTCfvo[thresholds.length];\r
+        for (int i=0; i<thresholds.length; i++) {\r
+            cfvos[i] = ((XSSFConditionalFormattingThreshold)thresholds[i]).getCTCfvo();\r
+        }\r
+        _iconset.setCfvoArray(cfvos);\r
+    }\r
+    public XSSFConditionalFormattingThreshold createThreshold() {\r
+        return new XSSFConditionalFormattingThreshold(_iconset.addNewCfvo());\r
     }\r
 }\r
index 3be13558b861f7ee1779873e57aec2d722e294cd..c39e3e40487d46ad06b5b7483f240f6252d7db23 100644 (file)
@@ -32,6 +32,8 @@ import org.apache.poi.hssf.util.HSSFColor;
 import org.apache.poi.ss.formula.ptg.Ptg;
 import org.apache.poi.ss.formula.ptg.RefNPtg;
 import org.apache.poi.ss.formula.ptg.RefPtg;
+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;
+import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -119,6 +121,46 @@ public final class TestCFRuleRecord extends TestCase {
         }
     }
 
+    public void testCreateIconCFRule12Record() {
+        HSSFWorkbook workbook = new HSSFWorkbook();
+        HSSFSheet sheet = workbook.createSheet();
+        CFRule12Record record = CFRule12Record.create(sheet, IconSet.GREY_5_ARROWS);
+        record.getMultiStateFormatting().getThresholds()[1].setType(RangeType.PERCENT.id);
+        record.getMultiStateFormatting().getThresholds()[1].setValue(10d);
+        record.getMultiStateFormatting().getThresholds()[2].setType(RangeType.NUMBER.id);
+        record.getMultiStateFormatting().getThresholds()[2].setValue(-4d);
+        
+        // Check it 
+        testCFRule12Record(record);
+        assertEquals(IconSet.GREY_5_ARROWS, record.getMultiStateFormatting().getIconSet());
+        assertEquals(5, record.getMultiStateFormatting().getThresholds().length);
+
+        // Serialize
+        byte [] serializedRecord = record.serialize();
+
+        // Strip header
+        byte [] recordData = new byte[serializedRecord.length-4];
+        System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length);
+
+        // Deserialize
+        record = new CFRule12Record(TestcaseRecordInputStream.create(CFRule12Record.sid, recordData));
+        
+        // Check it has the icon, and the right number of thresholds
+        assertEquals(IconSet.GREY_5_ARROWS, record.getMultiStateFormatting().getIconSet());
+        assertEquals(5, record.getMultiStateFormatting().getThresholds().length);
+
+        // Serialize again
+        byte[] output = record.serialize();
+
+        // Compare
+        assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength
+
+        for (int i = 0; i < recordData.length;i++)
+        {
+            assertEquals("CFRule12Record doesn't match", recordData[i], output[i+4]);
+        }
+    }
+    
     private void testCFRuleRecord(CFRuleRecord record) {
         testCFRuleBase(record);
         
index 6276b582915c38dbcba835860da4290a324d4f0e..fd7e5399419f088f4bf12da6e255f89d9d5968a6 100644 (file)
@@ -24,6 +24,7 @@ import junit.framework.TestCase;
 import org.apache.poi.hssf.usermodel.HSSFConditionalFormatting;\r
 import org.apache.poi.hssf.usermodel.HSSFConditionalFormattingRule;\r
 import org.apache.poi.ss.ITestDataProvider;\r
+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;\r
 import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;\r
 import org.apache.poi.ss.util.CellRangeAddress;\r
 \r
@@ -546,6 +547,7 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
         ConditionalFormatting cf = null;\r
         ConditionalFormattingRule cr = null;\r
         IconMultiStateFormatting icon = null;\r
+        ConditionalFormattingThreshold th = null;\r
         \r
         // Sanity check data\r
         assertEquals("Values", s.getRow(0).getCell(0).toString());\r
@@ -572,7 +574,7 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
                     type == ConditionType.FORMULA) {\r
                     fCF++;\r
                 } else {\r
-                    // TODO Detect Ext ones\r
+                    // TODO Properly detect Ext ones from the xml\r
                     fCF12++;\r
                 }\r
             }\r
@@ -599,7 +601,7 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
         // When it matches:\r
         //   Sets the font colour to dark green\r
         //   Sets the background colour to lighter green\r
-        // TODO Should the colours be slightly different between formats?\r
+        // TODO Should the colours be slightly different between formats? Would CFEX support help for HSSF?\r
         if (cr instanceof HSSFConditionalFormattingRule) {\r
             assertColour("0:8080:0", cr.getFontFormatting().getFontColor());\r
             assertColour("CCCC:FFFF:CCCC", cr.getPatternFormatting().getFillBackgroundColorColor());\r
@@ -623,7 +625,7 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
         // When it matches:\r
         //   Sets the font colour to dark red\r
         //   Sets the background colour to lighter red\r
-        // TODO Should the colours be slightly different between formats?\r
+        // TODO Should the colours be slightly different between formats? Would CFEX support help for HSSF?\r
         if (cr instanceof HSSFConditionalFormattingRule) {\r
             assertColour("8080:0:8080", cr.getFontFormatting().getFontColor());\r
             assertColour("FFFF:9999:CCCC", cr.getPatternFormatting().getFillBackgroundColorColor());\r
@@ -641,13 +643,34 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
         assertEquals(1, cf.getNumberOfRules());\r
         cr = cf.getRule(0);\r
         assertEquals(ConditionType.DATA_BAR, cr.getConditionTypeType());\r
-        // TODO Support then check the rest\r
+        // TODO Support Data Bars, then check the rest of this rule\r
         \r
         \r
         // Colours R->G - Column F\r
+        cf = sheetCF.getConditionalFormattingAt(3);\r
+        assertEquals(1, cf.getFormattingRanges().length);\r
+        assertEquals("F2:F17", cf.getFormattingRanges()[0].formatAsString());\r
+        \r
+        assertEquals(1, cf.getNumberOfRules());\r
+        cr = cf.getRule(0);\r
+        assertEquals(ConditionType.COLOR_SCALE, cr.getConditionTypeType());\r
+        // TODO Support Color Scales, then check the rest of this rule\r
+\r
+        \r
         // Colours BWR - Column G\r
+        cf = sheetCF.getConditionalFormattingAt(4);\r
+        assertEquals(1, cf.getFormattingRanges().length);\r
+        assertEquals("G2:G17", cf.getFormattingRanges()[0].formatAsString());\r
+        \r
+        assertEquals(1, cf.getNumberOfRules());\r
+        cr = cf.getRule(0);\r
+        assertEquals(ConditionType.COLOR_SCALE, cr.getConditionTypeType());\r
+        // TODO Support Color Scales, then check the rest of this rule\r
+\r
+        \r
+        // TODO Simplify asserts\r
         \r
-        // Icons : Default - Column H\r
+        // Icons : Default - Column H, percentage thresholds\r
         cf = sheetCF.getConditionalFormattingAt(5);\r
         assertEquals(1, cf.getFormattingRanges().length);\r
         assertEquals("H2:H17", cf.getFormattingRanges()[0].formatAsString());\r
@@ -658,21 +681,107 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
         assertEquals(ComparisonOperator.NO_COMPARISON, cr.getComparisonOperation());\r
         assertEquals(null, cr.getFormula1());\r
         assertEquals(null, cr.getFormula2());\r
-        if (cr instanceof HSSFConditionalFormattingRule) {\r
-            HSSFConditionalFormattingRule hcr = (HSSFConditionalFormattingRule)cr;\r
-            icon = hcr.getMultiStateFormatting();\r
-            assertNotNull(icon);\r
-            assertEquals(IconSet.GYR_3_TRAFFIC_LIGHTS, icon.getIconSet());\r
-            assertEquals(false, icon.isIconOnly());\r
-            assertEquals(false, icon.isReversed());\r
-            // TODO Check the rest\r
-        } else {\r
-            // TODO XSSF Support\r
-        }\r
+        \r
+        icon = cr.getMultiStateFormatting();\r
+        assertNotNull(icon);\r
+        assertEquals(IconSet.GYR_3_TRAFFIC_LIGHTS, icon.getIconSet());\r
+        assertEquals(false, icon.isIconOnly());\r
+        assertEquals(false, icon.isReversed());\r
+        \r
+        assertNotNull(icon.getThresholds());\r
+        assertEquals(3, icon.getThresholds().length);\r
+        th = icon.getThresholds()[0];\r
+        assertEquals(RangeType.PERCENT, th.getRangeType());\r
+        assertEquals(0.0d, th.getValue());\r
+        assertEquals(null, th.getFormula());\r
+        th = icon.getThresholds()[1];\r
+        assertEquals(RangeType.PERCENT, th.getRangeType());\r
+        assertEquals(33.0d, th.getValue());\r
+        assertEquals(null, th.getFormula());\r
+        th = icon.getThresholds()[2];\r
+        assertEquals(RangeType.PERCENT, th.getRangeType());\r
+        assertEquals(67.0d, th.getValue());\r
+        assertEquals(null, th.getFormula());\r
+        \r
         \r
         // Icons : 3 signs - Column I\r
+        cf = sheetCF.getConditionalFormattingAt(6);\r
+        assertEquals(1, cf.getFormattingRanges().length);\r
+        assertEquals("I2:I17", cf.getFormattingRanges()[0].formatAsString());\r
+        \r
+        assertEquals(1, cf.getNumberOfRules());\r
+        cr = cf.getRule(0);\r
+        assertEquals(ConditionType.ICON_SET, cr.getConditionTypeType());\r
+        assertEquals(ComparisonOperator.NO_COMPARISON, cr.getComparisonOperation());\r
+        assertEquals(null, cr.getFormula1());\r
+        assertEquals(null, cr.getFormula2());\r
+        \r
+        icon = cr.getMultiStateFormatting();\r
+        assertNotNull(icon);\r
+        assertEquals(IconSet.GYR_3_SHAPES, icon.getIconSet());\r
+        assertEquals(false, icon.isIconOnly());\r
+        assertEquals(false, icon.isReversed());\r
+        \r
+        assertNotNull(icon.getThresholds());\r
+        assertEquals(3, icon.getThresholds().length);\r
+        th = icon.getThresholds()[0];\r
+        assertEquals(RangeType.PERCENT, th.getRangeType());\r
+        assertEquals(0.0d, th.getValue());\r
+        assertEquals(null, th.getFormula());\r
+        th = icon.getThresholds()[1];\r
+        assertEquals(RangeType.PERCENT, th.getRangeType());\r
+        assertEquals(33.0d, th.getValue());\r
+        assertEquals(null, th.getFormula());\r
+        th = icon.getThresholds()[2];\r
+        assertEquals(RangeType.PERCENT, th.getRangeType());\r
+        assertEquals(67.0d, th.getValue());\r
+        assertEquals(null, th.getFormula());\r
+        \r
+        \r
         // Icons : 3 traffic lights 2 - Column J\r
+        cf = sheetCF.getConditionalFormattingAt(7);\r
+        assertEquals(1, cf.getFormattingRanges().length);\r
+        assertEquals("J2:J17", cf.getFormattingRanges()[0].formatAsString());\r
+        \r
+        assertEquals(1, cf.getNumberOfRules());\r
+        cr = cf.getRule(0);\r
+        assertEquals(ConditionType.ICON_SET, cr.getConditionTypeType());\r
+        assertEquals(ComparisonOperator.NO_COMPARISON, cr.getComparisonOperation());\r
+        assertEquals(null, cr.getFormula1());\r
+        assertEquals(null, cr.getFormula2());\r
+        \r
+        icon = cr.getMultiStateFormatting();\r
+        assertNotNull(icon);\r
+        assertEquals(IconSet.GYR_3_TRAFFIC_LIGHTS_BOX, icon.getIconSet());\r
+        assertEquals(false, icon.isIconOnly());\r
+        assertEquals(false, icon.isReversed());\r
+        \r
+        assertNotNull(icon.getThresholds());\r
+        assertEquals(3, icon.getThresholds().length);\r
+        th = icon.getThresholds()[0];\r
+        assertEquals(RangeType.PERCENT, th.getRangeType());\r
+        assertEquals(0.0d, th.getValue());\r
+        assertEquals(null, th.getFormula());\r
+        th = icon.getThresholds()[1];\r
+        assertEquals(RangeType.PERCENT, th.getRangeType());\r
+        assertEquals(33.0d, th.getValue());\r
+        assertEquals(null, th.getFormula());\r
+        th = icon.getThresholds()[2];\r
+        assertEquals(RangeType.PERCENT, th.getRangeType());\r
+        assertEquals(67.0d, th.getValue());\r
+        assertEquals(null, th.getFormula());\r
+        \r
+        \r
         // Icons : 4 traffic lights - Column K\r
+        cf = sheetCF.getConditionalFormattingAt(8);\r
+        assertEquals(1, cf.getFormattingRanges().length);\r
+        assertEquals("K2:K17", cf.getFormattingRanges()[0].formatAsString());\r
+        \r
+        assertEquals(1, cf.getNumberOfRules());\r
+        cr = cf.getRule(0);\r
+        assertIconSetPercentages(cr, IconSet.GYRB_4_TRAFFIC_LIGHTS, 0d, 25d, 50d, 75d);\r
+\r
+        \r
         // Icons : 3 symbols - Column L\r
         // Icons : 3 flags - Column M\r
         // Icons : 3 symbols 2 - Column N\r
@@ -685,6 +794,28 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
         // Mixed icons - Column U\r
 \r
     }\r
+    private void assertIconSetPercentages(ConditionalFormattingRule cr, IconSet iconset, Double...vals) {\r
+        assertEquals(ConditionType.ICON_SET, cr.getConditionTypeType());\r
+        assertEquals(ComparisonOperator.NO_COMPARISON, cr.getComparisonOperation());\r
+        assertEquals(null, cr.getFormula1());\r
+        assertEquals(null, cr.getFormula2());\r
+        \r
+        IconMultiStateFormatting icon = cr.getMultiStateFormatting();\r
+        assertNotNull(icon);\r
+        assertEquals(iconset, icon.getIconSet());\r
+        assertEquals(false, icon.isIconOnly());\r
+        assertEquals(false, icon.isReversed());\r
+        \r
+        assertNotNull(icon.getThresholds());\r
+        assertEquals(vals.length, icon.getThresholds().length);\r
+        for (int i=0; i<vals.length; i++) {\r
+            Double v = vals[i];\r
+            ConditionalFormattingThreshold th = icon.getThresholds()[i];\r
+            assertEquals(RangeType.PERCENT, th.getRangeType());\r
+            assertEquals(v, th.getValue());\r
+            assertEquals(null, th.getFormula());\r
+        }\r
+    }\r
 \r
     public void testCreateFontFormatting() {\r
         Workbook workbook = _testDataProvider.createWorkbook();\r
@@ -859,8 +990,55 @@ public abstract class BaseTestConditionalFormatting extends TestCase {
         assertEquals(BorderFormatting.BORDER_HAIR, r1fp.getBorderRight());\r
     }\r
     \r
-    public void testCreateIconFormatting() {\r
-        // TODO Implement for XSSF, then test here\r
+    // TODO Fix this test to work for HSSF\r
+    public void DISABLEDtestCreateIconFormatting() {\r
+        Workbook workbook = _testDataProvider.createWorkbook();\r
+        Sheet sheet = workbook.createSheet();\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+        ConditionalFormattingRule rule1 = \r
+                sheetCF.createConditionalFormattingRule(IconSet.GYRB_4_TRAFFIC_LIGHTS);\r
+        IconMultiStateFormatting iconFmt = rule1.getMultiStateFormatting();\r
+        \r
+        assertEquals(IconSet.GYRB_4_TRAFFIC_LIGHTS, iconFmt.getIconSet());\r
+        assertEquals(4, iconFmt.getThresholds().length);\r
+        assertEquals(false, iconFmt.isIconOnly());\r
+        assertEquals(false, iconFmt.isReversed());\r
+        \r
+        iconFmt.setIconOnly(true);\r
+        iconFmt.getThresholds()[0].setRangeType(RangeType.MIN);\r
+        iconFmt.getThresholds()[1].setRangeType(RangeType.NUMBER);\r
+        iconFmt.getThresholds()[1].setValue(10d);\r
+        iconFmt.getThresholds()[2].setRangeType(RangeType.PERCENT);\r
+        iconFmt.getThresholds()[2].setValue(75d);\r
+        iconFmt.getThresholds()[3].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
+        iconFmt = rule1.getMultiStateFormatting();\r
+        \r
+        assertEquals(IconSet.GYRB_4_TRAFFIC_LIGHTS, iconFmt.getIconSet());\r
+        assertEquals(4, iconFmt.getThresholds().length);\r
+        assertEquals(true, iconFmt.isIconOnly());\r
+        assertEquals(false, iconFmt.isReversed());\r
+\r
+        assertEquals(RangeType.MIN,    iconFmt.getThresholds()[0].getRangeType());\r
+        assertEquals(RangeType.NUMBER, iconFmt.getThresholds()[1].getRangeType());\r
+        assertEquals(RangeType.PERCENT,iconFmt.getThresholds()[2].getRangeType());\r
+        assertEquals(RangeType.MAX,    iconFmt.getThresholds()[3].getRangeType());\r
+        assertEquals(null, iconFmt.getThresholds()[0].getValue());\r
+        assertEquals(10d,  iconFmt.getThresholds()[1].getValue());\r
+        assertEquals(75d,  iconFmt.getThresholds()[2].getValue());\r
+        assertEquals(null, iconFmt.getThresholds()[3].getValue());\r
     }\r
     \r
     public void testBug55380() {\r