]> source.dussan.org Git - poi.git/commitdiff
support for conditional formatting in XSSF including docs and examples
authorYegor Kozlov <yegor@apache.org>
Fri, 29 Jul 2011 04:47:25 +0000 (04:47 +0000)
committerYegor Kozlov <yegor@apache.org>
Fri, 29 Jul 2011 04:47:25 +0000 (04:47 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1152099 13f79535-47bb-0310-9956-ffa450edef68

33 files changed:
src/documentation/content/xdocs/spreadsheet/quick-guide.xml
src/documentation/content/xdocs/status.xml
src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java [new file with mode: 0755]
src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java
src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java
src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java
src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java
src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java
src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java
src/java/org/apache/poi/ss/usermodel/BorderFormatting.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/FontFormatting.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/IndexedColors.java
src/java/org/apache/poi/ss/usermodel/PatternFormatting.java [new file with mode: 0644]
src/java/org/apache/poi/ss/usermodel/Sheet.java
src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java
src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java [new file with mode: 0644]
test-data/spreadsheet/WithConditionalFormatting.xls [new file with mode: 0755]
test-data/spreadsheet/WithConditionalFormatting.xlsx [new file with mode: 0755]

index 0e2d6a05b381c8e1d8f21ab447f7f2e67c2ed59f..d467468097173e40dad19c51d9967b68890bd1a8 100644 (file)
@@ -729,7 +729,7 @@ Examples:
     sheet1.addMergedRegion( region );
 
     // Set the border and border colors.
-    final short borderMediumDashed = HSSFCellStyle.BORDER_MEDIUM_DASHED;
+    final short borderMediumDashed = CellStyle.BORDER_MEDIUM_DASHED;
     RegionUtil.setBorderBottom( borderMediumDashed,
         region, sheet1, wb );
     RegionUtil.setBorderTop( borderMediumDashed,
@@ -748,7 +748,7 @@ Examples:
     style.setIndention((short)4);
     CellUtil.createCell(row, 8, "This is the value of the cell", style);
     Cell cell2 = CellUtil.createCell( row2, 8, "This is the value of the cell");
-    CellUtil.setAlignment(cell2, wb, HSSFCellStyle.ALIGN_CENTER);
+    CellUtil.setAlignment(cell2, wb, CellStyle.ALIGN_CENTER);
 
     // Write out the workbook
     FileOutputStream fileOut = new FileOutputStream( "workbook.xls" );
@@ -1677,39 +1677,43 @@ Examples:
        </source>
      </section>  
      <anchor id="ConditionalFormatting"/>
-     <section><title>Conditional Formatting (HSSF Only)</title>
+     <section><title>Conditional Formatting</title>
        <source>
-    HSSFWorkbook workbook = new HSSFWorkbook();
-    HSSFSheet sheet = workbook.createSheet();
-    String formula = "7";
+    Workbook workbook = new HSSFWorkbook(); // or new XSSFWorkbook();
+    Sheet sheet = workbook.createSheet();
 
-    HSSFSheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
+    SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
 
-    HSSFConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(formula);
-    HSSFFontFormatting fontFmt = rule1.createFontFormatting();
+    ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.EQUAL, "0");
+    FontFormatting fontFmt = rule1.createFontFormatting();
     fontFmt.setFontStyle(true, false);
+    fontFmt.setFontColorIndex(IndexedColors.DARK_RED.index);
+    
+    BorderFormatting bordFmt = rule1.createBorderFormatting();
+    bordFmt.setBorderBottom(BorderFormatting.BORDER_THIN);
+    bordFmt.setBorderTop(BorderFormatting.BORDER_THICK);
+    bordFmt.setBorderLeft(BorderFormatting.BORDER_DASHED);
+    bordFmt.setBorderRight(BorderFormatting.BORDER_DOTTED);
 
-    HSSFBorderFormatting bordFmt = rule1.createBorderFormatting();
-    bordFmt.setBorderBottom(HSSFBorderFormatting.BORDER_THIN);
-    bordFmt.setBorderTop(HSSFBorderFormatting.BORDER_THICK);
-    bordFmt.setBorderLeft(HSSFBorderFormatting.BORDER_DASHED);
-    bordFmt.setBorderRight(HSSFBorderFormatting.BORDER_DOTTED);
-
-    HSSFPatternFormatting patternFmt = rule1.createPatternFormatting();
-    patternFmt.setFillBackgroundColor(HSSFColor.YELLOW.index);
+    PatternFormatting patternFmt = rule1.createPatternFormatting();
+    patternFmt.setFillBackgroundColor(IndexedColors.YELLOW.index);
 
-    HSSFConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2");
-    HSSFConditionalFormattingRule [] cfRules =
+    ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "-10", "10");
+    ConditionalFormattingRule [] cfRules =
     {
         rule1, rule2
     };
 
-    CellRangeAddress [] regions = {
-        new CellRangeAddress(2, 4, 0, 0), // A3:A5
+    CellRangeAddress[] regions = {
+        CellRangeAddress.valueOf("A3:A5")
     };
 
     sheetCF.addConditionalFormatting(regions, cfRules);
        </source>
+     <p> See more examples on Excel conditional formatting in
+     <link href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java">ConditionalFormats.java</link>     
+      </p>
+       
      </section>  
     </body>
 </document>
index 510e67e842d654a492e6509b4274bacb2a80c788..4bf487c3e2689fea7af633aaf5bb784d08efe732 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta4" date="2011-??-??">
+           <action dev="poi-developers" type="add">Support for conditional formatting in XSSF</action>
            <action dev="poi-developers" type="add">Support isRightToLeft and setRightToLeft on the common spreadsheet Sheet interface, as per existing HSSF support</action>
            <action dev="poi-developers" type="fix">50209 - Fixed evaluation of Subtotals to ignore nested subtotals</action>
            <action dev="poi-developers" type="fix">44431 - HWPFDocument.write destroys fields</action>
diff --git a/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java b/src/examples/src/org/apache/poi/ss/examples/ConditionalFormats.java
new file mode 100755 (executable)
index 0000000..d0ce767
--- /dev/null
@@ -0,0 +1,349 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.ss.examples;\r
+\r
+import org.apache.poi.hssf.usermodel.*;\r
+import org.apache.poi.ss.usermodel.*;\r
+import org.apache.poi.ss.util.CellRangeAddress;\r
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;\r
+\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+\r
+/**\r
+ * Excel Conditional Formatting -- Examples\r
+ *\r
+ * <p>\r
+ *   Based on the code snippets from http://www.contextures.com/xlcondformat03.html\r
+ * </p>\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class ConditionalFormats {\r
+\r
+    public static void main(String[] args) throws IOException {\r
+        Workbook wb;\r
+\r
+        if(args.length > 0 && args[0].equals("-xls")) wb = new HSSFWorkbook();\r
+        else wb = new XSSFWorkbook();\r
+\r
+        sameCell(wb.createSheet("Same Cell"));\r
+        multiCell(wb.createSheet("MultiCell"));\r
+        errors(wb.createSheet("Errors"));\r
+        hideDupplicates(wb.createSheet("Hide Dups"));\r
+        formatDuplicates(wb.createSheet("Duplicates"));\r
+        inList(wb.createSheet("In List"));\r
+        expiry(wb.createSheet("Expiry"));\r
+        shadeAlt(wb.createSheet("Shade Alt"));\r
+        shadeBands(wb.createSheet("Shade Bands"));\r
+\r
+        // Write the output to a file\r
+        String file = "cf-poi.xls";\r
+        if(wb instanceof XSSFWorkbook) file += "x";\r
+        FileOutputStream out = new FileOutputStream(file);\r
+        wb.write(out);\r
+        out.close();\r
+\r
+    }\r
+\r
+    /**\r
+     * Highlight cells based on their values\r
+     */\r
+    static void sameCell(Sheet sheet) {\r
+        sheet.createRow(0).createCell(0).setCellValue(84);\r
+        sheet.createRow(1).createCell(0).setCellValue(74);\r
+        sheet.createRow(2).createCell(0).setCellValue(50);\r
+        sheet.createRow(3).createCell(0).setCellValue(51);\r
+        sheet.createRow(4).createCell(0).setCellValue(49);\r
+        sheet.createRow(5).createCell(0).setCellValue(41);\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        // Condition 1: Cell Value Is   greater than  70   (Blue Fill)\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.GT, "70");\r
+        PatternFormatting fill1 = rule1.createPatternFormatting();\r
+        fill1.setFillBackgroundColor(IndexedColors.BLUE.index);\r
+        fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);\r
+\r
+        // Condition 2: Cell Value Is  less than      50   (Green Fill)\r
+        ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.LT, "50");\r
+        PatternFormatting fill2 = rule2.createPatternFormatting();\r
+        fill2.setFillBackgroundColor(IndexedColors.GREEN.index);\r
+        fill2.setFillPattern(PatternFormatting.SOLID_FOREGROUND);\r
+\r
+        CellRangeAddress[] regions = {\r
+                CellRangeAddress.valueOf("A1:A6")\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, rule1, rule2);\r
+\r
+        sheet.getRow(0).createCell(2).setCellValue("<== Condition 1: Cell Value Is greater than 70 (Blue Fill)");\r
+        sheet.getRow(4).createCell(2).setCellValue("<== Condition 2: Cell Value Is less than 50 (Green Fill)");\r
+    }\r
+\r
+    /**\r
+     * Highlight multiple cells based on a formula\r
+     */\r
+    static void multiCell(Sheet sheet) {\r
+        // header row\r
+        Row row0 = sheet.createRow(0);\r
+        row0.createCell(0).setCellValue("Units");\r
+        row0.createCell(1).setCellValue("Cost");\r
+        row0.createCell(2).setCellValue("Total");\r
+\r
+        Row row1 = sheet.createRow(1);\r
+        row1.createCell(0).setCellValue(71);\r
+        row1.createCell(1).setCellValue(29);\r
+        row1.createCell(2).setCellValue(2059);\r
+\r
+        Row row2 = sheet.createRow(2);\r
+        row2.createCell(0).setCellValue(85);\r
+        row2.createCell(1).setCellValue(29);\r
+        row2.createCell(2).setCellValue(2059);\r
+\r
+        Row row3 = sheet.createRow(3);\r
+        row3.createCell(0).setCellValue(71);\r
+        row3.createCell(1).setCellValue(29);\r
+        row3.createCell(2).setCellValue(2059);\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        // Condition 1: Formula Is   =$B2>75   (Blue Fill)\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("$A2>75");\r
+        PatternFormatting fill1 = rule1.createPatternFormatting();\r
+        fill1.setFillBackgroundColor(IndexedColors.BLUE.index);\r
+        fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);\r
+\r
+        CellRangeAddress[] regions = {\r
+                CellRangeAddress.valueOf("A2:C4")\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+\r
+        sheet.getRow(2).createCell(4).setCellValue("<== Condition 1: Formula Is =$B2>75   (Blue Fill)");\r
+    }\r
+\r
+    /**\r
+     *  Use Excel conditional formatting to check for errors,\r
+     *  and change the font colour to match the cell colour.\r
+     *  In this example, if formula result is  #DIV/0! then it will have white font colour.\r
+     */\r
+    static void errors(Sheet sheet) {\r
+        sheet.createRow(0).createCell(0).setCellValue(84);\r
+        sheet.createRow(1).createCell(0).setCellValue(0);\r
+        sheet.createRow(2).createCell(0).setCellFormula("ROUND(A1/A2,0)");\r
+        sheet.createRow(3).createCell(0).setCellValue(0);\r
+        sheet.createRow(4).createCell(0).setCellFormula("ROUND(A6/A4,0)");\r
+        sheet.createRow(5).createCell(0).setCellValue(41);\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        // Condition 1: Formula Is   =ISERROR(C2)   (White Font)\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("ISERROR(A1)");\r
+        FontFormatting font = rule1.createFontFormatting();\r
+        font.setFontColorIndex(IndexedColors.WHITE.index);\r
+\r
+        CellRangeAddress[] regions = {\r
+                CellRangeAddress.valueOf("A1:A6")\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+\r
+        sheet.getRow(2).createCell(1).setCellValue("<== The error in this cell is hidden. Condition: Formula Is   =ISERROR(C2)   (White Font)");\r
+        sheet.getRow(4).createCell(1).setCellValue("<== The error in this cell is hidden. Condition: Formula Is   =ISERROR(C2)   (White Font)");\r
+    }\r
+\r
+    /**\r
+     * Use Excel conditional formatting to hide the duplicate values,\r
+     * and make the list easier to read. In this example, when the table is sorted by Region,\r
+     * the second (and subsequent) occurences of each region name will have white font colour.\r
+     */\r
+    static void hideDupplicates(Sheet sheet) {\r
+        sheet.createRow(0).createCell(0).setCellValue("City");\r
+        sheet.createRow(1).createCell(0).setCellValue("Boston");\r
+        sheet.createRow(2).createCell(0).setCellValue("Boston");\r
+        sheet.createRow(3).createCell(0).setCellValue("Chicago");\r
+        sheet.createRow(4).createCell(0).setCellValue("Chicago");\r
+        sheet.createRow(5).createCell(0).setCellValue("New York");\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        // Condition 1: Formula Is   =A2=A1   (White Font)\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("A2=A1");\r
+        FontFormatting font = rule1.createFontFormatting();\r
+        font.setFontColorIndex(IndexedColors.WHITE.index);\r
+\r
+        CellRangeAddress[] regions = {\r
+                CellRangeAddress.valueOf("A2:A6")\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+\r
+        sheet.getRow(1).createCell(1).setCellValue("<== the second (and subsequent) " +\r
+                "occurences of each region name will have white font colour.  " +\r
+                "Condition: Formula Is   =A2=A1   (White Font)");\r
+    }\r
+\r
+    /**\r
+     * Use Excel conditional formatting to highlight duplicate entries in a column.\r
+     */\r
+    static void formatDuplicates(Sheet sheet) {\r
+        sheet.createRow(0).createCell(0).setCellValue("Code");\r
+        sheet.createRow(1).createCell(0).setCellValue(4);\r
+        sheet.createRow(2).createCell(0).setCellValue(3);\r
+        sheet.createRow(3).createCell(0).setCellValue(6);\r
+        sheet.createRow(4).createCell(0).setCellValue(3);\r
+        sheet.createRow(5).createCell(0).setCellValue(5);\r
+        sheet.createRow(6).createCell(0).setCellValue(8);\r
+        sheet.createRow(7).createCell(0).setCellValue(0);\r
+        sheet.createRow(8).createCell(0).setCellValue(2);\r
+        sheet.createRow(9).createCell(0).setCellValue(8);\r
+        sheet.createRow(10).createCell(0).setCellValue(6);\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        // Condition 1: Formula Is   =A2=A1   (White Font)\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("COUNTIF($A$2:$A$11,A2)>1");\r
+        FontFormatting font = rule1.createFontFormatting();\r
+        font.setFontStyle(false, true);\r
+        font.setFontColorIndex(IndexedColors.BLUE.index);\r
+\r
+        CellRangeAddress[] regions = {\r
+                CellRangeAddress.valueOf("A2:A11")\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+\r
+        sheet.getRow(2).createCell(1).setCellValue("<== Duplicates numbers in the column are highlighted.  " +\r
+                "Condition: Formula Is =COUNTIF($A$2:$A$11,A2)>1   (Blue Font)");\r
+    }\r
+\r
+    /**\r
+     * Use Excel conditional formatting to highlight items that are in a list on the worksheet.\r
+     */\r
+    static void inList(Sheet sheet) {\r
+        sheet.createRow(0).createCell(0).setCellValue("Codes");\r
+        sheet.createRow(1).createCell(0).setCellValue("AA");\r
+        sheet.createRow(2).createCell(0).setCellValue("BB");\r
+        sheet.createRow(3).createCell(0).setCellValue("GG");\r
+        sheet.createRow(4).createCell(0).setCellValue("AA");\r
+        sheet.createRow(5).createCell(0).setCellValue("FF");\r
+        sheet.createRow(6).createCell(0).setCellValue("XX");\r
+        sheet.createRow(7).createCell(0).setCellValue("CC");\r
+\r
+        sheet.getRow(0).createCell(2).setCellValue("Valid");\r
+        sheet.getRow(1).createCell(2).setCellValue("AA");\r
+        sheet.getRow(2).createCell(2).setCellValue("BB");\r
+        sheet.getRow(3).createCell(2).setCellValue("CC");\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        // Condition 1: Formula Is   =A2=A1   (White Font)\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("COUNTIF($C$2:$C$4,A2)");\r
+        PatternFormatting fill1 = rule1.createPatternFormatting();\r
+        fill1.setFillBackgroundColor(IndexedColors.LIGHT_BLUE.index);\r
+        fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);\r
+\r
+        CellRangeAddress[] regions = {\r
+                CellRangeAddress.valueOf("A2:A8")\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+\r
+        sheet.getRow(2).createCell(3).setCellValue("<== Use Excel conditional formatting to highlight items that are in a list on the worksheet");\r
+    }\r
+\r
+    /**\r
+     *  Use Excel conditional formatting to highlight payments that are due in the next thirty days.\r
+     *  In this example, Due dates are entered in cells A2:A4.\r
+     */\r
+    static void expiry(Sheet sheet) {\r
+        CellStyle style = sheet.getWorkbook().createCellStyle();\r
+        style.setDataFormat((short)BuiltinFormats.getBuiltinFormat("d-mmm"));\r
+\r
+        sheet.createRow(0).createCell(0).setCellValue("Date");\r
+        sheet.createRow(1).createCell(0).setCellFormula("TODAY()+29");\r
+        sheet.createRow(2).createCell(0).setCellFormula("A2+1");\r
+        sheet.createRow(3).createCell(0).setCellFormula("A3+1");\r
+\r
+        for(int rownum = 1; rownum <= 3; rownum++) sheet.getRow(rownum).getCell(0).setCellStyle(style);\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        // Condition 1: Formula Is   =A2=A1   (White Font)\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("AND(A2-TODAY()>=0,A2-TODAY()<=30)");\r
+        FontFormatting font = rule1.createFontFormatting();\r
+        font.setFontStyle(false, true);\r
+        font.setFontColorIndex(IndexedColors.BLUE.index);\r
+\r
+        CellRangeAddress[] regions = {\r
+                CellRangeAddress.valueOf("A2:A4")\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+\r
+        sheet.getRow(0).createCell(1).setCellValue("Dates within the next 30 days are highlighted");\r
+    }\r
+\r
+    /**\r
+     * Use Excel conditional formatting to shade alternating rows on the worksheet\r
+     */\r
+    static void shadeAlt(Sheet sheet) {\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        // Condition 1: Formula Is   =A2=A1   (White Font)\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("MOD(ROW(),2)");\r
+        PatternFormatting fill1 = rule1.createPatternFormatting();\r
+        fill1.setFillBackgroundColor(IndexedColors.LIGHT_GREEN.index);\r
+        fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);\r
+\r
+        CellRangeAddress[] regions = {\r
+                CellRangeAddress.valueOf("A1:Z100")\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+\r
+        sheet.createRow(0).createCell(1).setCellValue("Shade Alternating Rows");\r
+        sheet.createRow(1).createCell(1).setCellValue("Condition: Formula Is  =MOD(ROW(),2)   (Light Green Fill)");\r
+    }\r
+\r
+    /**\r
+     * You can use Excel conditional formatting to shade bands of rows on the worksheet. \r
+     * In this example, 3 rows are shaded light grey, and 3 are left with no shading.\r
+     * In the MOD function, the total number of rows in the set of banded rows (6) is entered.\r
+     */\r
+    static void shadeBands(Sheet sheet) {\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("MOD(ROW(),6)<3");\r
+        PatternFormatting fill1 = rule1.createPatternFormatting();\r
+        fill1.setFillBackgroundColor(IndexedColors.GREY_25_PERCENT.index);\r
+        fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);\r
+\r
+        CellRangeAddress[] regions = {\r
+                CellRangeAddress.valueOf("A1:Z100")\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, rule1);\r
+\r
+        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
index 178e1675ef70e69e428b0227ae2e4357a7f8ceac..0bd2b40e0a343f95afe93077be7c2e2a0e1de60f 100644 (file)
@@ -27,38 +27,8 @@ import org.apache.poi.hssf.record.cf.BorderFormatting;
  * @author Dmitriy Kumshayev
  *
  */
-public final class HSSFBorderFormatting
+public final class HSSFBorderFormatting implements org.apache.poi.ss.usermodel.BorderFormatting
 {
-       /** No border */
-       public final static short BORDER_NONE =  BorderFormatting.BORDER_NONE;
-       /** Thin border */
-       public final static short BORDER_THIN =  BorderFormatting.BORDER_THIN;
-       /** Medium border */
-       public final static short BORDER_MEDIUM =  BorderFormatting.BORDER_MEDIUM;
-       /** dash border */
-       public final static short BORDER_DASHED =  BorderFormatting.BORDER_DASHED;
-       /** dot border */
-       public final static short BORDER_HAIR =  BorderFormatting.BORDER_HAIR;
-       /** Thick border */
-       public final static short BORDER_THICK =  BorderFormatting.BORDER_THICK;
-       /** double-line border */
-       public final static short BORDER_DOUBLE =  BorderFormatting.BORDER_DOUBLE;
-       /** hair-line border */
-       public final static short BORDER_DOTTED =  BorderFormatting.BORDER_DOTTED;
-       /** Medium dashed border */
-       public final static short BORDER_MEDIUM_DASHED =  BorderFormatting.BORDER_MEDIUM_DASHED;
-       /** dash-dot border */
-       public final static short BORDER_DASH_DOT =  BorderFormatting.BORDER_DASH_DOT;
-       /** medium dash-dot border */
-       public final static short BORDER_MEDIUM_DASH_DOT =  BorderFormatting.BORDER_MEDIUM_DASH_DOT;
-       /** dash-dot-dot border */
-       public final static short BORDER_DASH_DOT_DOT =  BorderFormatting.BORDER_DASH_DOT_DOT;
-       /** medium dash-dot-dot border */
-       public final static short BORDER_MEDIUM_DASH_DOT_DOT =  BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT;
-       /** slanted dash-dot border */
-       public final static short BORDER_SLANTED_DASH_DOT =  BorderFormatting.BORDER_SLANTED_DASH_DOT;
-
-       
        private final CFRuleRecord cfRuleRecord;
        private final BorderFormatting borderFormatting;
        
index 1d843c6848ea8d41f93f6bd37c88ad6f4fa03eec..80fb4ef99f73701d2348c7a490794e501e9ea53b 100644 (file)
@@ -18,6 +18,8 @@ package org.apache.poi.hssf.usermodel;
 
 import org.apache.poi.hssf.record.CFRuleRecord;
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
+import org.apache.poi.ss.usermodel.ConditionalFormatting;
+import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.Region;
 
@@ -74,7 +76,7 @@ import org.apache.poi.ss.util.Region;
  * 
  * @author Dmitriy Kumshayev
  */
-public final class HSSFConditionalFormatting
+public final class HSSFConditionalFormatting  implements ConditionalFormatting
 {
        private final HSSFWorkbook _workbook;
        private final CFRecordsAggregate cfAggregate;
@@ -122,6 +124,10 @@ public final class HSSFConditionalFormatting
                cfAggregate.setRule(idx, cfRule.getCfRuleRecord());
        }
 
+    public void setRule(int idx, ConditionalFormattingRule cfRule){
+        setRule(idx, (HSSFConditionalFormattingRule)cfRule);
+    }
+
        /**
         * add a Conditional Formatting rule. 
         * Excel allows to create up to 3 Conditional Formatting rules.
@@ -132,6 +138,10 @@ public final class HSSFConditionalFormatting
                cfAggregate.addRule(cfRule.getCfRuleRecord());
        }
 
+    public void addRule(ConditionalFormattingRule cfRule){
+        addRule((HSSFConditionalFormattingRule)cfRule);
+    }
+
        /**
         * @return the Conditional Formatting rule at position idx.
         */
index 82f7884d6ff95c0490aa37b7d9412f84750b2a2c..53f5423eb7daefc4ff52f675411bd6f78680f083 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.poi.hssf.record.cf.BorderFormatting;
 import org.apache.poi.hssf.record.cf.FontFormatting;
 import org.apache.poi.hssf.record.cf.PatternFormatting;
 import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
 
 /**
  *
@@ -33,7 +34,7 @@ import org.apache.poi.ss.formula.ptg.Ptg;
  *
  * @author Dmitriy Kumshayev
  */
-public final class HSSFConditionalFormattingRule
+public final class HSSFConditionalFormattingRule implements ConditionalFormattingRule
 {
        private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS;
 
index f55fe64b574fe44c5ef3c3b279a03967b1819dce..da1ddae6fa625e4c579eb1c9b705996dfa2e9e04 100644 (file)
@@ -26,24 +26,18 @@ import org.apache.poi.hssf.record.cf.FontFormatting;
  * @author Dmitriy Kumshayev
  *
  */
-public final class HSSFFontFormatting
+public final class HSSFFontFormatting implements org.apache.poi.ss.usermodel.FontFormatting
 {
-       /** Escapement type - None */
-       public final static short SS_NONE  = FontFormatting.SS_NONE;
-       /** Escapement type - Superscript */
-       public final static short SS_SUPER = FontFormatting.SS_SUPER;
-       /** Escapement type - Subscript */
-       public final static short SS_SUB   = FontFormatting.SS_SUB;
-
-       /** Underline type - None */ 
+
+       /** Underline type - None */
        public final static byte U_NONE              = FontFormatting.U_NONE;
-       /** Underline type - Single */ 
+       /** Underline type - Single */
        public final static byte U_SINGLE            = FontFormatting.U_SINGLE;
-       /** Underline type - Double */ 
+       /** Underline type - Double */
        public final static byte U_DOUBLE            = FontFormatting.U_DOUBLE;
-       /**  Underline type - Single Accounting */ 
+       /**  Underline type - Single Accounting */
        public final static byte U_SINGLE_ACCOUNTING = FontFormatting.U_SINGLE_ACCOUNTING;
-       /** Underline type - Double Accounting */ 
+       /** Underline type - Double Accounting */
        public final static byte U_DOUBLE_ACCOUNTING = FontFormatting.U_DOUBLE_ACCOUNTING;
 
        private final FontFormatting fontFormatting;
index f0d31aad2b17dd448267ba3a454acfcf3a6595ae..d97d03cfb8e4a68524bd47ebdd0b0045b885a1a8 100644 (file)
@@ -26,47 +26,8 @@ import org.apache.poi.hssf.record.cf.PatternFormatting;
  * @author Dmitriy Kumshayev
  *
  */
-public class HSSFPatternFormatting
+public class HSSFPatternFormatting implements org.apache.poi.ss.usermodel.PatternFormatting
 {
-       /**  No background */
-       public final static short NO_FILL                               =  PatternFormatting.NO_FILL;
-       /**  Solidly filled */
-       public final static short SOLID_FOREGROUND              =  PatternFormatting.SOLID_FOREGROUND;
-       /**  Small fine dots */
-       public final static short FINE_DOTS                     =  PatternFormatting.FINE_DOTS;
-       /**  Wide dots */
-       public final static short ALT_BARS                              =  PatternFormatting.ALT_BARS;
-       /**  Sparse dots */
-       public final static short SPARSE_DOTS                   =  PatternFormatting.SPARSE_DOTS;
-       /**  Thick horizontal bands */
-       public final static short THICK_HORZ_BANDS              =  PatternFormatting.THICK_HORZ_BANDS;
-       /**  Thick vertical bands */
-       public final static short THICK_VERT_BANDS              =  PatternFormatting.THICK_VERT_BANDS;
-       /**  Thick backward facing diagonals */
-       public final static short THICK_BACKWARD_DIAG   =  PatternFormatting.THICK_BACKWARD_DIAG;
-       /**  Thick forward facing diagonals */
-       public final static short THICK_FORWARD_DIAG    =  PatternFormatting.THICK_FORWARD_DIAG;
-       /**  Large spots */
-       public final static short BIG_SPOTS                     =  PatternFormatting.BIG_SPOTS;
-       /**  Brick-like layout */
-       public final static short BRICKS                                =  PatternFormatting.BRICKS;
-       /**  Thin horizontal bands */
-       public final static short THIN_HORZ_BANDS               =  PatternFormatting.THIN_HORZ_BANDS;
-       /**  Thin vertical bands */
-       public final static short THIN_VERT_BANDS               =  PatternFormatting.THIN_VERT_BANDS;
-       /**  Thin backward diagonal */
-       public final static short THIN_BACKWARD_DIAG    =  PatternFormatting.THIN_BACKWARD_DIAG;
-       /**  Thin forward diagonal */
-       public final static short THIN_FORWARD_DIAG     =  PatternFormatting.THIN_FORWARD_DIAG;
-       /**  Squares */
-       public final static short SQUARES                               =  PatternFormatting.SQUARES;
-       /**  Diamonds */
-       public final static short DIAMONDS                              =  PatternFormatting.DIAMONDS;
-       /**  Less Dots */
-       public final static short LESS_DOTS                     =  PatternFormatting.LESS_DOTS;
-       /**  Least Dots */
-       public final static short LEAST_DOTS                    =  PatternFormatting.LEAST_DOTS;
-
        private final CFRuleRecord cfRuleRecord;
        private final PatternFormatting patternFormatting;
        
index ab539c22de687ce32cb6b49929fe35d7e7837fb4..b75f0a620f16d01a24c232dbae223193189dd7c0 100644 (file)
@@ -20,6 +20,9 @@ package org.apache.poi.hssf.usermodel;
 import org.apache.poi.hssf.record.CFRuleRecord;
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
 import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
+import org.apache.poi.ss.usermodel.ConditionalFormatting;
+import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
+import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
 import org.apache.poi.ss.util.Region;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.SpreadsheetVersion;
@@ -29,7 +32,7 @@ import org.apache.poi.ss.SpreadsheetVersion;
  *
  * @author Dmitriy Kumshayev
  */
-public final class HSSFSheetConditionalFormatting {
+public final class HSSFSheetConditionalFormatting implements SheetConditionalFormatting {
 
        private final HSSFSheet _sheet;
        private final ConditionalFormattingTable _conditionalFormattingTable;
@@ -72,6 +75,15 @@ public final class HSSFSheetConditionalFormatting {
                return new HSSFConditionalFormattingRule(wb, rr);
        }
 
+    public HSSFConditionalFormattingRule createConditionalFormattingRule(
+            byte comparisonOperation,
+            String formula1) {
+
+        HSSFWorkbook wb = _sheet.getWorkbook();
+        CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, null);
+        return new HSSFConditionalFormattingRule(wb, rr);
+    }
+
        /**
         * A factory method allowing to create a conditional formatting rule with a formula.<br>
         *
@@ -102,6 +114,11 @@ public final class HSSFSheetConditionalFormatting {
 
                return _conditionalFormattingTable.add(cfraClone);
        }
+
+    public int addConditionalFormatting( ConditionalFormatting cf ) {
+        return addConditionalFormatting((HSSFConditionalFormatting)cf);
+    }
+
        /**
         * @deprecated use <tt>CellRangeAddress</tt> instead of <tt>Region</tt>
         */
@@ -140,16 +157,32 @@ public final class HSSFSheetConditionalFormatting {
                return _conditionalFormattingTable.add(cfra);
        }
 
+    public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) {
+        HSSFConditionalFormattingRule[] hfRules;
+        if(cfRules instanceof HSSFConditionalFormattingRule[]) hfRules = (HSSFConditionalFormattingRule[])cfRules;
+        else {
+            hfRules = new HSSFConditionalFormattingRule[cfRules.length];
+            System.arraycopy(cfRules, 0, hfRules, 0, hfRules.length);
+        }
+        return addConditionalFormatting(regions, hfRules);
+    }
+
        public int addConditionalFormatting(CellRangeAddress[] regions,
                        HSSFConditionalFormattingRule rule1)
        {
                return addConditionalFormatting(regions,
-                               new HSSFConditionalFormattingRule[]
+                               rule1 == null ? null : new HSSFConditionalFormattingRule[]
                                {
                                        rule1
                                });
        }
 
+    public int addConditionalFormatting(CellRangeAddress[] regions,
+            ConditionalFormattingRule rule1)
+    {
+        return addConditionalFormatting(regions,  (HSSFConditionalFormattingRule)rule1);
+    }
+
        public int addConditionalFormatting(CellRangeAddress[] regions,
                        HSSFConditionalFormattingRule rule1,
                        HSSFConditionalFormattingRule rule2)
@@ -161,6 +194,16 @@ public final class HSSFSheetConditionalFormatting {
                                });
        }
 
+    public int addConditionalFormatting(CellRangeAddress[] regions,
+            ConditionalFormattingRule rule1,
+            ConditionalFormattingRule rule2)
+    {
+        return addConditionalFormatting(regions,
+                (HSSFConditionalFormattingRule)rule1,
+                (HSSFConditionalFormattingRule)rule2
+                );
+    }
+
        /**
        * gets Conditional Formatting object at a particular index
        *
diff --git a/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java b/src/java/org/apache/poi/ss/usermodel/BorderFormatting.java
new file mode 100644 (file)
index 0000000..c15dc26
--- /dev/null
@@ -0,0 +1,115 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+/**\r
+ * @author Dmitriy Kumshayev\r
+ * @author Yegor Kozlov\r
+ */\r
+public interface BorderFormatting {\r
+    /** No border */\r
+    final static short    BORDER_NONE                = 0x0;\r
+    /** Thin border */\r
+    final static short    BORDER_THIN                = 0x1;\r
+    /** Medium border */\r
+    final static short    BORDER_MEDIUM              = 0x2;\r
+    /** dash border */\r
+    final static short    BORDER_DASHED              = 0x3;\r
+    /** dot border */\r
+    final static short    BORDER_HAIR                = 0x4;\r
+    /** Thick border */\r
+    final static short    BORDER_THICK               = 0x5;\r
+    /** double-line border */\r
+    final static short    BORDER_DOUBLE              = 0x6;\r
+    /** hair-line border */\r
+    final static short    BORDER_DOTTED              = 0x7;\r
+    /** Medium dashed border */\r
+    final static short    BORDER_MEDIUM_DASHED       = 0x8;\r
+    /** dash-dot border */\r
+    final static short    BORDER_DASH_DOT            = 0x9;\r
+    /** medium dash-dot border */\r
+    final static short    BORDER_MEDIUM_DASH_DOT     = 0xA;\r
+    /** dash-dot-dot border */\r
+    final static short    BORDER_DASH_DOT_DOT        = 0xB;\r
+    /** medium dash-dot-dot border */\r
+    final static short    BORDER_MEDIUM_DASH_DOT_DOT = 0xC;\r
+    /** slanted dash-dot border */\r
+    final static short    BORDER_SLANTED_DASH_DOT    = 0xD;\r
+\r
+    short getBorderBottom();\r
+\r
+    short getBorderDiagonal();\r
+\r
+    short getBorderLeft();\r
+\r
+    short getBorderRight();\r
+\r
+    short getBorderTop();\r
+\r
+    short getBottomBorderColor();\r
+\r
+    short getDiagonalBorderColor();\r
+\r
+    short getLeftBorderColor();\r
+\r
+    short getRightBorderColor();\r
+\r
+    short getTopBorderColor();\r
+\r
+    void setBorderBottom(short border);\r
+\r
+    /**\r
+     * Set diagonal border.\r
+     *\r
+     * @param border  MUST be a BORDER_* constant\r
+     */\r
+    void setBorderDiagonal(short border);\r
+\r
+    /**\r
+     * Set left border.\r
+     *\r
+     * @param border  MUST be a BORDER_* constant\r
+     */\r
+    void setBorderLeft(short border);\r
+\r
+    /**\r
+     * Set right border.\r
+     *\r
+     * @param border  MUST be a BORDER_* constant\r
+     */\r
+    void setBorderRight(short border);\r
+\r
+    /**\r
+     * Set top border.\r
+     *\r
+     * @param border  MUST be a BORDER_* constant\r
+     */\r
+    void setBorderTop(short border);\r
+\r
+    void setBottomBorderColor(short color);\r
+\r
+    void setDiagonalBorderColor(short color);\r
+\r
+    void setLeftBorderColor(short color);\r
+\r
+    void setRightBorderColor(short color);\r
+\r
+    void setTopBorderColor(short color);\r
+}\r
diff --git a/src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java b/src/java/org/apache/poi/ss/usermodel/ComparisonOperator.java
new file mode 100644 (file)
index 0000000..7e29cbf
--- /dev/null
@@ -0,0 +1,73 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+/**\r
+ * The conditional format operators used for "Highlight Cells That Contain..." rules.\r
+ * <p>\r
+ * For example, "highlight cells that begin with "M2" and contain "Mountain Gear".\r
+ * </p>\r
+ *\r
+ * @author Dmitriy Kumshayev\r
+ * @author Yegor Kozlov\r
+ */\r
+public final class ComparisonOperator {\r
+    public static final byte NO_COMPARISON = 0;\r
+\r
+    /**\r
+     * 'Between' operator\r
+     */\r
+    public static final byte BETWEEN       = 1;\r
+\r
+    /**\r
+     * 'Not between' operator\r
+     */\r
+    public static final byte NOT_BETWEEN   = 2;\r
+\r
+    /**\r
+     *  'Equal to' operator\r
+     */\r
+    public static final byte EQUAL         = 3;\r
+\r
+    /**\r
+     * 'Not equal to' operator\r
+     */\r
+    public static final byte NOT_EQUAL     = 4;\r
+\r
+    /**\r
+     * 'Greater than' operator\r
+     */\r
+    public static final byte GT            = 5;\r
+\r
+    /**\r
+     * 'Less than' operator\r
+     */\r
+    public static final byte LT            = 6;\r
+\r
+    /**\r
+     * 'Greater than or equal to' operator\r
+     */\r
+    public static final byte GE            = 7;\r
+\r
+    /**\r
+     * 'Less than or equal to' operator\r
+     */\r
+    public static final byte LE            = 8;\r
+}\r
diff --git a/src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java b/src/java/org/apache/poi/ss/usermodel/ConditionalFormatting.java
new file mode 100644 (file)
index 0000000..8b117ce
--- /dev/null
@@ -0,0 +1,115 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+import org.apache.poi.hssf.usermodel.HSSFConditionalFormattingRule;\r
+import org.apache.poi.ss.util.CellRangeAddress;\r
+\r
+/**\r
+ * The ConditionalFormatting class encapsulates all settings of Conditional Formatting.\r
+ *\r
+ * The class can be used\r
+ *\r
+ * <UL>\r
+ * <LI>\r
+ * to make a copy ConditionalFormatting settings.\r
+ * </LI>\r
+ *\r
+ *\r
+ * For example:\r
+ * <PRE>\r
+ * ConditionalFormatting cf = sheet.getConditionalFormattingAt(index);\r
+ * newSheet.addConditionalFormatting(cf);\r
+ * </PRE>\r
+ *\r
+ *  <LI>\r
+ *  or to modify existing Conditional Formatting settings (formatting regions and/or rules).\r
+ *  </LI>\r
+ *  </UL>\r
+ *\r
+ * Use {@link org.apache.poi.hssf.usermodel.Sheet#getSheetConditionalFormatting()} to get access to an instance of this class.\r
+ * <P>\r
+ * To create a new Conditional Formatting set use the following approach:\r
+ *\r
+ * <PRE>\r
+ *\r
+ * // Define a Conditional Formatting rule, which triggers formatting\r
+ * // when cell's value is greater or equal than 100.0 and\r
+ * // applies patternFormatting defined below.\r
+ * ConditionalFormattingRule rule = sheet.createConditionalFormattingRule(\r
+ *     ComparisonOperator.GE,\r
+ *     "100.0", // 1st formula\r
+ *     null     // 2nd formula is not used for comparison operator GE\r
+ * );\r
+ *\r
+ * // Create pattern with red background\r
+ * PatternFormatting patternFmt = rule.cretePatternFormatting();\r
+ * patternFormatting.setFillBackgroundColor(IndexedColor.RED.getIndex());\r
+ *\r
+ * // Define a region containing first column\r
+ * Region [] regions =\r
+ * {\r
+ *     new Region(1,(short)1,-1,(short)1)\r
+ * };\r
+ *\r
+ * // Apply Conditional Formatting rule defined above to the regions\r
+ * sheet.addConditionalFormatting(regions, rule);\r
+ * </PRE>\r
+ *\r
+ * @author Dmitriy Kumshayev\r
+ * @author Yegor Kozlov\r
+ */\r
+public interface ConditionalFormatting {\r
+\r
+    /**\r
+     * @return array of <tt>CellRangeAddress</tt>s. Never <code>null</code>\r
+     */\r
+    CellRangeAddress[] getFormattingRanges();\r
+\r
+    /**\r
+     * Replaces an existing Conditional Formatting rule at position idx.\r
+     * Excel allows to create up to 3 Conditional Formatting rules.\r
+     * This method can be useful to modify existing  Conditional Formatting rules.\r
+     *\r
+     * @param idx position of the rule. Should be between 0 and 2.\r
+     * @param cfRule - Conditional Formatting rule\r
+     */\r
+    void setRule(int idx, ConditionalFormattingRule cfRule);\r
+\r
+    /**\r
+     * Add a Conditional Formatting rule.\r
+     * Excel allows to create up to 3 Conditional Formatting rules.\r
+     *\r
+     * @param cfRule - Conditional Formatting rule\r
+     */\r
+    void addRule(ConditionalFormattingRule cfRule);\r
+\r
+    /**\r
+     * @return the Conditional Formatting rule at position idx.\r
+     */\r
+    ConditionalFormattingRule getRule(int idx);\r
+\r
+    /**\r
+     * @return number of Conditional Formatting rules.\r
+     */\r
+    int getNumberOfRules();\r
+\r
+\r
+}\r
diff --git a/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java b/src/java/org/apache/poi/ss/usermodel/ConditionalFormattingRule.java
new file mode 100644 (file)
index 0000000..1c63f19
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+/**\r
+ * Represents a description of a conditional formatting rule\r
+ *\r
+ * @author Dmitriy Kumshayev\r
+ * @author Yegor Kozlov\r
+ */\r
+public interface ConditionalFormattingRule {\r
+    /**\r
+     * This conditional formatting rule compares a cell value\r
+     * to a formula calculated result, using an operator\r
+     */\r
+    public static final byte CONDITION_TYPE_CELL_VALUE_IS = 1;\r
+\r
+    /**\r
+     *  This conditional formatting rule contains a formula to evaluate.\r
+     *  When the formula result is true, the cell is highlighted.\r
+     */\r
+    public static final byte CONDITION_TYPE_FORMULA = 2;\r
+\r
+    /**\r
+     * Create a new border formatting structure if it does not exist,\r
+     * otherwise just return existing object.\r
+     *\r
+     * @return - border formatting object, never returns <code>null</code>.\r
+     */\r
+    BorderFormatting createBorderFormatting();\r
+\r
+    /**\r
+     * @return - border formatting object  if defined,  <code>null</code> otherwise\r
+     */\r
+    BorderFormatting getBorderFormatting();\r
+\r
+    /**\r
+     * Create a new font formatting structure if it does not exist,\r
+     * otherwise just return existing object.\r
+     *\r
+     * @return - font formatting object, never returns <code>null</code>.\r
+     */\r
+    FontFormatting createFontFormatting();\r
+\r
+    /**\r
+     * @return - font formatting object  if defined,  <code>null</code> otherwise\r
+     */\r
+    FontFormatting getFontFormatting();\r
+\r
+    /**\r
+     * Create a new pattern formatting structure if it does not exist,\r
+     * otherwise just return existing object.\r
+     *\r
+     * @return - pattern formatting object, never returns <code>null</code>.\r
+     */\r
+    PatternFormatting createPatternFormatting();\r
+\r
+    /**\r
+     * @return - pattern formatting object  if defined,  <code>null</code> otherwise\r
+     */\r
+    PatternFormatting getPatternFormatting();\r
+\r
+    /**\r
+     * Type of conditional formatting rule.\r
+     * <p>\r
+     * MUST be either {@link #CONDITION_TYPE_CELL_VALUE_IS} or  {@link #CONDITION_TYPE_FORMULA}\r
+     * </p>\r
+     *\r
+     * @return the type of condition\r
+     */\r
+    byte getConditionType();\r
+\r
+    /**\r
+     * The comparison function used when the type of conditional formatting is set to\r
+     * {@link #CONDITION_TYPE_CELL_VALUE_IS}\r
+     * <p>\r
+     *     MUST be a constant from {@link ComparisonOperator}\r
+     * </p>\r
+     *\r
+     * @return the conditional format operator\r
+     */\r
+    byte getComparisonOperation();\r
+\r
+    /**\r
+     * The formula used to evaluate the first operand for the conditional formatting rule.\r
+     * <p>\r
+     * If the condition type is {@link #CONDITION_TYPE_CELL_VALUE_IS},\r
+     * this field is the first operand of the comparison.\r
+     * If type is {@link #CONDITION_TYPE_FORMULA}, this formula is used\r
+     * to determine if the conditional formatting is applied.\r
+     * </p>\r
+     * <p>\r
+     * If comparison type is {@link #CONDITION_TYPE_FORMULA} the formula MUST be a Boolean function\r
+     * </p>\r
+     *\r
+     * @return  the first formula\r
+     */\r
+    String getFormula1();\r
+\r
+    /**\r
+     * The formula used to evaluate the second operand of the comparison when\r
+     * comparison type is  {@link #CONDITION_TYPE_CELL_VALUE_IS} and operator\r
+     * is either {@link ComparisonOperator#BETWEEN} or {@link ComparisonOperator#NOT_BETWEEN}\r
+     *\r
+     * @return  the second formula\r
+     */\r
+    String getFormula2();\r
+}\r
diff --git a/src/java/org/apache/poi/ss/usermodel/FontFormatting.java b/src/java/org/apache/poi/ss/usermodel/FontFormatting.java
new file mode 100644 (file)
index 0000000..2298d79
--- /dev/null
@@ -0,0 +1,143 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+/**\r
+ * High level representation for Font Formatting component\r
+ * of Conditional Formatting settings\r
+ *\r
+ * @author Dmitriy Kumshayev\r
+ * @author Yegor Kozlov\r
+ */\r
+public interface FontFormatting {\r
+    /** Escapement type - None */\r
+    public final static short SS_NONE  = 0;\r
+    /** Escapement type - Superscript */\r
+    public final static short SS_SUPER = 1;\r
+    /** Escapement type - Subscript */\r
+    public final static short SS_SUB   = 2;\r
+\r
+    /** Underline type - None */\r
+    public final static byte U_NONE              = 0;\r
+    /** Underline type - Single */\r
+    public final static byte U_SINGLE            = 1;\r
+    /** Underline type - Double */\r
+    public final static byte U_DOUBLE            = 2;\r
+    /**  Underline type - Single Accounting */\r
+    public final static byte U_SINGLE_ACCOUNTING = 0x21;\r
+    /** Underline type - Double Accounting */\r
+    public final static byte U_DOUBLE_ACCOUNTING = 0x22;\r
+\r
+    /**\r
+     * get the type of super or subscript for the font\r
+     *\r
+     * @return super or subscript option\r
+     * @see #SS_NONE\r
+     * @see #SS_SUPER\r
+     * @see #SS_SUB\r
+     */\r
+    short getEscapementType();\r
+\r
+    /**\r
+     * set the escapement type for the font\r
+     *\r
+     * @param escapementType  super or subscript option\r
+     * @see #SS_NONE\r
+     * @see #SS_SUPER\r
+     * @see #SS_SUB\r
+     */\r
+    void setEscapementType(short escapementType);\r
+\r
+    /**\r
+     * @return font color index\r
+     */\r
+    short getFontColorIndex();\r
+\r
+\r
+    /**\r
+     * @param color font color index\r
+     */\r
+    void setFontColorIndex(short color);\r
+\r
+    /**\r
+     * gets the height of the font in 1/20th point units\r
+     *\r
+     * @return fontheight (in points/20); or -1 if not modified\r
+     */\r
+    int getFontHeight();\r
+\r
+    /**\r
+     * Sets the height of the font in 1/20th point units\r
+     *\r
+     * @param height the height in twips (in points/20)\r
+     */\r
+    void setFontHeight(int height);\r
+\r
+    /**\r
+     * get the type of underlining for the font\r
+     *\r
+     * @return font underlining type\r
+     *\r
+     * @see #U_NONE\r
+     * @see #U_SINGLE\r
+     * @see #U_DOUBLE\r
+     * @see #U_SINGLE_ACCOUNTING\r
+     * @see #U_DOUBLE_ACCOUNTING\r
+     */\r
+    short getUnderlineType();\r
+\r
+    /**\r
+     * set the type of underlining type for the font\r
+     *\r
+     * @param underlineType  super or subscript option\r
+     *\r
+     * @see #U_NONE\r
+     * @see #U_SINGLE\r
+     * @see #U_DOUBLE\r
+     * @see #U_SINGLE_ACCOUNTING\r
+     * @see #U_DOUBLE_ACCOUNTING\r
+     */\r
+    void setUnderlineType(short underlineType);\r
+\r
+    /**\r
+     * get whether the font weight is set to bold or not\r
+     *\r
+     * @return bold - whether the font is bold or not\r
+     */\r
+    boolean isBold();\r
+\r
+    /**\r
+     * @return true if font style was set to <i>italic</i>\r
+     */\r
+    boolean isItalic();\r
+\r
+    /**\r
+     * set font style options.\r
+     *\r
+     * @param italic - if true, set posture style to italic, otherwise to normal\r
+     * @param bold if true, set font weight to bold, otherwise to normal\r
+     */\r
+    void setFontStyle(boolean italic, boolean bold);\r
+\r
+    /**\r
+     * set font style options to default values (non-italic, non-bold)\r
+     */\r
+    void resetFontStyle();\r
+}\r
index 07237471aa18ae811284c2f3ad2fee18f3bc9458..61d7f6818c6f79257018f6df693998e93ac4d8d7 100644 (file)
@@ -80,10 +80,10 @@ public enum IndexedColors {
     GREY_80_PERCENT(63),
     AUTOMATIC(64);
 
-    private int index;
+    public final short index;
 
     IndexedColors(int idx){
-        index = idx;
+        index = (short)idx;
     }
 
     /**
@@ -92,6 +92,6 @@ public enum IndexedColors {
      * @return index of this color
      */
     public short getIndex(){
-        return (short)index;
+        return index;
     }
 }
diff --git a/src/java/org/apache/poi/ss/usermodel/PatternFormatting.java b/src/java/org/apache/poi/ss/usermodel/PatternFormatting.java
new file mode 100644 (file)
index 0000000..2739c96
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public interface PatternFormatting {\r
+    /**  No background */\r
+    public final static short     NO_FILL             = 0  ;\r
+    /**  Solidly filled */\r
+    public final static short     SOLID_FOREGROUND    = 1  ;\r
+    /**  Small fine dots */\r
+    public final static short     FINE_DOTS           = 2  ;\r
+    /**  Wide dots */\r
+    public final static short     ALT_BARS            = 3  ;\r
+    /**  Sparse dots */\r
+    public final static short     SPARSE_DOTS         = 4  ;\r
+    /**  Thick horizontal bands */\r
+    public final static short     THICK_HORZ_BANDS    = 5  ;\r
+    /**  Thick vertical bands */\r
+    public final static short     THICK_VERT_BANDS    = 6  ;\r
+    /**  Thick backward facing diagonals */\r
+    public final static short     THICK_BACKWARD_DIAG = 7  ;\r
+    /**  Thick forward facing diagonals */\r
+    public final static short     THICK_FORWARD_DIAG  = 8  ;\r
+    /**  Large spots */\r
+    public final static short     BIG_SPOTS           = 9  ;\r
+    /**  Brick-like layout */\r
+    public final static short     BRICKS              = 10 ;\r
+    /**  Thin horizontal bands */\r
+    public final static short     THIN_HORZ_BANDS     = 11 ;\r
+    /**  Thin vertical bands */\r
+    public final static short     THIN_VERT_BANDS     = 12 ;\r
+    /**  Thin backward diagonal */\r
+    public final static short     THIN_BACKWARD_DIAG  = 13 ;\r
+    /**  Thin forward diagonal */\r
+    public final static short     THIN_FORWARD_DIAG   = 14 ;\r
+    /**  Squares */\r
+    public final static short     SQUARES             = 15 ;\r
+    /**  Diamonds */\r
+    public final static short     DIAMONDS            = 16 ;\r
+    /**  Less Dots */\r
+    public final static short     LESS_DOTS           = 17 ;\r
+    /**  Least Dots */\r
+    public final static short     LEAST_DOTS          = 18 ;\r
+\r
+    short getFillBackgroundColor();\r
+\r
+    short getFillForegroundColor();\r
+\r
+    short getFillPattern();\r
+\r
+    void setFillBackgroundColor(short bg);\r
+\r
+    void setFillForegroundColor(short fg);\r
+\r
+    void setFillPattern(short fp);\r
+}\r
index b68f0fdd7272aa3ff36293201a8e82dbbf0adddc..5be4f1f5e63915be1a6fe245e5343949ae5470eb 100644 (file)
@@ -919,5 +919,12 @@ public interface Sheet extends Iterable<Row> {
      * @param range the range of cells to filter
      */
     AutoFilter setAutoFilter(CellRangeAddress range);
-    
+
+    /**
+     * The 'Conditional Formatting' facet for this <tt>Sheet</tt>
+     *
+     * @return  conditional formatting rule for this sheet
+     */
+    SheetConditionalFormatting getSheetConditionalFormatting();
+
 }
diff --git a/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java b/src/java/org/apache/poi/ss/usermodel/SheetConditionalFormatting.java
new file mode 100644 (file)
index 0000000..37387c8
--- /dev/null
@@ -0,0 +1,163 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+import org.apache.poi.ss.util.CellRangeAddress;\r
+\r
+/**\r
+ * The 'Conditional Formatting' facet of <tt>Sheet</tt>\r
+ *\r
+ * @author Dmitriy Kumshayev\r
+ * @author Yegor Kozlov\r
+ * @since 3.8\r
+ */\r
+public interface SheetConditionalFormatting {\r
+\r
+    /**\r
+     * Add a new Conditional Formatting to the sheet.\r
+     *\r
+     * @param regions - list of rectangular regions to apply conditional formatting rules\r
+     * @param rule -  the rule to apply\r
+     *\r
+     * @return index of the newly created Conditional Formatting object\r
+     */\r
+    int addConditionalFormatting(CellRangeAddress[] regions,\r
+                                 ConditionalFormattingRule rule);\r
+\r
+    /**\r
+     * Add a new Conditional Formatting consisting of two rules.\r
+     *\r
+     * @param regions - list of rectangular regions to apply conditional formatting rules\r
+     * @param rule1 -  the first rule\r
+     * @param rule1 -  the second rule\r
+     *\r
+     * @return index of the newly created Conditional Formatting object\r
+     */\r
+    int addConditionalFormatting(CellRangeAddress[] regions,\r
+                                 ConditionalFormattingRule rule1,\r
+                                 ConditionalFormattingRule rule2);\r
+\r
+    /**\r
+     * Add a new Conditional Formatting set to the sheet.\r
+     *\r
+     * @param regions - list of rectangular regions to apply conditional formatting rules\r
+     * @param cfRules - set of up to three conditional formatting rules\r
+     *\r
+     * @return index of the newly created Conditional Formatting object\r
+     */\r
+    int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules);\r
+\r
+    /**\r
+     * Adds a copy of a ConditionalFormatting object to the sheet\r
+     * <p>\r
+     *     This method could be used to copy ConditionalFormatting object\r
+     *     from one sheet to another. For example:\r
+     * </p>\r
+     * <pre>\r
+     * ConditionalFormatting cf = sheet.getConditionalFormattingAt(index);\r
+     * newSheet.addConditionalFormatting(cf);\r
+     * </pre>\r
+     *\r
+     * @param cf the Conditional Formatting to clone\r
+     * @return index of the new Conditional Formatting object\r
+     */\r
+    int addConditionalFormatting(ConditionalFormatting cf);\r
+\r
+    /**\r
+     * A factory method allowing to create a conditional formatting rule\r
+     * with a cell comparison operator\r
+     * <p>\r
+     * The created conditional formatting rule compares a cell value\r
+     * to a formula calculated result, using the specified operator.\r
+     * The type  of the created condition is {@link ConditionalFormattingRule#CONDITION_TYPE_CELL_VALUE_IS}\r
+     * </p>\r
+     *\r
+     * @param comparisonOperation - MUST be a constant value from\r
+     *          <tt>{@link ComparisonOperator}</tt>: <p>\r
+     * <ul>\r
+     *          <li>BETWEEN</li>\r
+     *          <li>NOT_BETWEEN</li>\r
+     *          <li>EQUAL</li>\r
+     *          <li>NOT_EQUAL</li>\r
+     *          <li>GT</li>\r
+     *          <li>LT</li>\r
+     *          <li>GE</li>\r
+     *          <li>LE</li>\r
+     * </ul>\r
+     * </p>\r
+     * @param formula1 - formula for the valued, compared with the cell\r
+     * @param formula2 - second formula (only used with\r
+     * {@link ComparisonOperator#BETWEEN}) and {@link ComparisonOperator#NOT_BETWEEN} operations)\r
+     */\r
+    ConditionalFormattingRule createConditionalFormattingRule(\r
+            byte comparisonOperation,\r
+            String formula1,\r
+            String formula2);\r
+\r
+    /**\r
+     * Create a conditional formatting rule that compares a cell value\r
+     * to a formula calculated result, using an operator     *\r
+     * <p>\r
+      * The type  of the created condition is {@link ConditionalFormattingRule#CONDITION_TYPE_CELL_VALUE_IS}\r
+     * </p>\r
+     *\r
+     * @param comparisonOperation  MUST be a constant value from\r
+     *          <tt>{@link ComparisonOperator}</tt> except  BETWEEN and NOT_BETWEEN\r
+     *\r
+     * @param formula  the formula to determine if the conditional formatting is applied\r
+     */\r
+    ConditionalFormattingRule createConditionalFormattingRule(\r
+            byte comparisonOperation,\r
+            String formula);\r
+\r
+    /**\r
+     *  Create a conditional formatting rule based on a Boolean formula.\r
+     *  When the formula result is true, the cell is highlighted.\r
+     *\r
+     * <p>\r
+     *  The type of the created format condition is  {@link ConditionalFormattingRule#CONDITION_TYPE_FORMULA}\r
+     * </p>\r
+     * @param formula   the formula to evaluate. MUST be a Boolean function.\r
+     */\r
+    ConditionalFormattingRule createConditionalFormattingRule(String formula);\r
+\r
+    /**\r
+    * Gets Conditional Formatting object at a particular index\r
+    *\r
+    * @param index  0-based index of the Conditional Formatting object to fetch\r
+    * @return Conditional Formatting object or <code>null</code> if not found\r
+    * @throws IllegalArgumentException if the index is  outside of the allowable range (0 ... numberOfFormats-1)\r
+    */\r
+    ConditionalFormatting getConditionalFormattingAt(int index);\r
+\r
+    /**\r
+     *\r
+     * @return the number of conditional formats in this sheet\r
+     */\r
+    int getNumConditionalFormattings();\r
+\r
+    /**\r
+    * Removes a Conditional Formatting object by index\r
+    *\r
+    * @param index 0-based index of the Conditional Formatting object to remove\r
+    * @throws IllegalArgumentException if the index is  outside of the allowable range (0 ... numberOfFormats-1)\r
+    */\r
+    void removeConditionalFormatting(int index);\r
+}\r
index 3a2e87903c1bea7701c87c6b073a1eba836503a2..50dca1811c9106eafa13ee010b9c60e6a2b88407 100644 (file)
@@ -346,6 +346,9 @@ public class StylesTable extends POIXMLDocumentPart {
        public CTStylesheet getCTStylesheet() {
                return doc.getStyleSheet();
        }
+    public int _getDXfsSize() {
+        return dxfs.size();
+    }
 
 
        /**
@@ -497,14 +500,11 @@ public class StylesTable extends POIXMLDocumentPart {
                return xssfFont;
        }
 
-       protected CTDxf getDxf(int idx) {
-               if (dxfs.size()==0) {
-                       return CTDxf.Factory.newInstance();
-               }
+       public CTDxf getDxfAt(int idx) {
                return dxfs.get(idx);
        }
 
-       protected int putDxf(CTDxf dxf) {
+       public int putDxf(CTDxf dxf) {
                this.dxfs.add(dxf);
                return this.dxfs.size();
        }
index e8e000b4ef541b8976a8db0deee7843840315bfb..05dc3ec12e5ba9d94c79f0def58f205417bf562b 100644 (file)
@@ -1196,6 +1196,11 @@ public class SXSSFSheet implements Sheet, Cloneable
     {
         return _sh.setAutoFilter(range);
     }
+
+    public SheetConditionalFormatting getSheetConditionalFormatting(){
+        return _sh.getSheetConditionalFormatting();
+    }
+
 //end of interface implementation
     /**
      * Specifies how many rows can be accessed at most via getRow().
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java
new file mode 100644 (file)
index 0000000..6505841
--- /dev/null
@@ -0,0 +1,150 @@
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.apache.poi.ss.usermodel.BorderFormatting;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFBorderFormatting implements BorderFormatting  {\r
+    CTBorder _border;\r
+\r
+    /*package*/ XSSFBorderFormatting(CTBorder border){\r
+        _border = border;\r
+    }\r
+\r
+    public short getBorderBottom(){\r
+        STBorderStyle.Enum ptrn = _border.isSetBottom() ? _border.getBottom().getStyle() : null;\r
+        return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);\r
+    }\r
+\r
+    public short getBorderDiagonal(){\r
+        STBorderStyle.Enum ptrn = _border.isSetDiagonal() ? _border.getDiagonal().getStyle() : null;\r
+        return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);\r
+    }\r
+\r
+    public short getBorderLeft(){\r
+        STBorderStyle.Enum ptrn = _border.isSetLeft() ? _border.getLeft().getStyle() : null;\r
+        return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);\r
+    }\r
+\r
+    public short getBorderRight(){\r
+        STBorderStyle.Enum ptrn = _border.isSetRight() ? _border.getRight().getStyle() : null;\r
+        return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);\r
+    }\r
+\r
+    public short getBorderTop(){\r
+        STBorderStyle.Enum ptrn = _border.isSetTop() ? _border.getTop().getStyle() : null;\r
+        return ptrn == null ? BORDER_NONE : (short)(ptrn.intValue() - 1);\r
+    }\r
+\r
+    public short getBottomBorderColor(){\r
+        if(!_border.isSetBottom()) return 0;\r
+\r
+        CTBorderPr pr = _border.getBottom();\r
+        return (short)pr.getColor().getIndexed();\r
+    }\r
+\r
+    public short getDiagonalBorderColor(){\r
+        if(!_border.isSetDiagonal()) return 0;\r
+\r
+        CTBorderPr pr = _border.getDiagonal();\r
+        return (short)pr.getColor().getIndexed();\r
+    }\r
+\r
+    public short getLeftBorderColor(){\r
+        if(!_border.isSetLeft()) return 0;\r
+\r
+        CTBorderPr pr = _border.getLeft();\r
+        return (short)pr.getColor().getIndexed();\r
+    }\r
+\r
+    public short getRightBorderColor(){\r
+        if(!_border.isSetRight()) return 0;\r
+\r
+        CTBorderPr pr = _border.getRight();\r
+        return (short)pr.getColor().getIndexed();\r
+    }\r
+\r
+    public short getTopBorderColor(){\r
+        if(!_border.isSetTop()) return 0;\r
+\r
+        CTBorderPr pr = _border.getTop();\r
+        return (short)pr.getColor().getIndexed();\r
+    }\r
+\r
+    public void setBorderBottom(short border){\r
+        CTBorderPr pr = _border.isSetBottom() ? _border.getBottom() : _border.addNewBottom();\r
+        if(border == BORDER_NONE) _border.unsetBottom();\r
+        else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));\r
+    }\r
+\r
+    public void setBorderDiagonal(short border){\r
+        CTBorderPr pr = _border.isSetDiagonal() ? _border.getDiagonal() : _border.addNewDiagonal();\r
+        if(border == BORDER_NONE) _border.unsetDiagonal();\r
+        else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));\r
+    }\r
+\r
+    public void setBorderLeft(short border){\r
+        CTBorderPr pr = _border.isSetLeft() ? _border.getLeft() : _border.addNewLeft();\r
+        if(border == BORDER_NONE) _border.unsetLeft();\r
+        else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));\r
+    }\r
+\r
+    public void setBorderRight(short border){\r
+        CTBorderPr pr = _border.isSetRight() ? _border.getRight() : _border.addNewRight();\r
+        if(border == BORDER_NONE) _border.unsetRight();\r
+        else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));\r
+    }\r
+\r
+    public void setBorderTop(short border){\r
+        CTBorderPr pr = _border.isSetTop() ? _border.getTop() : _border.addNewTop();\r
+        if(border == BORDER_NONE) _border.unsetTop();\r
+        else pr.setStyle(STBorderStyle.Enum.forInt(border + 1));\r
+    }\r
+\r
+    public void setBottomBorderColor(short color){\r
+        CTBorderPr pr = _border.isSetBottom() ? _border.getBottom() : _border.addNewBottom();\r
+\r
+        CTColor ctColor = CTColor.Factory.newInstance();\r
+        ctColor.setIndexed(color);\r
+        pr.setColor(ctColor);\r
+    }\r
+\r
+    public void setDiagonalBorderColor(short color){\r
+        CTBorderPr pr = _border.isSetDiagonal() ? _border.getDiagonal() : _border.addNewDiagonal();\r
+\r
+        CTColor ctColor = CTColor.Factory.newInstance();\r
+        ctColor.setIndexed(color);\r
+        pr.setColor(ctColor);\r
+    }\r
+\r
+    public void setLeftBorderColor(short color){\r
+        CTBorderPr pr = _border.isSetLeft() ? _border.getLeft() : _border.addNewLeft();\r
+\r
+        CTColor ctColor = CTColor.Factory.newInstance();\r
+        ctColor.setIndexed(color);\r
+        pr.setColor(ctColor);\r
+    }\r
+\r
+    public void setRightBorderColor(short color){\r
+        CTBorderPr pr = _border.isSetRight() ? _border.getRight() : _border.addNewRight();\r
+\r
+        CTColor ctColor = CTColor.Factory.newInstance();\r
+        ctColor.setIndexed(color);\r
+        pr.setColor(ctColor);\r
+    }\r
+\r
+    public void setTopBorderColor(short color){\r
+        CTBorderPr pr = _border.isSetTop() ? _border.getTop() : _border.addNewTop();\r
+\r
+        CTColor ctColor = CTColor.Factory.newInstance();\r
+        ctColor.setIndexed(color);\r
+        pr.setColor(ctColor);\r
+    }\r
+    \r
+}\r
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormatting.java
new file mode 100644 (file)
index 0000000..127c037
--- /dev/null
@@ -0,0 +1,101 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.apache.poi.ss.usermodel.ConditionalFormatting;\r
+import org.apache.poi.ss.usermodel.ConditionalFormattingRule;\r
+import org.apache.poi.ss.util.CellRangeAddress;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;\r
+\r
+import java.util.ArrayList;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFConditionalFormatting implements ConditionalFormatting {\r
+    private final CTConditionalFormatting _cf;\r
+    private final XSSFSheet _sh;\r
+\r
+    /*package*/ XSSFConditionalFormatting(XSSFSheet sh){\r
+        _cf = CTConditionalFormatting.Factory.newInstance();\r
+        _sh = sh;\r
+    }\r
+\r
+    /*package*/ XSSFConditionalFormatting(XSSFSheet sh, CTConditionalFormatting cf){\r
+        _cf = cf;\r
+        _sh = sh;\r
+    }\r
+\r
+    /*package*/  CTConditionalFormatting getCTConditionalFormatting(){\r
+        return _cf;\r
+    }\r
+\r
+    /**\r
+      * @return array of <tt>CellRangeAddress</tt>s. Never <code>null</code>\r
+      */\r
+     public CellRangeAddress[] getFormattingRanges(){\r
+         ArrayList<CellRangeAddress> lst = new ArrayList<CellRangeAddress>();\r
+         for (Object stRef : _cf.getSqref()) {\r
+             String[] regions = stRef.toString().split(" ");\r
+             for (int i = 0; i < regions.length; i++) {\r
+                 lst.add(CellRangeAddress.valueOf(regions[i]));\r
+             }\r
+         }\r
+         return lst.toArray(new CellRangeAddress[lst.size()]);\r
+     }\r
+\r
+     /**\r
+      * Replaces an existing Conditional Formatting rule at position idx.\r
+      * Excel allows to create up to 3 Conditional Formatting rules.\r
+      * This method can be useful to modify existing  Conditional Formatting rules.\r
+      *\r
+      * @param idx position of the rule. Should be between 0 and 2.\r
+      * @param cfRule - Conditional Formatting rule\r
+      */\r
+     public void setRule(int idx, ConditionalFormattingRule cfRule){\r
+         XSSFConditionalFormattingRule xRule = (XSSFConditionalFormattingRule)cfRule;\r
+         _cf.getCfRuleArray(idx).set(xRule.getCTCfRule());\r
+     }\r
+\r
+     /**\r
+      * Add a Conditional Formatting rule.\r
+      * Excel allows to create up to 3 Conditional Formatting rules.\r
+      *\r
+      * @param cfRule - Conditional Formatting rule\r
+      */\r
+     public void addRule(ConditionalFormattingRule cfRule){\r
+        XSSFConditionalFormattingRule xRule = (XSSFConditionalFormattingRule)cfRule;\r
+         _cf.addNewCfRule().set(xRule.getCTCfRule());\r
+     }\r
+\r
+     /**\r
+      * @return the Conditional Formatting rule at position idx.\r
+      */\r
+     public XSSFConditionalFormattingRule getRule(int idx){\r
+         return new XSSFConditionalFormattingRule(_sh, _cf.getCfRuleArray(idx));\r
+     }\r
+\r
+     /**\r
+      * @return number of Conditional Formatting rules.\r
+      */\r
+     public int getNumberOfRules(){\r
+         return _cf.sizeOfCfRuleArray();\r
+     }\r
+}\r
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java
new file mode 100644 (file)
index 0000000..e816a84
--- /dev/null
@@ -0,0 +1,226 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.apache.poi.ss.usermodel.*;\r
+import org.apache.poi.xssf.usermodel.XSSFFontFormatting;\r
+import org.apache.poi.xssf.model.StylesTable;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxfs;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxf;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTStylesheet;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFConditionalFormattingRule implements ConditionalFormattingRule {\r
+    private final CTCfRule _cfRule;\r
+    private XSSFSheet _sh;\r
+\r
+    /*package*/ XSSFConditionalFormattingRule(XSSFSheet sh){\r
+        _cfRule = CTCfRule.Factory.newInstance();\r
+        _sh = sh;\r
+    }\r
+\r
+    /*package*/ XSSFConditionalFormattingRule(XSSFSheet sh, CTCfRule cfRule){\r
+        _cfRule = cfRule;\r
+        _sh = sh;\r
+    }\r
+\r
+    /*package*/  CTCfRule getCTCfRule(){\r
+        return _cfRule;\r
+    }\r
+\r
+    /*package*/  CTDxf getDxf(boolean create){\r
+        StylesTable styles = _sh.getWorkbook().getStylesSource();\r
+        CTDxf dxf = null;\r
+        if(styles._getDXfsSize() > 0 && _cfRule.isSetDxfId()){\r
+            int dxfId = (int)_cfRule.getDxfId();\r
+            dxf = styles.getDxfAt(dxfId);\r
+        }\r
+        if(create && dxf == null) {\r
+            dxf = CTDxf.Factory.newInstance();\r
+            int dxfId = styles.putDxf(dxf);\r
+            _cfRule.setDxfId(dxfId - 1);\r
+        }\r
+        return dxf;\r
+    }\r
+\r
+    /**\r
+     * Create a new border formatting structure if it does not exist,\r
+     * otherwise just return existing object.\r
+     *\r
+     * @return - border formatting object, never returns <code>null</code>.\r
+     */\r
+    public XSSFBorderFormatting createBorderFormatting(){\r
+        CTDxf dxf = getDxf(true);\r
+        CTBorder border;\r
+        if(!dxf.isSetBorder()) {\r
+            border = dxf.addNewBorder();\r
+        } else {\r
+            border = dxf.getBorder();\r
+        }\r
+\r
+        return new XSSFBorderFormatting(border);\r
+    }\r
+\r
+    /**\r
+     * @return - border formatting object  if defined,  <code>null</code> otherwise\r
+     */\r
+    public XSSFBorderFormatting getBorderFormatting(){\r
+        CTDxf dxf = getDxf(false);\r
+        if(dxf == null || !dxf.isSetBorder()) return null;\r
+\r
+        return new XSSFBorderFormatting(dxf.getBorder());\r
+     }\r
+\r
+    /**\r
+     * Create a new font formatting structure if it does not exist,\r
+     * otherwise just return existing object.\r
+     *\r
+     * @return - font formatting object, never returns <code>null</code>.\r
+     */\r
+    public XSSFFontFormatting createFontFormatting(){\r
+        CTDxf dxf = getDxf(true);\r
+        CTFont font;\r
+        if(!dxf.isSetFont()) {\r
+            font = dxf.addNewFont();\r
+        } else {\r
+            font = dxf.getFont();\r
+        }\r
+\r
+        return new XSSFFontFormatting(font);\r
+    }\r
+\r
+    /**\r
+     * @return - font formatting object  if defined,  <code>null</code> otherwise\r
+     */\r
+    public XSSFFontFormatting getFontFormatting(){\r
+        CTDxf dxf = getDxf(false);\r
+        if(dxf == null || !dxf.isSetFont()) return null;\r
+\r
+        return new XSSFFontFormatting(dxf.getFont());\r
+    }\r
+\r
+    /**\r
+     * Create a new pattern formatting structure if it does not exist,\r
+     * otherwise just return existing object.\r
+     *\r
+     * @return - pattern formatting object, never returns <code>null</code>.\r
+     */\r
+    public XSSFPatternFormatting createPatternFormatting(){\r
+        CTDxf dxf = getDxf(true);\r
+        CTFill fill;\r
+        if(!dxf.isSetFill()) {\r
+            fill = dxf.addNewFill();\r
+        } else {\r
+            fill = dxf.getFill();\r
+        }\r
+\r
+        return new XSSFPatternFormatting(fill);\r
+    }\r
+\r
+    /**\r
+     * @return - pattern formatting object  if defined,  <code>null</code> otherwise\r
+     */\r
+    public XSSFPatternFormatting getPatternFormatting(){\r
+        CTDxf dxf = getDxf(false);\r
+        if(dxf == null || !dxf.isSetFill()) return null;\r
+\r
+        return new XSSFPatternFormatting(dxf.getFill());\r
+    }\r
+\r
+    /**\r
+     * Type of conditional formatting rule.\r
+     * <p>\r
+     * MUST be either {@link ConditionalFormattingRule#CONDITION_TYPE_CELL_VALUE_IS}\r
+     * or  {@link ConditionalFormattingRule#CONDITION_TYPE_FORMULA}\r
+     * </p>\r
+     *\r
+     * @return the type of condition\r
+     */\r
+    public byte getConditionType(){\r
+        switch (_cfRule.getType().intValue()){\r
+            case STCfType.INT_EXPRESSION: return ConditionalFormattingRule.CONDITION_TYPE_FORMULA;\r
+            case STCfType.INT_CELL_IS: return ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS;\r
+        }\r
+        return 0;\r
+    }\r
+\r
+    /**\r
+     * The comparison function used when the type of conditional formatting is set to\r
+     * {@link ConditionalFormattingRule#CONDITION_TYPE_CELL_VALUE_IS}\r
+     * <p>\r
+     *     MUST be a constant from {@link org.apache.poi.ss.usermodel.ComparisonOperator}\r
+     * </p>\r
+     *\r
+     * @return the conditional format operator\r
+     */\r
+    public byte getComparisonOperation(){\r
+        STConditionalFormattingOperator.Enum op = _cfRule.getOperator();\r
+        if(op == null) return ComparisonOperator.NO_COMPARISON;\r
+        \r
+        switch(op.intValue()){\r
+            case STConditionalFormattingOperator.INT_LESS_THAN: return ComparisonOperator.LT;\r
+            case STConditionalFormattingOperator.INT_LESS_THAN_OR_EQUAL: return ComparisonOperator.LE;\r
+            case STConditionalFormattingOperator.INT_GREATER_THAN: return ComparisonOperator.GT;\r
+            case STConditionalFormattingOperator.INT_GREATER_THAN_OR_EQUAL: return ComparisonOperator.GE;\r
+            case STConditionalFormattingOperator.INT_EQUAL: return ComparisonOperator.EQUAL;\r
+            case STConditionalFormattingOperator.INT_NOT_EQUAL: return ComparisonOperator.NOT_EQUAL;\r
+            case STConditionalFormattingOperator.INT_BETWEEN: return ComparisonOperator.BETWEEN;\r
+            case STConditionalFormattingOperator.INT_NOT_BETWEEN: return ComparisonOperator.NOT_BETWEEN;\r
+        }\r
+        return ComparisonOperator.NO_COMPARISON;\r
+    }\r
+\r
+    /**\r
+     * The formula used to evaluate the first operand for the conditional formatting rule.\r
+     * <p>\r
+     * If the condition type is {@link ConditionalFormattingRule#CONDITION_TYPE_CELL_VALUE_IS},\r
+     * this field is the first operand of the comparison.\r
+     * If type is {@link ConditionalFormattingRule#CONDITION_TYPE_FORMULA}, this formula is used\r
+     * to determine if the conditional formatting is applied.\r
+     * </p>\r
+     * <p>\r
+     * If comparison type is {@link ConditionalFormattingRule#CONDITION_TYPE_FORMULA} the formula MUST be a Boolean function\r
+     * </p>\r
+     *\r
+     * @return  the first formula\r
+     */\r
+    public String getFormula1(){\r
+        return _cfRule.sizeOfFormulaArray() > 0 ? _cfRule.getFormulaArray(0) : null;\r
+    }\r
+\r
+    /**\r
+     * The formula used to evaluate the second operand of the comparison when\r
+     * comparison type is  {@link ConditionalFormattingRule#CONDITION_TYPE_CELL_VALUE_IS} and operator\r
+     * is either {@link org.apache.poi.ss.usermodel.ComparisonOperator#BETWEEN} or {@link org.apache.poi.ss.usermodel.ComparisonOperator#NOT_BETWEEN}\r
+     *\r
+     * @return  the second formula\r
+     */\r
+    public String getFormula2(){\r
+        return _cfRule.sizeOfFormulaArray() == 2 ? _cfRule.getFormulaArray(1) : null;\r
+    }\r
+}\r
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java
new file mode 100644 (file)
index 0000000..4c9cb54
--- /dev/null
@@ -0,0 +1,212 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.apache.poi.ss.usermodel.*;\r
+import org.apache.poi.hssf.util.HSSFColor;\r
+import org.apache.poi.POIXMLException;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTUnderlineProperty;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontSize;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTVerticalAlignFontProperty;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STVerticalAlignRun;\r
+\r
+import java.util.Map;\r
+import java.util.Iterator;\r
+import java.awt.*;\r
+import java.awt.Font;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFFontFormatting implements FontFormatting {\r
+    CTFont _font;\r
+\r
+    /*package*/ XSSFFontFormatting(CTFont font){\r
+        _font = font;\r
+    }\r
+\r
+    /**\r
+     * get the type of super or subscript for the font\r
+     *\r
+     * @return super or subscript option\r
+     * @see #SS_NONE\r
+     * @see #SS_SUPER\r
+     * @see #SS_SUB\r
+     */\r
+    public short getEscapementType(){\r
+        if(_font.sizeOfVertAlignArray() == 0) return SS_NONE;\r
+\r
+        CTVerticalAlignFontProperty prop = _font.getVertAlignArray(0);\r
+        return (short)(prop.getVal().intValue() - 1);\r
+   }\r
+\r
+    /**\r
+     * set the escapement type for the font\r
+     *\r
+     * @param escapementType  super or subscript option\r
+     * @see #SS_NONE\r
+     * @see #SS_SUPER\r
+     * @see #SS_SUB\r
+     */\r
+    public void setEscapementType(short escapementType){\r
+        _font.setVertAlignArray(null);\r
+        if(escapementType != SS_NONE){\r
+            _font.addNewVertAlign().setVal(STVerticalAlignRun.Enum.forInt(escapementType + 1));\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @return font color index\r
+     */\r
+    public short getFontColorIndex(){\r
+        if(_font.sizeOfColorArray() == 0) return -1;\r
+\r
+        int idx = 0;\r
+        CTColor color = _font.getColorArray(0);\r
+        if(color.isSetIndexed()) idx = (int)color.getIndexed();\r
+        return (short)idx;\r
+    }\r
+\r
+\r
+    /**\r
+     * @param color font color index\r
+     */\r
+    public void setFontColorIndex(short color){\r
+        _font.setColorArray(null);\r
+        if(color != -1){\r
+            _font.addNewColor().setIndexed(color);\r
+        }\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @return xssf color wrapper or null if color info is missing\r
+     */\r
+    public XSSFColor getXSSFColor(){\r
+        if(_font.sizeOfColorArray() == 0) return null;\r
+\r
+        return new XSSFColor(_font.getColorArray(0));\r
+    }\r
+\r
+    /**\r
+     * gets the height of the font in 1/20th point units\r
+     *\r
+     * @return fontheight (in points/20); or -1 if not modified\r
+     */\r
+    public int getFontHeight(){\r
+        if(_font.sizeOfSzArray() == 0) return -1;\r
+\r
+        CTFontSize sz = _font.getSzArray(0);\r
+        return (short)(20*sz.getVal());\r
+    }\r
+\r
+    /**\r
+     * Sets the height of the font in 1/20th point units\r
+     *\r
+     * @param height the height in twips (in points/20)\r
+     */\r
+    public void setFontHeight(int height){\r
+        _font.setSzArray(null);\r
+        if(height != -1){\r
+            _font.addNewSz().setVal((double)height / 20);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * get the type of underlining for the font\r
+     *\r
+     * @return font underlining type\r
+     *\r
+     * @see #U_NONE\r
+     * @see #U_SINGLE\r
+     * @see #U_DOUBLE\r
+     * @see #U_SINGLE_ACCOUNTING\r
+     * @see #U_DOUBLE_ACCOUNTING\r
+     */\r
+    public short getUnderlineType(){\r
+        if(_font.sizeOfUArray() == 0) return U_NONE;\r
+        CTUnderlineProperty u = _font.getUArray(0);\r
+        switch(u.getVal().intValue()){\r
+            case STUnderlineValues.INT_SINGLE: return U_SINGLE;\r
+            case STUnderlineValues.INT_DOUBLE: return U_DOUBLE;\r
+            case STUnderlineValues.INT_SINGLE_ACCOUNTING: return U_SINGLE_ACCOUNTING;\r
+            case STUnderlineValues.INT_DOUBLE_ACCOUNTING: return U_DOUBLE_ACCOUNTING;\r
+            default: return U_NONE;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * set the type of underlining type for the font\r
+     *\r
+     * @param underlineType  super or subscript option\r
+     *\r
+     * @see #U_NONE\r
+     * @see #U_SINGLE\r
+     * @see #U_DOUBLE\r
+     * @see #U_SINGLE_ACCOUNTING\r
+     * @see #U_DOUBLE_ACCOUNTING\r
+     */\r
+    public void setUnderlineType(short underlineType){\r
+        _font.setUArray(null);\r
+        if(underlineType != U_NONE){\r
+            FontUnderline fenum = FontUnderline.valueOf(underlineType);\r
+            STUnderlineValues.Enum val = STUnderlineValues.Enum.forInt(fenum.getValue());\r
+            _font.addNewU().setVal(val);\r
+        }\r
+     }\r
+\r
+    /**\r
+     * get whether the font weight is set to bold or not\r
+     *\r
+     * @return bold - whether the font is bold or not\r
+     */\r
+    public boolean isBold(){\r
+        return _font.sizeOfBArray() == 1 && _font.getBArray(0).getVal();\r
+    }\r
+\r
+    /**\r
+     * @return true if font style was set to <i>italic</i>\r
+     */\r
+    public boolean isItalic(){\r
+        return _font.sizeOfIArray() == 1 && _font.getIArray(0).getVal();\r
+    }\r
+\r
+    /**\r
+     * set font style options.\r
+     *\r
+     * @param italic - if true, set posture style to italic, otherwise to normal\r
+     * @param bold if true, set font weight to bold, otherwise to normal\r
+     */\r
+    public void setFontStyle(boolean italic, boolean bold){\r
+        _font.setIArray(null);\r
+        _font.setBArray(null);\r
+        if(italic) _font.addNewI().setVal(true);\r
+        if(bold) _font.addNewB().setVal(true);\r
+    }\r
+\r
+    /**\r
+     * set font style options to default values (non-italic, non-bold)\r
+     */\r
+    public void resetFontStyle(){\r
+        _font.set(CTFont.Factory.newInstance());\r
+    }\r
+}\r
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java
new file mode 100644 (file)
index 0000000..f3d1329
--- /dev/null
@@ -0,0 +1,75 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.apache.poi.ss.usermodel.PatternFormatting;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFPatternFormatting implements PatternFormatting {\r
+    CTFill _fill;\r
+\r
+    XSSFPatternFormatting(CTFill fill){\r
+        _fill = fill;\r
+    }\r
+\r
+    public short getFillBackgroundColor(){\r
+        if(!_fill.isSetPatternFill()) return 0;\r
+\r
+        return (short)_fill.getPatternFill().getBgColor().getIndexed();\r
+    }\r
+\r
+    public short getFillForegroundColor(){\r
+        if(!_fill.isSetPatternFill() || ! _fill.getPatternFill().isSetFgColor())\r
+            return 0;\r
+\r
+        return (short)_fill.getPatternFill().getFgColor().getIndexed();\r
+    }\r
+\r
+    public short getFillPattern(){\r
+        if(!_fill.isSetPatternFill() || !_fill.getPatternFill().isSetPatternType()) return NO_FILL;\r
+\r
+        return (short)(_fill.getPatternFill().getPatternType().intValue() - 1);\r
+     }\r
+\r
+    public void setFillBackgroundColor(short bg){\r
+        CTPatternFill ptrn = _fill.isSetPatternFill() ? _fill.getPatternFill() : _fill.addNewPatternFill();\r
+        CTColor bgColor = CTColor.Factory.newInstance();\r
+        bgColor.setIndexed(bg);\r
+        ptrn.setBgColor(bgColor);\r
+    }\r
+\r
+    public void setFillForegroundColor(short fg){\r
+        CTPatternFill ptrn = _fill.isSetPatternFill() ? _fill.getPatternFill() : _fill.addNewPatternFill();\r
+        CTColor fgColor = CTColor.Factory.newInstance();\r
+        fgColor.setIndexed(fg);\r
+        ptrn.setFgColor(fgColor);\r
+    }\r
+\r
+    public void setFillPattern(short fp){\r
+        CTPatternFill ptrn = _fill.isSetPatternFill() ? _fill.getPatternFill() : _fill.addNewPatternFill();\r
+        if(fp == NO_FILL) ptrn.unsetPatternType();\r
+        else ptrn.setPatternType(STPatternType.Enum.forInt(fp + 1));\r
+    }\r
+}\r
index 281f773495601b0128baa4d16cc9f41ac80facf8..f1c573ebb8fd95aff00f1dac4fbd82b538b6b507 100644 (file)
@@ -49,7 +49,7 @@ import org.apache.poi.ss.usermodel.Footer;
 import org.apache.poi.ss.usermodel.Header;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.util.CellRangeAddress;
+simport org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellRangeAddressList;
 import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.ss.util.SSCellRange;
@@ -2391,6 +2391,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         rowShifter.updateNamedRanges(shifter);
         rowShifter.updateFormulas(shifter);
         rowShifter.shiftMerged(startRow, endRow, n);
+        rowShifter.updateConditionalFormatting(shifter);
 
         //rebuild the _rows map
         TreeMap<Integer, XSSFRow> map = new TreeMap<Integer, XSSFRow>();
@@ -3209,4 +3210,8 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
        );
        return tableList;
     }
+
+    public XSSFSheetConditionalFormatting getSheetConditionalFormatting(){
+        return new XSSFSheetConditionalFormatting(this);
+    }
 }
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
new file mode 100644 (file)
index 0000000..3a0e71d
--- /dev/null
@@ -0,0 +1,236 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.apache.poi.ss.usermodel.ConditionalFormatting;\r
+import org.apache.poi.ss.usermodel.ConditionalFormattingRule;\r
+import org.apache.poi.ss.usermodel.SheetConditionalFormatting;\r
+import org.apache.poi.ss.usermodel.ComparisonOperator;\r
+import org.apache.poi.ss.util.CellRangeAddress;\r
+import org.apache.poi.ss.SpreadsheetVersion;\r
+import org.apache.poi.hssf.record.cf.CellRangeUtil;\r
+import org.apache.xmlbeans.XmlObject;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;\r
+\r
+import java.util.List;\r
+import java.util.Arrays;\r
+import java.util.ArrayList;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFSheetConditionalFormatting implements SheetConditionalFormatting {\r
+    private final XSSFSheet _sheet;\r
+\r
+    /* package */ XSSFSheetConditionalFormatting(XSSFSheet sheet) {\r
+        _sheet = sheet;\r
+    }\r
+\r
+    /**\r
+     * A factory method allowing to create a conditional formatting rule\r
+     * with a cell comparison operator<p/>\r
+     * TODO - formulas containing cell references are currently not parsed properly\r
+     *\r
+     * @param comparisonOperation - a constant value from\r
+     *          <tt>{@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator}</tt>: <p>\r
+     * <ul>\r
+     *          <li>BETWEEN</li>\r
+     *          <li>NOT_BETWEEN</li>\r
+     *          <li>EQUAL</li>\r
+     *          <li>NOT_EQUAL</li>\r
+     *          <li>GT</li>\r
+     *          <li>LT</li>\r
+     *          <li>GE</li>\r
+     *          <li>LE</li>\r
+     * </ul>\r
+     * </p>\r
+     * @param formula1 - formula for the valued, compared with the cell\r
+     * @param formula2 - second formula (only used with\r
+     * {@link org.apache.poi.ss.usermodel.ComparisonOperator#BETWEEN}) and\r
+     * {@link org.apache.poi.ss.usermodel.ComparisonOperator#NOT_BETWEEN} operations)\r
+     */\r
+    public XSSFConditionalFormattingRule createConditionalFormattingRule(\r
+            byte comparisonOperation,\r
+            String formula1,\r
+            String formula2) {\r
+\r
+        XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet);\r
+        CTCfRule cfRule = rule.getCTCfRule();\r
+        cfRule.addFormula(formula1);\r
+        if(formula2 != null) cfRule.addFormula(formula2);\r
+        cfRule.setType(STCfType.CELL_IS);\r
+        STConditionalFormattingOperator.Enum operator;\r
+        switch (comparisonOperation){\r
+            case ComparisonOperator.BETWEEN: operator = STConditionalFormattingOperator.BETWEEN; break;\r
+            case ComparisonOperator.NOT_BETWEEN: operator = STConditionalFormattingOperator.NOT_BETWEEN; break;\r
+            case ComparisonOperator.LT: operator = STConditionalFormattingOperator.LESS_THAN; break;\r
+            case ComparisonOperator.LE: operator = STConditionalFormattingOperator.LESS_THAN_OR_EQUAL; break;\r
+            case ComparisonOperator.GT: operator = STConditionalFormattingOperator.GREATER_THAN; break;\r
+            case ComparisonOperator.GE: operator = STConditionalFormattingOperator.GREATER_THAN_OR_EQUAL; break;\r
+            case ComparisonOperator.EQUAL: operator = STConditionalFormattingOperator.EQUAL; break;\r
+            case ComparisonOperator.NOT_EQUAL: operator = STConditionalFormattingOperator.NOT_EQUAL; break;\r
+            default: throw new IllegalArgumentException("Unknown comparison operator: " + comparisonOperation);\r
+        }\r
+        cfRule.setOperator(operator);\r
+\r
+        return rule;\r
+    }\r
+\r
+    public XSSFConditionalFormattingRule createConditionalFormattingRule(\r
+            byte comparisonOperation,\r
+            String formula) {\r
+\r
+        return createConditionalFormattingRule(comparisonOperation, formula, null);\r
+    }\r
+\r
+    /**\r
+     * A factory method allowing to create a conditional formatting rule with a formula.<br>\r
+     *\r
+     * @param formula - formula for the valued, compared with the cell\r
+     */\r
+    public XSSFConditionalFormattingRule createConditionalFormattingRule(String formula) {\r
+        XSSFConditionalFormattingRule rule = new XSSFConditionalFormattingRule(_sheet);\r
+        CTCfRule cfRule = rule.getCTCfRule();\r
+        cfRule.addFormula(formula);\r
+        cfRule.setType(STCfType.EXPRESSION);\r
+        return rule;\r
+    }\r
+\r
+    public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) {\r
+        if (regions == null) {\r
+            throw new IllegalArgumentException("regions must not be null");\r
+        }\r
+        for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL2007);\r
+\r
+        if (cfRules == null) {\r
+            throw new IllegalArgumentException("cfRules must not be null");\r
+        }\r
+        if (cfRules.length == 0) {\r
+            throw new IllegalArgumentException("cfRules must not be empty");\r
+        }\r
+        if (cfRules.length > 3) {\r
+            throw new IllegalArgumentException("Number of rules must not exceed 3");\r
+        }\r
+        XSSFConditionalFormattingRule[] hfRules;\r
+        if(cfRules instanceof XSSFConditionalFormattingRule[]) hfRules = (XSSFConditionalFormattingRule[])cfRules;\r
+        else {\r
+            hfRules = new XSSFConditionalFormattingRule[cfRules.length];\r
+            System.arraycopy(cfRules, 0, hfRules, 0, hfRules.length);\r
+        }\r
+        CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(regions);\r
+        CTConditionalFormatting cf = _sheet.getCTWorksheet().addNewConditionalFormatting();\r
+        List<String> refs = new ArrayList<String>();\r
+        for(CellRangeAddress a : mergeCellRanges) refs.add(a.formatAsString());\r
+        cf.setSqref(refs);\r
+\r
+\r
+        int priority = 1;\r
+        for(CTConditionalFormatting c : _sheet.getCTWorksheet().getConditionalFormattingList()){\r
+            priority += c.sizeOfCfRuleArray();\r
+        }\r
+\r
+        for(ConditionalFormattingRule rule : cfRules){\r
+            XSSFConditionalFormattingRule xRule = (XSSFConditionalFormattingRule)rule;\r
+            xRule.getCTCfRule().setPriority(priority++);\r
+            cf.addNewCfRule().set(xRule.getCTCfRule());\r
+        }\r
+        return _sheet.getCTWorksheet().sizeOfConditionalFormattingArray() - 1;\r
+    }\r
+\r
+    public int addConditionalFormatting(CellRangeAddress[] regions,\r
+            ConditionalFormattingRule rule1)\r
+    {\r
+        return addConditionalFormatting(regions,\r
+                rule1 == null ? null : new XSSFConditionalFormattingRule[] {\r
+                (XSSFConditionalFormattingRule)rule1\r
+        });\r
+    }\r
+\r
+    public int addConditionalFormatting(CellRangeAddress[] regions,\r
+            ConditionalFormattingRule rule1, ConditionalFormattingRule rule2)\r
+    {\r
+        return addConditionalFormatting(regions,\r
+                rule1 == null ? null : new XSSFConditionalFormattingRule[] {\r
+                    (XSSFConditionalFormattingRule)rule1,\r
+                    (XSSFConditionalFormattingRule)rule2\r
+            });\r
+    }\r
+\r
+    /**\r
+     * Adds a copy of HSSFConditionalFormatting object to the sheet\r
+     * <p>This method could be used to copy HSSFConditionalFormatting object\r
+     * from one sheet to another. For example:\r
+     * <pre>\r
+     * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);\r
+     * newSheet.addConditionalFormatting(cf);\r
+     * </pre>\r
+     *\r
+     * @param cf HSSFConditionalFormatting object\r
+     * @return index of the new Conditional Formatting object\r
+     */\r
+    public int addConditionalFormatting( ConditionalFormatting cf ) {\r
+        XSSFConditionalFormatting xcf = (XSSFConditionalFormatting)cf;\r
+        CTWorksheet sh = _sheet.getCTWorksheet();\r
+        sh.addNewConditionalFormatting().set(xcf.getCTConditionalFormatting().copy());\r
+        return sh.sizeOfConditionalFormattingArray() - 1;\r
+    }\r
+\r
+    /**\r
+    * gets Conditional Formatting object at a particular index\r
+    *\r
+    * @param index\r
+    *                  of the Conditional Formatting object to fetch\r
+    * @return Conditional Formatting object\r
+    */\r
+    public XSSFConditionalFormatting getConditionalFormattingAt(int index) {\r
+        checkIndex(index);\r
+        CTConditionalFormatting cf = _sheet.getCTWorksheet().getConditionalFormattingArray(index);\r
+        return new XSSFConditionalFormatting(_sheet, cf);\r
+    }\r
+\r
+    /**\r
+    * @return number of Conditional Formatting objects of the sheet\r
+    */\r
+    public int getNumConditionalFormattings() {\r
+        return _sheet.getCTWorksheet().sizeOfConditionalFormattingArray();\r
+    }\r
+\r
+    /**\r
+    * removes a Conditional Formatting object by index\r
+    * @param index of a Conditional Formatting object to remove\r
+    */\r
+    public void removeConditionalFormatting(int index) {\r
+        checkIndex(index);\r
+        _sheet.getCTWorksheet().getConditionalFormattingList().remove(index);\r
+    }\r
+\r
+    private void checkIndex(int index) {\r
+        int cnt = getNumConditionalFormattings();\r
+        if (index < 0 || index >= cnt) {\r
+            throw new IllegalArgumentException("Specified CF index " + index\r
+                    + " is outside the allowable range (0.." + (cnt - 1) + ")");\r
+        }\r
+    }\r
+\r
+}\r
index 166dcc369cb4c8a24eb45a41b2ac1e458e86195a..40de77bcd40e929eac586fbdb9969b1217db5226 100644 (file)
@@ -26,8 +26,12 @@ import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.formula.FormulaShifter;
 import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.AreaPtg;
+import org.apache.poi.ss.formula.ptg.AreaErrPtg;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;
 
 import java.util.List;
 import java.util.ArrayList;
@@ -187,4 +191,81 @@ public final class XSSFRowShifter {
         return shiftedFmla;
     }
 
+    public void updateConditionalFormatting(FormulaShifter shifter) {
+        XSSFWorkbook wb = sheet.getWorkbook();
+        int sheetIndex = wb.getSheetIndex(sheet);
+
+
+        XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
+        List<CTConditionalFormatting> cfList = sheet.getCTWorksheet().getConditionalFormattingList();
+        for(int j = 0; j< cfList.size(); j++){
+            CTConditionalFormatting cf = cfList.get(j);
+
+            ArrayList<CellRangeAddress> cellRanges = new ArrayList<CellRangeAddress>();
+            for (Object stRef : cf.getSqref()) {
+                String[] regions = stRef.toString().split(" ");
+                for (int i = 0; i < regions.length; i++) {
+                    cellRanges.add(CellRangeAddress.valueOf(regions[i]));
+                }
+            }
+
+            boolean changed = false;
+            List<CellRangeAddress> temp = new ArrayList<CellRangeAddress>();
+            for (int i = 0; i < cellRanges.size(); i++) {
+                CellRangeAddress craOld = cellRanges.get(i);
+                CellRangeAddress craNew = shiftRange(shifter, craOld, sheetIndex);
+                if (craNew == null) {
+                    changed = true;
+                    continue;
+                }
+                temp.add(craNew);
+                if (craNew != craOld) {
+                    changed = true;
+                }
+            }
+
+            if (changed) {
+                int nRanges = temp.size();
+                if (nRanges == 0) {
+                    cfList.remove(j);
+                    continue;
+                }
+                List<String> refs = new ArrayList<String>();
+                for(CellRangeAddress a : temp) refs.add(a.formatAsString());
+                cf.setSqref(refs);
+            }
+
+            for(CTCfRule cfRule : cf.getCfRuleList()){
+                List<String> formulas = cfRule.getFormulaList();
+                for (int i = 0; i < formulas.size(); i++) {
+                    String formula = formulas.get(i);
+                    Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex);
+                    if (shifter.adjustFormula(ptgs, sheetIndex)) {
+                        String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
+                        formulas.set(i, shiftedFmla);
+                    }
+                }
+            }
+        }
+    }
+
+    private static CellRangeAddress shiftRange(FormulaShifter shifter, CellRangeAddress cra, int currentExternSheetIx) {
+        // FormulaShifter works well in terms of Ptgs - so convert CellRangeAddress to AreaPtg (and back) here
+        AreaPtg aptg = new AreaPtg(cra.getFirstRow(), cra.getLastRow(), cra.getFirstColumn(), cra.getLastColumn(), false, false, false, false);
+        Ptg[] ptgs = { aptg, };
+
+        if (!shifter.adjustFormula(ptgs, currentExternSheetIx)) {
+            return cra;
+        }
+        Ptg ptg0 = ptgs[0];
+        if (ptg0 instanceof AreaPtg) {
+            AreaPtg bptg = (AreaPtg) ptg0;
+            return new CellRangeAddress(bptg.getFirstRow(), bptg.getLastRow(), bptg.getFirstColumn(), bptg.getLastColumn());
+        }
+        if (ptg0 instanceof AreaErrPtg) {
+            return null;
+        }
+        throw new IllegalStateException("Unexpected shifted ptg class (" + ptg0.getClass().getName() + ")");
+    }
+
 }
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFConditionalFormatting.java
new file mode 100644 (file)
index 0000000..325c534
--- /dev/null
@@ -0,0 +1,35 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.apache.poi.ss.usermodel.BaseTestConditionalFormatting;\r
+import org.apache.poi.xssf.XSSFITestDataProvider;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestXSSFConditionalFormatting extends BaseTestConditionalFormatting {\r
+    public TestXSSFConditionalFormatting(){\r
+        super(XSSFITestDataProvider.instance);\r
+    }\r
+\r
+    public void testRead(){\r
+        testRead("WithConditionalFormatting.xlsx");\r
+    }\r
+}\r
index f4fa306cc212828993511bc082589e7233ff1769..54951997701433683209e753af0cf44dca953944 100644 (file)
@@ -20,171 +20,22 @@ package org.apache.poi.hssf.usermodel;
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
+import org.apache.poi.hssf.HSSFITestDataProvider;
 import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
 import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.BaseTestConditionalFormatting;
 import org.apache.poi.ss.util.CellRangeAddress;
 
 /**
  *
  * @author Dmitriy Kumshayev
  */
-public final class TestHSSFConditionalFormatting extends TestCase {
-       public void testCreateCF() {
-               HSSFWorkbook workbook = new HSSFWorkbook();
-               HSSFSheet sheet = workbook.createSheet();
-               String formula = "7";
-
-               HSSFSheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
-
-               HSSFConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(formula);
-               HSSFFontFormatting fontFmt = rule1.createFontFormatting();
-               fontFmt.setFontStyle(true, false);
-
-               HSSFBorderFormatting bordFmt = rule1.createBorderFormatting();
-               bordFmt.setBorderBottom(HSSFBorderFormatting.BORDER_THIN);
-               bordFmt.setBorderTop(HSSFBorderFormatting.BORDER_THICK);
-               bordFmt.setBorderLeft(HSSFBorderFormatting.BORDER_DASHED);
-               bordFmt.setBorderRight(HSSFBorderFormatting.BORDER_DOTTED);
-
-               HSSFPatternFormatting patternFmt = rule1.createPatternFormatting();
-               patternFmt.setFillBackgroundColor(HSSFColor.YELLOW.index);
-
-
-               HSSFConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2");
-               HSSFConditionalFormattingRule [] cfRules =
-               {
-                       rule1, rule2
-               };
-
-               short col = 1;
-               CellRangeAddress [] regions = {
-                       new CellRangeAddress(0, 65535, col, col)
-               };
-
-               sheetCF.addConditionalFormatting(regions, cfRules);
-               sheetCF.addConditionalFormatting(regions, cfRules);
-
-               // Verification
-               assertEquals(2, sheetCF.getNumConditionalFormattings());
-               sheetCF.removeConditionalFormatting(1);
-               assertEquals(1, sheetCF.getNumConditionalFormattings());
-               HSSFConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);
-               assertNotNull(cf);
-
-               regions = cf.getFormattingRanges();
-               assertNotNull(regions);
-               assertEquals(1, regions.length);
-               CellRangeAddress r = regions[0];
-               assertEquals(1, r.getFirstColumn());
-               assertEquals(1, r.getLastColumn());
-               assertEquals(0, r.getFirstRow());
-               assertEquals(65535, r.getLastRow());
-
-               assertEquals(2, cf.getNumberOfRules());
-
-               rule1 = cf.getRule(0);
-               assertEquals("7",rule1.getFormula1());
-               assertNull(rule1.getFormula2());
-
-               HSSFFontFormatting    r1fp = rule1.getFontFormatting();
-               assertNotNull(r1fp);
-
-               assertTrue(r1fp.isItalic());
-               assertFalse(r1fp.isBold());
-
-               HSSFBorderFormatting  r1bf = rule1.getBorderFormatting();
-               assertNotNull(r1bf);
-               assertEquals(HSSFBorderFormatting.BORDER_THIN, r1bf.getBorderBottom());
-               assertEquals(HSSFBorderFormatting.BORDER_THICK,r1bf.getBorderTop());
-               assertEquals(HSSFBorderFormatting.BORDER_DASHED,r1bf.getBorderLeft());
-               assertEquals(HSSFBorderFormatting.BORDER_DOTTED,r1bf.getBorderRight());
-
-               HSSFPatternFormatting r1pf = rule1.getPatternFormatting();
-               assertNotNull(r1pf);
-               assertEquals(HSSFColor.YELLOW.index,r1pf.getFillBackgroundColor());
-
-               rule2 = cf.getRule(1);
-               assertEquals("2",rule2.getFormula2());
-               assertEquals("1",rule2.getFormula1());
-       }
-
-       public void testClone() {
-
-               HSSFWorkbook wb = new HSSFWorkbook();
-               HSSFSheet sheet = wb.createSheet();
-               String formula = "7";
-
-               HSSFSheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
-
-               HSSFConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(formula);
-               HSSFFontFormatting fontFmt = rule1.createFontFormatting();
-               fontFmt.setFontStyle(true, false);
-
-               HSSFPatternFormatting patternFmt = rule1.createPatternFormatting();
-               patternFmt.setFillBackgroundColor(HSSFColor.YELLOW.index);
-
-
-               HSSFConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2");
-               HSSFConditionalFormattingRule [] cfRules =
-               {
-                       rule1, rule2
-               };
-
-               short col = 1;
-               CellRangeAddress [] regions = {
-                       new CellRangeAddress(0, 65535, col, col)
-               };
-
-               sheetCF.addConditionalFormatting(regions, cfRules);
-
-               try {
-                       wb.cloneSheet(0);
-               } catch (RuntimeException e) {
-                       if (e.getMessage().indexOf("needs to define a clone method") > 0) {
-                               throw new AssertionFailedError("Indentified bug 45682");
-                       }
-                       throw e;
-               }
-               assertEquals(2, wb.getNumberOfSheets());
-       }
-
-       public void testShiftRows() {
-
-               HSSFWorkbook wb = new HSSFWorkbook();
-               HSSFSheet sheet = wb.createSheet();
-
-               HSSFSheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
-
-               HSSFConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(
-                               ComparisonOperator.BETWEEN, "sum(A10:A15)", "1+sum(B16:B30)");
-               HSSFFontFormatting fontFmt = rule1.createFontFormatting();
-               fontFmt.setFontStyle(true, false);
-
-               HSSFPatternFormatting patternFmt = rule1.createPatternFormatting();
-               patternFmt.setFillBackgroundColor(HSSFColor.YELLOW.index);
-               HSSFConditionalFormattingRule [] cfRules = { rule1, };
-
-               CellRangeAddress [] regions = {
-                       new CellRangeAddress(2, 4, 0, 0), // A3:A5
-               };
-               sheetCF.addConditionalFormatting(regions, cfRules);
-
-               // This row-shift should destroy the CF region
-               sheet.shiftRows(10, 20, -9);
-               assertEquals(0, sheetCF.getNumConditionalFormattings());
-
-               // re-add the CF
-               sheetCF.addConditionalFormatting(regions, cfRules);
-
-               // This row shift should only affect the formulas
-               sheet.shiftRows(14, 17, 8);
-               HSSFConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);
-               assertEquals("SUM(A10:A23)", cf.getRule(0).getFormula1());
-               assertEquals("1+SUM(B24:B30)", cf.getRule(0).getFormula2());
-
-               sheet.shiftRows(0, 8, 21);
-               cf = sheetCF.getConditionalFormattingAt(0);
-               assertEquals("SUM(A10:A21)", cf.getRule(0).getFormula1());
-               assertEquals("1+SUM(#REF!)", cf.getRule(0).getFormula2());
-       }
+public final class TestHSSFConditionalFormatting extends BaseTestConditionalFormatting {
+    public TestHSSFConditionalFormatting(){
+        super(HSSFITestDataProvider.instance);
+    }
+
+    public void testRead(){
+        testRead("WithConditionalFormatting.xls");
+    }
 }
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java
new file mode 100644 (file)
index 0000000..7ddb3f0
--- /dev/null
@@ -0,0 +1,692 @@
+/*\r
+ *  ====================================================================\r
+ *    Licensed to the Apache Software Foundation (ASF) under one or more\r
+ *    contributor license agreements.  See the NOTICE file distributed with\r
+ *    this work for additional information regarding copyright ownership.\r
+ *    The ASF licenses this file to You under the Apache License, Version 2.0\r
+ *    (the "License"); you may not use this file except in compliance with\r
+ *    the License.  You may obtain a copy of the License at\r
+ *\r
+ *        http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *    Unless required by applicable law or agreed to in writing, software\r
+ *    distributed under the License is distributed on an "AS IS" BASIS,\r
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *    See the License for the specific language governing permissions and\r
+ *    limitations under the License.\r
+ * ====================================================================\r
+ */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+import junit.framework.TestCase;\r
+import org.apache.poi.ss.ITestDataProvider;\r
+import org.apache.poi.ss.usermodel.*;\r
+import org.apache.poi.ss.util.CellRangeAddress;\r
+\r
+/**\r
+ * @author Dmitriy Kumshayev\r
+ * @author Yegor Kozlov\r
+ */\r
+public abstract class BaseTestConditionalFormatting extends TestCase {\r
+    private final ITestDataProvider _testDataProvider;\r
+\r
+    public BaseTestConditionalFormatting(ITestDataProvider testDataProvider){\r
+        _testDataProvider = testDataProvider;\r
+    }\r
+\r
+    public void testBasic() {\r
+        Workbook wb = _testDataProvider.createWorkbook();\r
+        Sheet sh = wb.createSheet();\r
+        SheetConditionalFormatting sheetCF = sh.getSheetConditionalFormatting();\r
+\r
+        assertEquals(0, sheetCF.getNumConditionalFormattings());\r
+        try {\r
+            assertNull(sheetCF.getConditionalFormattingAt(0));\r
+            fail("expected exception");\r
+        } catch (IllegalArgumentException e) {\r
+            assertTrue(e.getMessage().startsWith("Specified CF index 0 is outside the allowable range"));\r
+        }\r
+\r
+        try {\r
+            sheetCF.removeConditionalFormatting(0);\r
+            fail("expected exception");\r
+        } catch (IllegalArgumentException e) {\r
+            assertTrue(e.getMessage().startsWith("Specified CF index 0 is outside the allowable range"));\r
+        }\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("1");\r
+        ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule("2");\r
+        ConditionalFormattingRule rule3 = sheetCF.createConditionalFormattingRule("3");\r
+        ConditionalFormattingRule rule4 = sheetCF.createConditionalFormattingRule("4");\r
+        try {\r
+            sheetCF.addConditionalFormatting(null, rule1);\r
+            fail("expected exception");\r
+        } catch (IllegalArgumentException e) {\r
+            assertTrue(e.getMessage().startsWith("regions must not be null"));\r
+        }\r
+        try {\r
+            sheetCF.addConditionalFormatting(\r
+                    new CellRangeAddress[]{ CellRangeAddress.valueOf("A1:A3") },\r
+                    (ConditionalFormattingRule)null);\r
+            fail("expected exception");\r
+        } catch (IllegalArgumentException e) {\r
+            assertTrue(e.getMessage().startsWith("cfRules must not be null"));\r
+        }\r
+\r
+        try {\r
+            sheetCF.addConditionalFormatting(\r
+                    new CellRangeAddress[]{ CellRangeAddress.valueOf("A1:A3") },\r
+                    new ConditionalFormattingRule[0]);\r
+            fail("expected exception");\r
+        } catch (IllegalArgumentException e) {\r
+            assertTrue(e.getMessage().startsWith("cfRules must not be empty"));\r
+        }\r
+\r
+        try {\r
+            sheetCF.addConditionalFormatting(\r
+                    new CellRangeAddress[]{ CellRangeAddress.valueOf("A1:A3") },\r
+                    new ConditionalFormattingRule[]{rule1, rule2, rule3, rule4});\r
+            fail("expected exception");\r
+        } catch (IllegalArgumentException e) {\r
+            assertTrue(e.getMessage().startsWith("Number of rules must not exceed 3"));\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Test format conditions based on a boolean formula\r
+     */\r
+    public void testBooleanFormulaConditions() {\r
+        Workbook wb = _testDataProvider.createWorkbook();\r
+        Sheet sh = wb.createSheet();\r
+        SheetConditionalFormatting sheetCF = sh.getSheetConditionalFormatting();\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("SUM(A1:A5)>10");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_FORMULA, rule1.getConditionType());\r
+        assertEquals("SUM(A1:A5)>10", rule1.getFormula1());\r
+        int formatIndex1 = sheetCF.addConditionalFormatting(\r
+                new CellRangeAddress[]{\r
+                        CellRangeAddress.valueOf("B1"),\r
+                        CellRangeAddress.valueOf("C3"),\r
+                }, rule1);\r
+        assertEquals(0, formatIndex1);\r
+        assertEquals(1, sheetCF.getNumConditionalFormattings());\r
+        CellRangeAddress[] ranges1 = sheetCF.getConditionalFormattingAt(formatIndex1).getFormattingRanges();\r
+        assertEquals(2, ranges1.length);\r
+        assertEquals("B1", ranges1[0].formatAsString());\r
+        assertEquals("C3", ranges1[1].formatAsString());\r
+\r
+        // adjacent address are merged\r
+        int formatIndex2 = sheetCF.addConditionalFormatting(\r
+                new CellRangeAddress[]{\r
+                        CellRangeAddress.valueOf("B1"),\r
+                        CellRangeAddress.valueOf("B2"),\r
+                        CellRangeAddress.valueOf("B3"),\r
+                }, rule1);\r
+        assertEquals(1, formatIndex2);\r
+        assertEquals(2, sheetCF.getNumConditionalFormattings());\r
+        CellRangeAddress[] ranges2 = sheetCF.getConditionalFormattingAt(formatIndex2).getFormattingRanges();\r
+        assertEquals(1, ranges2.length);\r
+        assertEquals("B1:B3", ranges2[0].formatAsString());\r
+    }\r
+\r
+    public void testSingleFormulaConditions() {\r
+        Workbook wb = _testDataProvider.createWorkbook();\r
+        Sheet sh = wb.createSheet();\r
+        SheetConditionalFormatting sheetCF = sh.getSheetConditionalFormatting();\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.EQUAL, "SUM(A1:A5)+10");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule1.getConditionType());\r
+        assertEquals("SUM(A1:A5)+10", rule1.getFormula1());\r
+        assertEquals(ComparisonOperator.EQUAL, rule1.getComparisonOperation());\r
+\r
+        ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.NOT_EQUAL, "15");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule2.getConditionType());\r
+        assertEquals("15", rule2.getFormula1());\r
+        assertEquals(ComparisonOperator.NOT_EQUAL, rule2.getComparisonOperation());\r
+\r
+        ConditionalFormattingRule rule3 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.NOT_EQUAL, "15");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule3.getConditionType());\r
+        assertEquals("15", rule3.getFormula1());\r
+        assertEquals(ComparisonOperator.NOT_EQUAL, rule3.getComparisonOperation());\r
+\r
+        ConditionalFormattingRule rule4 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.GT, "0");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule4.getConditionType());\r
+        assertEquals("0", rule4.getFormula1());\r
+        assertEquals(ComparisonOperator.GT, rule4.getComparisonOperation());\r
+\r
+        ConditionalFormattingRule rule5 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.LT, "0");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule5.getConditionType());\r
+        assertEquals("0", rule5.getFormula1());\r
+        assertEquals(ComparisonOperator.LT, rule5.getComparisonOperation());\r
+\r
+        ConditionalFormattingRule rule6 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.GE, "0");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule6.getConditionType());\r
+        assertEquals("0", rule6.getFormula1());\r
+        assertEquals(ComparisonOperator.GE, rule6.getComparisonOperation());\r
+\r
+        ConditionalFormattingRule rule7 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.LE, "0");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule7.getConditionType());\r
+        assertEquals("0", rule7.getFormula1());\r
+        assertEquals(ComparisonOperator.LE, rule7.getComparisonOperation());\r
+\r
+        ConditionalFormattingRule rule8 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.BETWEEN, "0", "5");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule8.getConditionType());\r
+        assertEquals("0", rule8.getFormula1());\r
+        assertEquals("5", rule8.getFormula2());\r
+        assertEquals(ComparisonOperator.BETWEEN, rule8.getComparisonOperation());\r
+\r
+        ConditionalFormattingRule rule9 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.NOT_BETWEEN, "0", "5");\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule9.getConditionType());\r
+        assertEquals("0", rule9.getFormula1());\r
+        assertEquals("5", rule9.getFormula2());\r
+        assertEquals(ComparisonOperator.NOT_BETWEEN, rule9.getComparisonOperation());\r
+    }\r
+\r
+    public void testCopy() {\r
+        Workbook wb = _testDataProvider.createWorkbook();\r
+        Sheet sheet1 = wb.createSheet();\r
+        Sheet sheet2 = wb.createSheet();\r
+        SheetConditionalFormatting sheet1CF = sheet1.getSheetConditionalFormatting();\r
+        SheetConditionalFormatting sheet2CF = sheet2.getSheetConditionalFormatting();\r
+        assertEquals(0, sheet1CF.getNumConditionalFormattings());\r
+        assertEquals(0, sheet2CF.getNumConditionalFormattings());\r
+\r
+        ConditionalFormattingRule rule1 = sheet1CF.createConditionalFormattingRule(\r
+                ComparisonOperator.EQUAL, "SUM(A1:A5)+10");\r
+\r
+        ConditionalFormattingRule rule2 = sheet1CF.createConditionalFormattingRule(\r
+                ComparisonOperator.NOT_EQUAL, "15");\r
+\r
+        // adjacent address are merged\r
+        int formatIndex = sheet1CF.addConditionalFormatting(\r
+                new CellRangeAddress[]{\r
+                        CellRangeAddress.valueOf("A1:A5"),\r
+                        CellRangeAddress.valueOf("C1:C5")\r
+                }, rule1, rule2);\r
+        assertEquals(0, formatIndex);\r
+        assertEquals(1, sheet1CF.getNumConditionalFormattings());\r
+\r
+        assertEquals(0, sheet2CF.getNumConditionalFormattings());\r
+        sheet2CF.addConditionalFormatting(sheet1CF.getConditionalFormattingAt(formatIndex));\r
+        assertEquals(1, sheet2CF.getNumConditionalFormattings());\r
+\r
+        ConditionalFormatting sheet2cf = sheet2CF.getConditionalFormattingAt(0);\r
+        assertEquals(2, sheet2cf.getNumberOfRules());\r
+        assertEquals("SUM(A1:A5)+10", sheet2cf.getRule(0).getFormula1());\r
+        assertEquals(ComparisonOperator.EQUAL, sheet2cf.getRule(0).getComparisonOperation());\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, sheet2cf.getRule(0).getConditionType());\r
+        assertEquals("15", sheet2cf.getRule(1).getFormula1());\r
+        assertEquals(ComparisonOperator.NOT_EQUAL, sheet2cf.getRule(1).getComparisonOperation());\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, sheet2cf.getRule(1).getConditionType());\r
+    }\r
+\r
+    public void testRemove() {\r
+        Workbook wb = _testDataProvider.createWorkbook();\r
+        Sheet sheet1 = wb.createSheet();\r
+        SheetConditionalFormatting sheetCF = sheet1.getSheetConditionalFormatting();\r
+        assertEquals(0, sheetCF.getNumConditionalFormattings());\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.EQUAL, "SUM(A1:A5)");\r
+\r
+        // adjacent address are merged\r
+        int formatIndex = sheetCF.addConditionalFormatting(\r
+                new CellRangeAddress[]{\r
+                        CellRangeAddress.valueOf("A1:A5")\r
+                }, rule1);\r
+        assertEquals(0, formatIndex);\r
+        assertEquals(1, sheetCF.getNumConditionalFormattings());\r
+        sheetCF.removeConditionalFormatting(0);\r
+        assertEquals(0, sheetCF.getNumConditionalFormattings());\r
+        try {\r
+            assertNull(sheetCF.getConditionalFormattingAt(0));\r
+            fail("expected exception");\r
+        } catch (IllegalArgumentException e) {\r
+            assertTrue(e.getMessage().startsWith("Specified CF index 0 is outside the allowable range"));\r
+        }\r
+\r
+        formatIndex = sheetCF.addConditionalFormatting(\r
+                new CellRangeAddress[]{\r
+                        CellRangeAddress.valueOf("A1:A5")\r
+                }, rule1);\r
+        assertEquals(0, formatIndex);\r
+        assertEquals(1, sheetCF.getNumConditionalFormattings());\r
+        sheetCF.removeConditionalFormatting(0);\r
+        assertEquals(0, sheetCF.getNumConditionalFormattings());\r
+        try {\r
+            assertNull(sheetCF.getConditionalFormattingAt(0));\r
+            fail("expected exception");\r
+        } catch (IllegalArgumentException e) {\r
+            assertTrue(e.getMessage().startsWith("Specified CF index 0 is outside the allowable range"));\r
+        }\r
+    }\r
+    \r
+    public void testCreateCF() {\r
+        Workbook workbook = _testDataProvider.createWorkbook();\r
+        Sheet sheet = workbook.createSheet();\r
+        String formula = "7";\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(formula);\r
+        FontFormatting fontFmt = rule1.createFontFormatting();\r
+        fontFmt.setFontStyle(true, false);\r
+\r
+        BorderFormatting bordFmt = rule1.createBorderFormatting();\r
+        bordFmt.setBorderBottom(BorderFormatting.BORDER_THIN);\r
+        bordFmt.setBorderTop(BorderFormatting.BORDER_THICK);\r
+        bordFmt.setBorderLeft(BorderFormatting.BORDER_DASHED);\r
+        bordFmt.setBorderRight(BorderFormatting.BORDER_DOTTED);\r
+\r
+        PatternFormatting patternFmt = rule1.createPatternFormatting();\r
+        patternFmt.setFillBackgroundColor(IndexedColors.YELLOW.index);\r
+\r
+\r
+        ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2");\r
+        ConditionalFormattingRule [] cfRules =\r
+        {\r
+            rule1, rule2\r
+        };\r
+\r
+        short col = 1;\r
+        CellRangeAddress [] regions = {\r
+            new CellRangeAddress(0, 65535, col, col)\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, cfRules);\r
+        sheetCF.addConditionalFormatting(regions, cfRules);\r
+\r
+        // Verification\r
+        assertEquals(2, sheetCF.getNumConditionalFormattings());\r
+        sheetCF.removeConditionalFormatting(1);\r
+        assertEquals(1, sheetCF.getNumConditionalFormattings());\r
+        ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);\r
+        assertNotNull(cf);\r
+\r
+        regions = cf.getFormattingRanges();\r
+        assertNotNull(regions);\r
+        assertEquals(1, regions.length);\r
+        CellRangeAddress r = regions[0];\r
+        assertEquals(1, r.getFirstColumn());\r
+        assertEquals(1, r.getLastColumn());\r
+        assertEquals(0, r.getFirstRow());\r
+        assertEquals(65535, r.getLastRow());\r
+\r
+        assertEquals(2, cf.getNumberOfRules());\r
+\r
+        rule1 = cf.getRule(0);\r
+        assertEquals("7",rule1.getFormula1());\r
+        assertNull(rule1.getFormula2());\r
+\r
+        FontFormatting    r1fp = rule1.getFontFormatting();\r
+        assertNotNull(r1fp);\r
+\r
+        assertTrue(r1fp.isItalic());\r
+        assertFalse(r1fp.isBold());\r
+\r
+        BorderFormatting  r1bf = rule1.getBorderFormatting();\r
+        assertNotNull(r1bf);\r
+        assertEquals(BorderFormatting.BORDER_THIN, r1bf.getBorderBottom());\r
+        assertEquals(BorderFormatting.BORDER_THICK,r1bf.getBorderTop());\r
+        assertEquals(BorderFormatting.BORDER_DASHED,r1bf.getBorderLeft());\r
+        assertEquals(BorderFormatting.BORDER_DOTTED,r1bf.getBorderRight());\r
+\r
+        PatternFormatting r1pf = rule1.getPatternFormatting();\r
+        assertNotNull(r1pf);\r
+//        assertEquals(IndexedColors.YELLOW.index,r1pf.getFillBackgroundColor());\r
+\r
+        rule2 = cf.getRule(1);\r
+        assertEquals("2",rule2.getFormula2());\r
+        assertEquals("1",rule2.getFormula1());\r
+    }\r
+\r
+    public void testClone() {\r
+\r
+        Workbook wb = _testDataProvider.createWorkbook();\r
+        Sheet sheet = wb.createSheet();\r
+        String formula = "7";\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(formula);\r
+        FontFormatting fontFmt = rule1.createFontFormatting();\r
+        fontFmt.setFontStyle(true, false);\r
+\r
+        PatternFormatting patternFmt = rule1.createPatternFormatting();\r
+        patternFmt.setFillBackgroundColor(IndexedColors.YELLOW.index);\r
+\r
+\r
+        ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2");\r
+        ConditionalFormattingRule [] cfRules =\r
+        {\r
+            rule1, rule2\r
+        };\r
+\r
+        short col = 1;\r
+        CellRangeAddress [] regions = {\r
+            new CellRangeAddress(0, 65535, col, col)\r
+        };\r
+\r
+        sheetCF.addConditionalFormatting(regions, cfRules);\r
+\r
+        try {\r
+            wb.cloneSheet(0);\r
+        } catch (RuntimeException e) {\r
+            if (e.getMessage().indexOf("needs to define a clone method") > 0) {\r
+                fail("Indentified bug 45682");\r
+            }\r
+            throw e;\r
+        }\r
+        assertEquals(2, wb.getNumberOfSheets());\r
+    }\r
+\r
+    public void testShiftRows() {\r
+\r
+        Workbook wb = _testDataProvider.createWorkbook();\r
+        Sheet sheet = wb.createSheet();\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(\r
+                ComparisonOperator.BETWEEN, "SUM(A10:A15)", "1+SUM(B16:B30)");\r
+        FontFormatting fontFmt = rule1.createFontFormatting();\r
+        fontFmt.setFontStyle(true, false);\r
+\r
+        PatternFormatting patternFmt = rule1.createPatternFormatting();\r
+        patternFmt.setFillBackgroundColor(IndexedColors.YELLOW.index);\r
+        ConditionalFormattingRule [] cfRules = { rule1, };\r
+\r
+        CellRangeAddress [] regions = {\r
+            new CellRangeAddress(2, 4, 0, 0), // A3:A5\r
+        };\r
+        sheetCF.addConditionalFormatting(regions, cfRules);\r
+\r
+        // This row-shift should destroy the CF region\r
+        sheet.shiftRows(10, 20, -9);\r
+        assertEquals(0, sheetCF.getNumConditionalFormattings());\r
+\r
+        // re-add the CF\r
+        sheetCF.addConditionalFormatting(regions, cfRules);\r
+\r
+        // This row shift should only affect the formulas\r
+        sheet.shiftRows(14, 17, 8);\r
+        ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);\r
+        assertEquals("SUM(A10:A23)", cf.getRule(0).getFormula1());\r
+        assertEquals("1+SUM(B24:B30)", cf.getRule(0).getFormula2());\r
+\r
+        sheet.shiftRows(0, 8, 21);\r
+        cf = sheetCF.getConditionalFormattingAt(0);\r
+        assertEquals("SUM(A10:A21)", cf.getRule(0).getFormula1());\r
+        assertEquals("1+SUM(#REF!)", cf.getRule(0).getFormula2());\r
+    }\r
+\r
+    protected void testRead(String filename){\r
+        Workbook wb = _testDataProvider.openSampleWorkbook(filename);\r
+        Sheet sh = wb.getSheet("CF");\r
+        SheetConditionalFormatting sheetCF = sh.getSheetConditionalFormatting();\r
+        assertEquals(3, sheetCF.getNumConditionalFormattings());\r
+\r
+        ConditionalFormatting cf1 = sheetCF.getConditionalFormattingAt(0);\r
+        assertEquals(2, cf1.getNumberOfRules());\r
+\r
+        CellRangeAddress[] regions1 = cf1.getFormattingRanges();\r
+        assertEquals(1, regions1.length);\r
+        assertEquals("A1:A8", regions1[0].formatAsString());\r
+\r
+        // CF1 has two rules: values less than -3 are bold-italic red, values greater than 3 are green\r
+        ConditionalFormattingRule rule1 = cf1.getRule(0);\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule1.getConditionType());\r
+        assertEquals(ComparisonOperator.GT, rule1.getComparisonOperation());\r
+        assertEquals("3", rule1.getFormula1());\r
+        assertNull(rule1.getFormula2());\r
+        // fills and borders are not set\r
+        assertNull(rule1.getPatternFormatting());\r
+        assertNull(rule1.getBorderFormatting());\r
+\r
+        FontFormatting fmt1 = rule1.getFontFormatting();\r
+//        assertEquals(IndexedColors.GREEN.index, fmt1.getFontColorIndex());\r
+        assertTrue(fmt1.isBold());\r
+        assertFalse(fmt1.isItalic());\r
+\r
+        ConditionalFormattingRule rule2 = cf1.getRule(1);\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule2.getConditionType());\r
+        assertEquals(ComparisonOperator.LT, rule2.getComparisonOperation());\r
+        assertEquals("-3", rule2.getFormula1());\r
+        assertNull(rule2.getFormula2());\r
+        assertNull(rule2.getPatternFormatting());\r
+        assertNull(rule2.getBorderFormatting());\r
+\r
+        FontFormatting fmt2 = rule2.getFontFormatting();\r
+//        assertEquals(IndexedColors.RED.index, fmt2.getFontColorIndex());\r
+        assertTrue(fmt2.isBold());\r
+        assertTrue(fmt2.isItalic());\r
+\r
+\r
+        ConditionalFormatting cf2 = sheetCF.getConditionalFormattingAt(1);\r
+        assertEquals(1, cf2.getNumberOfRules());\r
+        CellRangeAddress[] regions2 = cf2.getFormattingRanges();\r
+        assertEquals(1, regions2.length);\r
+        assertEquals("B9", regions2[0].formatAsString());\r
+\r
+        ConditionalFormattingRule rule3 = cf2.getRule(0);\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_FORMULA, rule3.getConditionType());\r
+        assertEquals(ComparisonOperator.NO_COMPARISON, rule3.getComparisonOperation());\r
+        assertEquals("$A$8>5", rule3.getFormula1());\r
+        assertNull(rule3.getFormula2());\r
+\r
+        FontFormatting fmt3 = rule3.getFontFormatting();\r
+//        assertEquals(IndexedColors.RED.index, fmt3.getFontColorIndex());\r
+        assertTrue(fmt3.isBold());\r
+        assertTrue(fmt3.isItalic());\r
+\r
+        PatternFormatting fmt4 = rule3.getPatternFormatting();\r
+//        assertEquals(IndexedColors.LIGHT_CORNFLOWER_BLUE.index, fmt4.getFillBackgroundColor());\r
+//        assertEquals(IndexedColors.AUTOMATIC.index, fmt4.getFillForegroundColor());\r
+        assertEquals(PatternFormatting.NO_FILL, fmt4.getFillPattern());\r
+        // borders are not set\r
+        assertNull(rule3.getBorderFormatting());\r
+\r
+        ConditionalFormatting cf3 = sheetCF.getConditionalFormattingAt(2);\r
+        CellRangeAddress[] regions3 = cf3.getFormattingRanges();\r
+        assertEquals(1, regions3.length);\r
+        assertEquals("B1:B7", regions3[0].formatAsString());\r
+        assertEquals(2, cf3.getNumberOfRules());\r
+\r
+        ConditionalFormattingRule rule4 = cf3.getRule(0);\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule4.getConditionType());\r
+        assertEquals(ComparisonOperator.LE, rule4.getComparisonOperation());\r
+        assertEquals("\"AAA\"", rule4.getFormula1());\r
+        assertNull(rule4.getFormula2());\r
+\r
+        ConditionalFormattingRule rule5 = cf3.getRule(1);\r
+        assertEquals(ConditionalFormattingRule.CONDITION_TYPE_CELL_VALUE_IS, rule5.getConditionType());\r
+        assertEquals(ComparisonOperator.BETWEEN, rule5.getComparisonOperation());\r
+        assertEquals("\"A\"", rule5.getFormula1());\r
+        assertEquals("\"AAA\"", rule5.getFormula2());\r
+    }\r
+\r
+\r
+    public void testCreateFontFormatting() {\r
+        Workbook workbook = _testDataProvider.createWorkbook();\r
+        Sheet sheet = workbook.createSheet();\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.EQUAL, "7");\r
+        FontFormatting fontFmt = rule1.createFontFormatting();\r
+        assertFalse(fontFmt.isItalic());\r
+        assertFalse(fontFmt.isBold());\r
+        fontFmt.setFontStyle(true, true);\r
+        assertTrue(fontFmt.isItalic());\r
+        assertTrue(fontFmt.isBold());\r
+\r
+        assertEquals(-1, fontFmt.getFontHeight()); // not modified\r
+        fontFmt.setFontHeight(200);\r
+        assertEquals(200, fontFmt.getFontHeight()); \r
+        fontFmt.setFontHeight(100);\r
+        assertEquals(100, fontFmt.getFontHeight());\r
+\r
+        assertEquals(FontFormatting.SS_NONE, fontFmt.getEscapementType());\r
+        fontFmt.setEscapementType(FontFormatting.SS_SUB);\r
+        assertEquals(FontFormatting.SS_SUB, fontFmt.getEscapementType());\r
+        fontFmt.setEscapementType(FontFormatting.SS_NONE);\r
+        assertEquals(FontFormatting.SS_NONE, fontFmt.getEscapementType());\r
+        fontFmt.setEscapementType(FontFormatting.SS_SUPER);\r
+        assertEquals(FontFormatting.SS_SUPER, fontFmt.getEscapementType());\r
+\r
+        assertEquals(FontFormatting.U_NONE, fontFmt.getUnderlineType());\r
+        fontFmt.setUnderlineType(FontFormatting.U_SINGLE);\r
+        assertEquals(FontFormatting.U_SINGLE, fontFmt.getUnderlineType());\r
+        fontFmt.setUnderlineType(FontFormatting.U_NONE);\r
+        assertEquals(FontFormatting.U_NONE, fontFmt.getUnderlineType());\r
+        fontFmt.setUnderlineType(FontFormatting.U_DOUBLE);\r
+        assertEquals(FontFormatting.U_DOUBLE, fontFmt.getUnderlineType());\r
+\r
+        assertEquals(-1, fontFmt.getFontColorIndex());\r
+        fontFmt.setFontColorIndex(IndexedColors.RED.index);\r
+        assertEquals(IndexedColors.RED.index, fontFmt.getFontColorIndex());\r
+        fontFmt.setFontColorIndex(IndexedColors.AUTOMATIC.index);\r
+        assertEquals(IndexedColors.AUTOMATIC.index, fontFmt.getFontColorIndex());\r
+        fontFmt.setFontColorIndex(IndexedColors.BLUE.index);\r
+        assertEquals(IndexedColors.BLUE.index, fontFmt.getFontColorIndex());\r
+\r
+        ConditionalFormattingRule [] cfRules = { rule1 };\r
+\r
+        CellRangeAddress [] regions = { CellRangeAddress.valueOf("A1:A5") };\r
+\r
+        sheetCF.addConditionalFormatting(regions, cfRules);\r
+\r
+        // Verification\r
+        ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);\r
+        assertNotNull(cf);\r
+\r
+        assertEquals(1, cf.getNumberOfRules());\r
+\r
+        FontFormatting  r1fp = cf.getRule(0).getFontFormatting();\r
+        assertNotNull(r1fp);\r
+\r
+        assertTrue(r1fp.isItalic());\r
+        assertTrue(r1fp.isBold());\r
+        assertEquals(FontFormatting.SS_SUPER, r1fp.getEscapementType());\r
+        assertEquals(FontFormatting.U_DOUBLE, r1fp.getUnderlineType());\r
+        assertEquals(IndexedColors.BLUE.index, r1fp.getFontColorIndex());\r
+\r
+    }\r
+\r
+    public void testCreatePatternFormatting() {\r
+        Workbook workbook = _testDataProvider.createWorkbook();\r
+        Sheet sheet = workbook.createSheet();\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.EQUAL, "7");\r
+        PatternFormatting patternFmt = rule1.createPatternFormatting();\r
+\r
+        assertEquals(0, patternFmt.getFillBackgroundColor());\r
+        patternFmt.setFillBackgroundColor(IndexedColors.RED.index);\r
+        assertEquals(IndexedColors.RED.index, patternFmt.getFillBackgroundColor());\r
+\r
+        assertEquals(0, patternFmt.getFillForegroundColor());\r
+        patternFmt.setFillForegroundColor(IndexedColors.BLUE.index);\r
+        assertEquals(IndexedColors.BLUE.index, patternFmt.getFillForegroundColor());\r
+\r
+        assertEquals(PatternFormatting.NO_FILL, patternFmt.getFillPattern());\r
+        patternFmt.setFillPattern(PatternFormatting.SOLID_FOREGROUND);\r
+        assertEquals(PatternFormatting.SOLID_FOREGROUND, patternFmt.getFillPattern());\r
+        patternFmt.setFillPattern(PatternFormatting.NO_FILL);\r
+        assertEquals(PatternFormatting.NO_FILL, patternFmt.getFillPattern());\r
+        patternFmt.setFillPattern(PatternFormatting.BRICKS);\r
+        assertEquals(PatternFormatting.BRICKS, patternFmt.getFillPattern());\r
+\r
+        ConditionalFormattingRule [] cfRules = { rule1 };\r
+\r
+        CellRangeAddress [] regions = { CellRangeAddress.valueOf("A1:A5") };\r
+\r
+        sheetCF.addConditionalFormatting(regions, cfRules);\r
+\r
+        // Verification\r
+        ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);\r
+        assertNotNull(cf);\r
+\r
+        assertEquals(1, cf.getNumberOfRules());\r
+\r
+        PatternFormatting  r1fp = cf.getRule(0).getPatternFormatting();\r
+        assertNotNull(r1fp);\r
+\r
+        assertEquals(IndexedColors.RED.index, r1fp.getFillBackgroundColor());\r
+        assertEquals(IndexedColors.BLUE.index, r1fp.getFillForegroundColor());\r
+        assertEquals(PatternFormatting.BRICKS, r1fp.getFillPattern());\r
+    }\r
+\r
+    public void testCreateBorderFormatting() {\r
+        Workbook workbook = _testDataProvider.createWorkbook();\r
+        Sheet sheet = workbook.createSheet();\r
+\r
+        SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();\r
+\r
+        ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.EQUAL, "7");\r
+        BorderFormatting borderFmt = rule1.createBorderFormatting();\r
+\r
+        assertEquals(BorderFormatting.BORDER_NONE, borderFmt.getBorderBottom());\r
+        borderFmt.setBorderBottom(BorderFormatting.BORDER_DOTTED);\r
+        assertEquals(BorderFormatting.BORDER_DOTTED, borderFmt.getBorderBottom());\r
+        borderFmt.setBorderBottom(BorderFormatting.BORDER_NONE);\r
+        assertEquals(BorderFormatting.BORDER_NONE, borderFmt.getBorderBottom());\r
+        borderFmt.setBorderBottom(BorderFormatting.BORDER_THICK);\r
+        assertEquals(BorderFormatting.BORDER_THICK, borderFmt.getBorderBottom());\r
+\r
+        assertEquals(BorderFormatting.BORDER_NONE, borderFmt.getBorderTop());\r
+        borderFmt.setBorderTop(BorderFormatting.BORDER_DOTTED);\r
+        assertEquals(BorderFormatting.BORDER_DOTTED, borderFmt.getBorderTop());\r
+        borderFmt.setBorderTop(BorderFormatting.BORDER_NONE);\r
+        assertEquals(BorderFormatting.BORDER_NONE, borderFmt.getBorderTop());\r
+        borderFmt.setBorderTop(BorderFormatting.BORDER_THICK);\r
+        assertEquals(BorderFormatting.BORDER_THICK, borderFmt.getBorderTop());\r
+\r
+        assertEquals(BorderFormatting.BORDER_NONE, borderFmt.getBorderLeft());\r
+        borderFmt.setBorderLeft(BorderFormatting.BORDER_DOTTED);\r
+        assertEquals(BorderFormatting.BORDER_DOTTED, borderFmt.getBorderLeft());\r
+        borderFmt.setBorderLeft(BorderFormatting.BORDER_NONE);\r
+        assertEquals(BorderFormatting.BORDER_NONE, borderFmt.getBorderLeft());\r
+        borderFmt.setBorderLeft(BorderFormatting.BORDER_THIN);\r
+        assertEquals(BorderFormatting.BORDER_THIN, borderFmt.getBorderLeft());\r
+\r
+        assertEquals(BorderFormatting.BORDER_NONE, borderFmt.getBorderRight());\r
+        borderFmt.setBorderRight(BorderFormatting.BORDER_DOTTED);\r
+        assertEquals(BorderFormatting.BORDER_DOTTED, borderFmt.getBorderRight());\r
+        borderFmt.setBorderRight(BorderFormatting.BORDER_NONE);\r
+        assertEquals(BorderFormatting.BORDER_NONE, borderFmt.getBorderRight());\r
+        borderFmt.setBorderRight(BorderFormatting.BORDER_HAIR);\r
+        assertEquals(BorderFormatting.BORDER_HAIR, borderFmt.getBorderRight());\r
+\r
+        ConditionalFormattingRule [] cfRules = { rule1 };\r
+\r
+        CellRangeAddress [] regions = { CellRangeAddress.valueOf("A1:A5") };\r
+\r
+        sheetCF.addConditionalFormatting(regions, cfRules);\r
+\r
+        // Verification\r
+        ConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0);\r
+        assertNotNull(cf);\r
+\r
+        assertEquals(1, cf.getNumberOfRules());\r
+\r
+        BorderFormatting  r1fp = cf.getRule(0).getBorderFormatting();\r
+        assertNotNull(r1fp);\r
+        assertEquals(BorderFormatting.BORDER_THICK, r1fp.getBorderBottom());\r
+        assertEquals(BorderFormatting.BORDER_THICK, r1fp.getBorderTop());\r
+        assertEquals(BorderFormatting.BORDER_THIN, r1fp.getBorderLeft());\r
+        assertEquals(BorderFormatting.BORDER_HAIR, r1fp.getBorderRight());\r
+\r
+    }\r
+}\r
diff --git a/test-data/spreadsheet/WithConditionalFormatting.xls b/test-data/spreadsheet/WithConditionalFormatting.xls
new file mode 100755 (executable)
index 0000000..b47782a
Binary files /dev/null and b/test-data/spreadsheet/WithConditionalFormatting.xls differ
diff --git a/test-data/spreadsheet/WithConditionalFormatting.xlsx b/test-data/spreadsheet/WithConditionalFormatting.xlsx
new file mode 100755 (executable)
index 0000000..f2d2923
Binary files /dev/null and b/test-data/spreadsheet/WithConditionalFormatting.xlsx differ