From 35d89933c9748d29bae8e1bc33af122e2bd79e49 Mon Sep 17 00:00:00 2001 From: Josh Micich Date: Tue, 15 Apr 2008 17:07:06 +0000 Subject: [PATCH] Conditional Formatting (30311) - API improvements, added HSSFSheetConditionalFormatting git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@648334 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 1 + src/documentation/content/xdocs/status.xml | 1 + .../apache/poi/hssf/record/CFRuleRecord.java | 7 +- .../hssf/usermodel/HSSFBorderFormatting.java | 62 +++++- .../usermodel/HSSFConditionalFormatting.java | 47 ++--- .../HSSFConditionalFormattingRule.java | 121 +++++++---- .../hssf/usermodel/HSSFFontFormatting.java | 20 +- .../hssf/usermodel/HSSFPatternFormatting.java | 25 ++- .../apache/poi/hssf/usermodel/HSSFSheet.java | 174 ++-------------- .../HSSFSheetConditionalFormatting.java | 196 ++++++++++++++++++ .../poi/hssf/record/TestCFRuleRecord.java | 3 +- .../TestHSSFConditionalFormatting.java | 35 ++-- 12 files changed, 428 insertions(+), 264 deletions(-) create mode 100644 src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index 0850c6ce2..91090ca5a 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,6 +37,7 @@ + 30311 - Conditional Formatting - improved API, added HSSFSheetConditionalFormatting Update the formula parser code to use a HSSFWorkbook, rather than the low level model.Workbook, to make things cleaner and make supporting XSSF formulas in future much easier Fix the logger used by POIFSFileSystem, so that commons-logging isn't required when not used Update HSLFSlideShow and HSSFWorkbook to take advantage of POIFS updates, and allow reading embeded documents diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index aaf35f4d8..ea3157841 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 30311 - Conditional Formatting - improved API, added HSSFSheetConditionalFormatting Update the formula parser code to use a HSSFWorkbook, rather than the low level model.Workbook, to make things cleaner and make supporting XSSF formulas in future much easier Fix the logger used by POIFSFileSystem, so that commons-logging isn't required when not used Update HSLFSlideShow and HSSFWorkbook to take advantage of POIFS updates, and allow reading embeded documents diff --git a/src/java/org/apache/poi/hssf/record/CFRuleRecord.java b/src/java/org/apache/poi/hssf/record/CFRuleRecord.java index 5b9f98aa7..2b1705abe 100644 --- a/src/java/org/apache/poi/hssf/record/CFRuleRecord.java +++ b/src/java/org/apache/poi/hssf/record/CFRuleRecord.java @@ -30,6 +30,7 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.util.BitField; import org.apache.poi.util.BitFieldFactory; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.StringUtil; /** * Conditional Formatting Rule Record. @@ -63,7 +64,7 @@ public final class CFRuleRecord extends Record private int field_5_options; - private static final BitField modificationBits = bf(0x83FFFFFF); // Bits: font,align,bord,patt,prot + private static final BitField modificationBits = bf(0x003FFFFF); // Bits: font,align,bord,patt,prot private static final BitField alignHor = bf(0x00000001); // 0 = Horizontal alignment modified private static final BitField alignVer = bf(0x00000002); // 0 = Vertical alignment modified private static final BitField alignWrap = bf(0x00000004); // 0 = Text wrapped flag modified @@ -608,6 +609,8 @@ public final class CFRuleRecord extends Record { StringBuffer buffer = new StringBuffer(); buffer.append("[CFRULE]\n"); + buffer.append(" OPTION FLAGS=0x"+Integer.toHexString(getOptions())); + /* if( containsFontFormattingBlock()) { buffer.append(fontFormatting.toString()); @@ -620,7 +623,7 @@ public final class CFRuleRecord extends Record { buffer.append(patternFormatting.toString()); } - buffer.append("[/CFRULE]\n"); + buffer.append("[/CFRULE]\n");*/ return buffer.toString(); } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java index ba2d58762..33e1d3a85 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java @@ -17,6 +17,7 @@ package org.apache.poi.hssf.usermodel; +import org.apache.poi.hssf.record.CFRuleRecord; import org.apache.poi.hssf.record.cf.BorderFormatting; /** @@ -58,18 +59,15 @@ public final class HSSFBorderFormatting public final static short BORDER_SLANTED_DASH_DOT = BorderFormatting.BORDER_SLANTED_DASH_DOT; + private final CFRuleRecord cfRuleRecord; private final BorderFormatting borderFormatting; - public HSSFBorderFormatting() + protected HSSFBorderFormatting(CFRuleRecord cfRuleRecord) { - borderFormatting = new BorderFormatting(); + this.cfRuleRecord = cfRuleRecord; + this.borderFormatting = cfRuleRecord.getBorderFormatting(); } - protected HSSFBorderFormatting(BorderFormatting borderFormatting) - { - this.borderFormatting = borderFormatting; - } - protected BorderFormatting getBorderFormattingBlock() { return borderFormatting; @@ -138,60 +136,110 @@ public final class HSSFBorderFormatting public void setBackwardDiagonalOn(boolean on) { borderFormatting.setBackwardDiagonalOn(on); + if( on ) + { + cfRuleRecord.setTopLeftBottomRightBorderModified(on); + } } public void setBorderBottom(short border) { borderFormatting.setBorderBottom(border); + if( border != 0) + { + cfRuleRecord.setBottomBorderModified(true); + } } public void setBorderDiagonal(short border) { borderFormatting.setBorderDiagonal(border); + if( border != 0) + { + cfRuleRecord.setBottomLeftTopRightBorderModified(true); + cfRuleRecord.setTopLeftBottomRightBorderModified(true); + } } public void setBorderLeft(short border) { borderFormatting.setBorderLeft(border); + if( border != 0) + { + cfRuleRecord.setLeftBorderModified(true); + } } public void setBorderRight(short border) { borderFormatting.setBorderRight(border); + if( border != 0) + { + cfRuleRecord.setRightBorderModified(true); + } } public void setBorderTop(short border) { borderFormatting.setBorderTop(border); + if( border != 0) + { + cfRuleRecord.setTopBorderModified(true); + } } public void setBottomBorderColor(short color) { borderFormatting.setBottomBorderColor(color); + if( color != 0) + { + cfRuleRecord.setBottomBorderModified(true); + } } public void setDiagonalBorderColor(short color) { borderFormatting.setDiagonalBorderColor(color); + if( color != 0) + { + cfRuleRecord.setBottomLeftTopRightBorderModified(true); + cfRuleRecord.setTopLeftBottomRightBorderModified(true); + } } public void setForwardDiagonalOn(boolean on) { borderFormatting.setForwardDiagonalOn(on); + if( on ) + { + cfRuleRecord.setBottomLeftTopRightBorderModified(on); + } } public void setLeftBorderColor(short color) { borderFormatting.setLeftBorderColor(color); + if( color != 0) + { + cfRuleRecord.setLeftBorderModified(true); + } } public void setRightBorderColor(short color) { borderFormatting.setRightBorderColor(color); + if( color != 0) + { + cfRuleRecord.setRightBorderModified(true); + } } public void setTopBorderColor(short color) { borderFormatting.setTopBorderColor(color); + if( color != 0) + { + cfRuleRecord.setTopBorderModified(true); + } } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java index 532133f93..6c798abcf 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java @@ -16,7 +16,6 @@ ==================================================================== */ package org.apache.poi.hssf.usermodel; -import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.CFHeaderRecord; import org.apache.poi.hssf.record.CFRuleRecord; import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate; @@ -50,52 +49,46 @@ import org.apache.poi.hssf.util.Region; * To create a new Conditional Formatting set use the following approach: * *
+ * 
+ * // Define a Conditional Formatting rule, which triggers formatting
+ * // when cell's value is greater or equal than 100.0 and
+ * // applies patternFormatting defined below.
+ * HSSFConditionalFormattingRule rule = sheet.createConditionalFormattingRule(
+ *     ComparisonOperator.GE, 
+ *     "100.0", // 1st formula 
+ *     null     // 2nd formula is not used for comparison operator GE
+ * );
+ * 
  * // Create pattern with red background
- * HSSFPatternFormatting patternFormatting = new HSSFPatternFormatting();
+ * HSSFPatternFormatting patternFmt = rule.cretePatternFormatting();
  * patternFormatting.setFillBackgroundColor(HSSFColor.RED.index);
  * 
+ * // Define a region containing first column
  * Region [] regions =
  * {
- *     // Define a region containing first column
  *     new Region(1,(short)1,-1,(short)1)
  * };
  *     
- * HSSFConditionalFormattingRule[] rules = 
- * {
- *     // Define a Conditional Formatting rule, which triggers formatting
- *     // when cell's value is greater or equal than 100.0 and
- *     // applies patternFormatting defined above.
- *         
- *     sheet.createConditionalFormattingRule(
- *             HSSFConditionalFormattingRule.COMPARISON_OPERATOR_GE, 
- *             "100.0", // 1st formula 
- *             null,    // 2nd formula is not used for comparison operator GE
- *             null,    // do not override Font Formatting
- *             null,    // do not override Border Formatting
- *             patternFormatting
- *     )
- * };
- *     
- * // Apply Conditional Formatting rules defined above to the regions  
- * sheet.addConditionalFormatting(regions, rules);
+ * // Apply Conditional Formatting rule defined above to the regions  
+ * sheet.addConditionalFormatting(regions, rule);
  * 
* * @author Dmitriy Kumshayev */ public final class HSSFConditionalFormatting { - private final HSSFWorkbook workbook; + private final HSSFWorkbook _workbook; private final CFRecordsAggregate cfAggregate; - HSSFConditionalFormatting(HSSFSheet sheet, CFRecordsAggregate cfAggregate) + HSSFConditionalFormatting(HSSFWorkbook workbook, CFRecordsAggregate cfAggregate) { - if(sheet == null) { - throw new IllegalArgumentException("sheet must not be null"); + if(workbook == null) { + throw new IllegalArgumentException("workbook must not be null"); } if(cfAggregate == null) { throw new IllegalArgumentException("cfAggregate must not be null"); } - workbook = sheet.workbook; + _workbook = workbook; this.cfAggregate = cfAggregate; } CFRecordsAggregate getCFRecordsAggregate() { @@ -141,7 +134,7 @@ public final class HSSFConditionalFormatting public HSSFConditionalFormattingRule getRule(int idx) { CFRuleRecord ruleRecord = cfAggregate.getRule(idx); - return new HSSFConditionalFormattingRule(workbook, ruleRecord); + return new HSSFConditionalFormattingRule(_workbook, ruleRecord); } /** diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java index 5d3436028..1d4100655 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java @@ -18,7 +18,6 @@ package org.apache.poi.hssf.usermodel; import org.apache.poi.hssf.model.FormulaParser; -import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.CFRuleRecord; import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator; import org.apache.poi.hssf.record.cf.BorderFormatting; @@ -46,27 +45,30 @@ public final class HSSFConditionalFormattingRule workbook = pWorkbook; cfRuleRecord = pRuleRecord; } - HSSFConditionalFormattingRule(HSSFWorkbook pWorkbook, CFRuleRecord pRuleRecord, - HSSFFontFormatting fontFmt, HSSFBorderFormatting bordFmt, HSSFPatternFormatting patternFmt) { - this(pWorkbook, pRuleRecord); - setFontFormatting(fontFmt); - setBorderFormatting(bordFmt); - setPatternFormatting(patternFmt); - } CFRuleRecord getCfRuleRecord() { return cfRuleRecord; } - - /** - * @param fontFmt pass null to signify 'font unchanged' - */ - public void setFontFormatting(HSSFFontFormatting fontFmt) + private HSSFFontFormatting getFontFormatting(boolean create) { - FontFormatting block = fontFmt==null ? null : fontFmt.getFontFormattingBlock(); - cfRuleRecord.setFontFormatting(block); + FontFormatting fontFormatting = cfRuleRecord.getFontFormatting(); + if ( fontFormatting != null) + { + cfRuleRecord.setFontFormatting(fontFormatting); + return new HSSFFontFormatting(cfRuleRecord); + } + else if( create ) + { + fontFormatting = new FontFormatting(); + cfRuleRecord.setFontFormatting(fontFormatting); + return new HSSFFontFormatting(cfRuleRecord); + } + else + { + return null; + } } /** @@ -74,50 +76,89 @@ public final class HSSFConditionalFormattingRule */ public HSSFFontFormatting getFontFormatting() { - FontFormatting ff = cfRuleRecord.getFontFormatting(); - if ( ff == null ) { - return null; - } - return new HSSFFontFormatting(ff); + return getFontFormatting(false); + } + /** + * create a new font formatting structure if it does not exist, + * otherwise just return existing object. + * @return - font formatting object, never returns null. + */ + public HSSFFontFormatting createFontFormatting() + { + return getFontFormatting(true); } - /** - * @param borderFmt pass null to signify 'border unchanged' - */ - public void setBorderFormatting(HSSFBorderFormatting borderFmt) + private HSSFBorderFormatting getBorderFormatting(boolean create) { - BorderFormatting block = borderFmt==null ? null : borderFmt.getBorderFormattingBlock(); - cfRuleRecord.setBorderFormatting(block); + BorderFormatting borderFormatting = cfRuleRecord.getBorderFormatting(); + if ( borderFormatting != null) + { + cfRuleRecord.setBorderFormatting(borderFormatting); + return new HSSFBorderFormatting(cfRuleRecord); + } + else if( create ) + { + borderFormatting = new BorderFormatting(); + cfRuleRecord.setBorderFormatting(borderFormatting); + return new HSSFBorderFormatting(cfRuleRecord); + } + else + { + return null; + } } /** * @return - border formatting object if defined, null otherwise */ public HSSFBorderFormatting getBorderFormatting() { - BorderFormatting bf = cfRuleRecord.getBorderFormatting(); - if ( bf == null ) { - return null; - } - return new HSSFBorderFormatting(bf); + return getBorderFormatting(false); } /** - * @param patternFmt pass null to signify 'pattern unchanged' + * create a new border formatting structure if it does not exist, + * otherwise just return existing object. + * @return - border formatting object, never returns null. */ - public void setPatternFormatting(HSSFPatternFormatting patternFmt) + public HSSFBorderFormatting createBorderFormatting() { - PatternFormatting block = patternFmt==null ? null : patternFmt.getPatternFormattingBlock(); - cfRuleRecord.setPatternFormatting(block); + return getBorderFormatting(true); } + + private HSSFPatternFormatting getPatternFormatting(boolean create) + { + PatternFormatting patternFormatting = cfRuleRecord.getPatternFormatting(); + if ( patternFormatting != null) + { + cfRuleRecord.setPatternFormatting(patternFormatting); + return new HSSFPatternFormatting(cfRuleRecord); + } + else if( create ) + { + patternFormatting = new PatternFormatting(); + cfRuleRecord.setPatternFormatting(patternFormatting); + return new HSSFPatternFormatting(cfRuleRecord); + } + else + { + return null; + } + } + /** * @return - pattern formatting object if defined, null otherwise */ public HSSFPatternFormatting getPatternFormatting() { - PatternFormatting pf = cfRuleRecord.getPatternFormatting(); - if ( pf == null ) { - return null; - } - return new HSSFPatternFormatting(pf); + return getPatternFormatting(false); + } + /** + * create a new pattern formatting structure if it does not exist, + * otherwise just return existing object. + * @return - pattern formatting object, never returns null. + */ + public HSSFPatternFormatting createPatternFormatting() + { + return getPatternFormatting(true); } public String getFormula1() diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java index a701eb63a..774bc1ea4 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java @@ -17,6 +17,7 @@ package org.apache.poi.hssf.usermodel; +import org.apache.poi.hssf.record.CFRuleRecord; import org.apache.poi.hssf.record.cf.FontFormatting; /** * High level representation for Font Formatting component @@ -33,28 +34,23 @@ public final class HSSFFontFormatting public final static short SS_SUPER = FontFormatting.SS_SUPER; /** Escapement type - Subscript */ public final static short SS_SUB = FontFormatting.SS_SUB; - + /** 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 */ 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; - public HSSFFontFormatting() + protected HSSFFontFormatting(CFRuleRecord cfRuleRecord) { - fontFormatting = new FontFormatting(); - } - - protected HSSFFontFormatting(FontFormatting ff) - { - fontFormatting = ff; + this.fontFormatting = cfRuleRecord.getFontFormatting(); } protected FontFormatting getFontFormattingBlock() diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java index b94d19601..cb1ae9365 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java @@ -17,6 +17,7 @@ package org.apache.poi.hssf.usermodel; +import org.apache.poi.hssf.record.CFRuleRecord; import org.apache.poi.hssf.record.cf.PatternFormatting; /** @@ -66,15 +67,13 @@ public class HSSFPatternFormatting /** Least Dots */ public final static short LEAST_DOTS = PatternFormatting.LEAST_DOTS; - private PatternFormatting patternFormatting; + private final CFRuleRecord cfRuleRecord; + private final PatternFormatting patternFormatting; - public HSSFPatternFormatting() + protected HSSFPatternFormatting(CFRuleRecord cfRuleRecord) { - patternFormatting = new PatternFormatting(); - } - protected HSSFPatternFormatting(PatternFormatting patternFormatting) - { - this.patternFormatting = patternFormatting; + this.cfRuleRecord = cfRuleRecord; + this.patternFormatting = cfRuleRecord.getPatternFormatting(); } protected PatternFormatting getPatternFormattingBlock() @@ -116,6 +115,10 @@ public class HSSFPatternFormatting public void setFillBackgroundColor(short bg) { patternFormatting.setFillBackgroundColor(bg); + if( bg != 0) + { + cfRuleRecord.setPatternBackgroundColorModified(true); + } } /** @@ -125,6 +128,10 @@ public class HSSFPatternFormatting public void setFillForegroundColor(short fg) { patternFormatting.setFillForegroundColor(fg); + if( fg != 0) + { + cfRuleRecord.setPatternColorModified(true); + } } /** @@ -134,5 +141,9 @@ public class HSSFPatternFormatting public void setFillPattern(short fp) { patternFormatting.setFillPattern(fp); + if( fp != 0) + { + cfRuleRecord.setPatternStyleModified(true); + } } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index 3558618e7..b6d8d5723 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -17,35 +17,33 @@ package org.apache.poi.hssf.usermodel; -import org.apache.poi.ddf.EscherRecord; -import org.apache.poi.hssf.model.FormulaParser; -import org.apache.poi.hssf.model.Sheet; -import org.apache.poi.hssf.model.Workbook; -import org.apache.poi.hssf.record.*; -import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate; -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.ReferencePtg; -import org.apache.poi.hssf.util.HSSFCellRangeAddress; -import org.apache.poi.hssf.util.HSSFDataValidation; -import org.apache.poi.hssf.util.Region; -import org.apache.poi.hssf.util.PaneInformation; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - +import java.awt.font.FontRenderContext; +import java.awt.font.TextAttribute; +import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; import java.io.PrintWriter; +import java.text.AttributedString; +import java.text.DecimalFormat; +import java.text.NumberFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Stack; import java.util.TreeMap; -import java.text.AttributedString; -import java.text.NumberFormat; -import java.text.DecimalFormat; -import java.awt.font.TextLayout; -import java.awt.font.FontRenderContext; -import java.awt.font.TextAttribute; -import java.awt.geom.AffineTransform; +import org.apache.poi.ddf.EscherRecord; +import org.apache.poi.hssf.model.FormulaParser; +import org.apache.poi.hssf.model.Sheet; +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.*; +import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.hssf.record.formula.ReferencePtg; +import org.apache.poi.hssf.util.HSSFCellRangeAddress; +import org.apache.poi.hssf.util.HSSFDataValidation; +import org.apache.poi.hssf.util.PaneInformation; +import org.apache.poi.hssf.util.Region; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; /** * High level representation of a worksheet. @@ -1839,135 +1837,7 @@ public final class HSSFSheet { return null; } - - /** - * A factory method allowing to create a conditional formatting rule - * with a cell comparison operator and - * formatting rules such as font format, border format and pattern format - * - * @param comparisonOperation - a constant value from - * {@link HSSFConditionalFormattingRule.ComparisonOperator}:

- *

    - *
  • BETWEEN
  • - *
  • NOT_BETWEEN
  • - *
  • EQUAL
  • - *
  • NOT_EQUAL
  • - *
  • GT
  • - *
  • LT
  • - *
  • GE
  • - *
  • LE
  • - *
- *

- * @param formula1 - formula for the valued, compared with the cell - * @param formula2 - second formula (only used with - * {@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_BETWEEN}) and - * {@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_BETWEEN} operations) - * @param fontFmt - font formatting rules (may be null) - * @param bordFmt - border formatting rules (may be null) - * @param patternFmt - pattern formatting rules (may be null) - */ - public HSSFConditionalFormattingRule createConditionalFormattingRule( - byte comparisonOperation, - String formula1, - String formula2, - HSSFFontFormatting fontFmt, - HSSFBorderFormatting bordFmt, - HSSFPatternFormatting patternFmt) { - - CFRuleRecord rr = CFRuleRecord.create(workbook, comparisonOperation, formula1, formula2); - return new HSSFConditionalFormattingRule(workbook, rr, fontFmt, bordFmt, patternFmt); - } - - /** - * A factory method allowing to create a conditional formatting rule with a formula - * and formatting rules such as font format, border format and pattern format.
- * - * The formatting rules are applied by Excel when the value of the formula not equal to 0. - * - * @param formula - formula for the valued, compared with the cell - * @param fontFmt - font formatting rules (may be null) - * @param bordFmt - border formatting rules (may be null) - * @param patternFmt - pattern formatting rules (may be null) - */ - public HSSFConditionalFormattingRule createConditionalFormattingRule( - String formula, - HSSFFontFormatting fontFmt, - HSSFBorderFormatting bordFmt, - HSSFPatternFormatting patternFmt) { - CFRuleRecord rr = CFRuleRecord.create(workbook, formula); - return new HSSFConditionalFormattingRule(workbook, rr, fontFmt, bordFmt, patternFmt); - } - - /** - * Adds a copy of HSSFConditionalFormatting object to the sheet - *

This method could be used to copy HSSFConditionalFormatting object - * from one sheet to another. For example: - *

-      * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
-      * newSheet.addConditionalFormatting(cf);
-      * 
- * - * @param cf HSSFConditionalFormatting object - * @return index of the new Conditional Formatting object - */ - public int addConditionalFormatting( HSSFConditionalFormatting cf ) { - CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate(); - - return sheet.addConditionalFormatting(cfraClone); - } - - /** - * Allows to add a new Conditional Formatting set to the sheet. - * - * @param regions - list of rectangular regions to apply conditional formatting rules - * @param hcfRules - set of up to three conditional formatting rules - * - * @return index of the newly created Conditional Formatting object - */ - - public int addConditionalFormatting(Region [] regions, HSSFConditionalFormattingRule [] hcfRules) { - if (regions == null) { - throw new IllegalArgumentException("regions must not be null"); - } - if (hcfRules == null) { - throw new IllegalArgumentException("hcfRules must not be null"); - } - - CFRuleRecord[] rules = new CFRuleRecord[hcfRules.length]; - for (int i = 0; i != hcfRules.length; i++) { - rules[i] = hcfRules[i].getCfRuleRecord(); - } - CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules); - return sheet.addConditionalFormatting(cfra); - } - - /** - * gets Conditional Formatting object at a particular index - * - * @param index - * of the Conditional Formatting object to fetch - * @return Conditional Formatting object - */ - public HSSFConditionalFormatting getConditionalFormattingAt(int index) { - CFRecordsAggregate cf = sheet.getCFRecordsAggregateAt(index); - if (cf == null) { - return null; - } - return new HSSFConditionalFormatting(this,cf); - } - - /** - * @return number of Conditional Formatting objects of the sheet - */ - public int getNumConditionalFormattings() { - return sheet.getNumConditionalFormattings(); - } - - /** - * removes a Conditional Formatting object by index - * @param index of a Conditional Formatting object to remove - */ - public void removeConditionalFormatting(int index) { - sheet.removeConditionalFormatting(index); + public HSSFSheetConditionalFormatting getSheetConditionalFormatting() { + return new HSSFSheetConditionalFormatting(workbook, sheet); } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java new file mode 100644 index 000000000..6862a87ea --- /dev/null +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java @@ -0,0 +1,196 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.usermodel; + +import org.apache.poi.hssf.model.Sheet; +import org.apache.poi.hssf.record.CFRuleRecord; +import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate; +import org.apache.poi.hssf.util.Region; + +/** + * The 'Conditional Formatting' facet of HSSFSheet + * + * @author Dmitriy Kumshayev + */ +public final class HSSFSheetConditionalFormatting { + + private final HSSFWorkbook _workbook; + private final Sheet _sheet; + + /* package */ HSSFSheetConditionalFormatting(HSSFWorkbook workbook, Sheet sheet) { + _workbook = workbook; + _sheet = sheet; + } + + /** + * A factory method allowing to create a conditional formatting rule + * with a cell comparison operator + * + * @param comparisonOperation - a constant value from + * {@link HSSFConditionalFormattingRule.ComparisonOperator}:

+ *

    + *
  • BETWEEN
  • + *
  • NOT_BETWEEN
  • + *
  • EQUAL
  • + *
  • NOT_EQUAL
  • + *
  • GT
  • + *
  • LT
  • + *
  • GE
  • + *
  • LE
  • + *
+ *

+ * @param formula1 - formula for the valued, compared with the cell + * @param formula2 - second formula (only used with + * {@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_BETWEEN}) and + * {@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_BETWEEN} operations) + */ + public HSSFConditionalFormattingRule createConditionalFormattingRule( + byte comparisonOperation, + String formula1, + String formula2) { + + HSSFWorkbook wb = _workbook; + CFRuleRecord rr = CFRuleRecord.create(wb, comparisonOperation, formula1, formula2); + return new HSSFConditionalFormattingRule(wb, rr); + } + + /** + * A factory method allowing to create a conditional formatting rule with a formula.
+ * + * The formatting rules are applied by Excel when the value of the formula not equal to 0. + * + * @param formula - formula for the valued, compared with the cell + */ + public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) { + HSSFWorkbook wb = _workbook; + CFRuleRecord rr = CFRuleRecord.create(wb, formula); + return new HSSFConditionalFormattingRule(wb, rr); + } + + /** + * Adds a copy of HSSFConditionalFormatting object to the sheet + *

This method could be used to copy HSSFConditionalFormatting object + * from one sheet to another. For example: + *

+	 * HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
+	 * newSheet.addConditionalFormatting(cf);
+	 * 
+ * + * @param cf HSSFConditionalFormatting object + * @return index of the new Conditional Formatting object + */ + public int addConditionalFormatting( HSSFConditionalFormatting cf ) { + CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate(); + + return _sheet.addConditionalFormatting(cfraClone); + } + + /** + * Allows to add a new Conditional Formatting set to the sheet. + * + * @param regions - list of rectangular regions to apply conditional formatting rules + * @param cfRules - set of up to three conditional formatting rules + * + * @return index of the newly created Conditional Formatting object + */ + + public int addConditionalFormatting(Region[] regions, HSSFConditionalFormattingRule[] cfRules) { + if (regions == null) { + throw new IllegalArgumentException("regions must not be null"); + } + if (cfRules == null) { + throw new IllegalArgumentException("cfRules must not be null"); + } + if (cfRules.length == 0) { + throw new IllegalArgumentException("cfRules must not be empty"); + } + if (cfRules.length > 3) { + throw new IllegalArgumentException("Number of rules must not exceed 3"); + } + + CFRuleRecord[] rules = new CFRuleRecord[cfRules.length]; + for (int i = 0; i != cfRules.length; i++) { + rules[i] = cfRules[i].getCfRuleRecord(); + } + CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules); + return _sheet.addConditionalFormatting(cfra); + } + + public int addConditionalFormatting(Region[] regions, + HSSFConditionalFormattingRule rule1) + { + return addConditionalFormatting(regions, + new HSSFConditionalFormattingRule[] + { + rule1 + }); + } + + public int addConditionalFormatting(Region[] regions, + HSSFConditionalFormattingRule rule1, + HSSFConditionalFormattingRule rule2) + { + return addConditionalFormatting(regions, + new HSSFConditionalFormattingRule[] + { + rule1, rule2 + }); + } + + public int addConditionalFormatting(Region[] regions, + HSSFConditionalFormattingRule rule1, + HSSFConditionalFormattingRule rule2, + HSSFConditionalFormattingRule rule3) + { + return addConditionalFormatting(regions, + new HSSFConditionalFormattingRule[] + { + rule1, rule2, rule3 + }); + } + + /** + * gets Conditional Formatting object at a particular index + * + * @param index + * of the Conditional Formatting object to fetch + * @return Conditional Formatting object + */ + public HSSFConditionalFormatting getConditionalFormattingAt(int index) { + CFRecordsAggregate cf = _sheet.getCFRecordsAggregateAt(index); + if (cf == null) { + return null; + } + return new HSSFConditionalFormatting(_workbook, cf); + } + + /** + * @return number of Conditional Formatting objects of the sheet + */ + public int getNumConditionalFormattings() { + return _sheet.getNumConditionalFormattings(); + } + + /** + * removes a Conditional Formatting object by index + * @param index of a Conditional Formatting object to remove + */ + public void removeConditionalFormatting(int index) { + _sheet.removeConditionalFormatting(index); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java index ebc41bafe..afc44e704 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java @@ -293,7 +293,8 @@ public final class TestCFRuleRecord extends TestCase int flags = LittleEndian.getInt(data, 10); assertEquals("unused flags should be 111", 0x00380000, flags & 0x00380000); assertEquals("undocumented flags should be 0000", 0, flags & 0x03C00000); // Otherwise Excel gets unhappy - assertEquals(0xA03FFFFF, flags); + // check all remaining flag bits (some are not well understood yet) + assertEquals(0x203FFFFF, flags); } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java index 7ce8272d0..405f78106 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFConditionalFormatting.java @@ -34,22 +34,26 @@ public final class TestHSSFConditionalFormatting extends TestCase HSSFSheet sheet = workbook.createSheet(); String formula = "7"; - HSSFFontFormatting fontFmt = new HSSFFontFormatting(); + HSSFSheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting(); + + HSSFConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(formula); + HSSFFontFormatting fontFmt = rule1.createFontFormatting(); fontFmt.setFontStyle(true, false); - HSSFBorderFormatting bordFmt = new HSSFBorderFormatting(); + 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 = new HSSFPatternFormatting(); - patternFmt.setFillBackgroundColor(HSSFColor.RED.index); + HSSFPatternFormatting patternFmt = rule1.createPatternFormatting(); + patternFmt.setFillBackgroundColor(HSSFColor.YELLOW.index); + + HSSFConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2"); HSSFConditionalFormattingRule [] cfRules = { - sheet.createConditionalFormattingRule(formula, fontFmt, bordFmt, patternFmt), - sheet.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2", fontFmt, bordFmt, patternFmt) + rule1, rule2 }; short col = 1; @@ -58,14 +62,14 @@ public final class TestHSSFConditionalFormatting extends TestCase new Region(0,col,65535,col) }; - sheet.addConditionalFormatting(regions, cfRules); - sheet.addConditionalFormatting(regions, cfRules); + sheetCF.addConditionalFormatting(regions, cfRules); + sheetCF.addConditionalFormatting(regions, cfRules); // Verification - assertEquals(2, sheet.getNumConditionalFormattings()); - sheet.removeConditionalFormatting(1); - assertEquals(1, sheet.getNumConditionalFormattings()); - HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(0); + assertEquals(2, sheetCF.getNumConditionalFormattings()); + sheetCF.removeConditionalFormatting(1); + assertEquals(1, sheetCF.getNumConditionalFormattings()); + HSSFConditionalFormatting cf = sheetCF.getConditionalFormattingAt(0); assertNotNull(cf); regions = cf.getFormattingRegions(); @@ -79,7 +83,7 @@ public final class TestHSSFConditionalFormatting extends TestCase assertEquals(2, cf.getNumberOfRules()); - HSSFConditionalFormattingRule rule1 = cf.getRule(0); + rule1 = cf.getRule(0); assertEquals("7",rule1.getFormula1()); assertNull(rule1.getFormula2()); @@ -98,11 +102,10 @@ public final class TestHSSFConditionalFormatting extends TestCase HSSFPatternFormatting r1pf = rule1.getPatternFormatting(); assertNotNull(r1pf); - assertEquals(HSSFColor.RED.index,r1pf.getFillBackgroundColor()); + assertEquals(HSSFColor.YELLOW.index,r1pf.getFillBackgroundColor()); - HSSFConditionalFormattingRule rule2 = cf.getRule(1); + rule2 = cf.getRule(1); assertEquals("2",rule2.getFormula2()); assertEquals("1",rule2.getFormula1()); } - }