From e33dbf93a0ba2c109184832e19028c25444de6f1 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 19 Mar 2008 12:28:56 +0000 Subject: [PATCH] Patch from Dmitriy from bug #30311 - Support for conditional formatting records git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@638812 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 1 + src/documentation/content/xdocs/status.xml | 1 + src/java/org/apache/poi/hssf/model/Sheet.java | 73 ++ .../poi/hssf/record/CFHeaderRecord.java | 223 ++++++ .../apache/poi/hssf/record/CFRuleRecord.java | 657 ++++++++++++++++++ .../apache/poi/hssf/record/RecordFactory.java | 2 + .../poi/hssf/record/SharedFormulaRecord.java | 42 +- .../record/aggregates/CFRecordsAggregate.java | 224 ++++++ .../poi/hssf/record/cf/BorderFormatting.java | 560 +++++++++++++++ .../apache/poi/hssf/record/cf/CellRange.java | 259 +++++++ .../poi/hssf/record/cf/FontFormatting.java | 591 ++++++++++++++++ .../poi/hssf/record/cf/PatternFormatting.java | 206 ++++++ .../hssf/usermodel/HSSFBorderFormatting.java | 128 ++++ .../usermodel/HSSFConditionalFormatting.java | 201 ++++++ .../HSSFConditionalFormattingRule.java | 248 +++++++ .../hssf/usermodel/HSSFFontFormatting.java | 456 ++++++++++++ .../hssf/usermodel/HSSFPatternFormatting.java | 134 ++++ .../apache/poi/hssf/usermodel/HSSFSheet.java | 158 +++++ .../poi/hssf/record/TestCFHeaderRecord.java | 145 ++++ .../poi/hssf/record/TestCFRuleRecord.java | 296 ++++++++ .../aggregates/TestCFRecordsAggregate.java | 111 +++ .../poi/hssf/record/cf/TestCellRange.java | 139 ++++ 22 files changed, 4841 insertions(+), 14 deletions(-) create mode 100644 src/java/org/apache/poi/hssf/record/CFHeaderRecord.java create mode 100644 src/java/org/apache/poi/hssf/record/CFRuleRecord.java create mode 100644 src/java/org/apache/poi/hssf/record/aggregates/CFRecordsAggregate.java create mode 100644 src/java/org/apache/poi/hssf/record/cf/BorderFormatting.java create mode 100644 src/java/org/apache/poi/hssf/record/cf/CellRange.java create mode 100644 src/java/org/apache/poi/hssf/record/cf/FontFormatting.java create mode 100644 src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java create mode 100644 src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java create mode 100644 src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java create mode 100644 src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java create mode 100644 src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java create mode 100644 src/java/org/apache/poi/hssf/usermodel/HSSFPatternFormatting.java create mode 100644 src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java create mode 100644 src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java create mode 100644 src/testcases/org/apache/poi/hssf/record/aggregates/TestCFRecordsAggregate.java create mode 100644 src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index eab4f64638..c2f3d50e13 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -36,6 +36,7 @@ + 30311 - Initial support for Conditional Formatting 44609 - Handle leading spaces in formulas, such as '= 4' 44608 - Support for PercentPtg in the formula evaluator 44606 - Support calculated string values for evaluated formulas diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index a6467d5164..e0468b2f87 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -33,6 +33,7 @@ + 30311 - Initial support for Conditional Formatting 44609 - Handle leading spaces in formulas, such as '= 4' 44608 - Support for PercentPtg in the formula evaluator 44606 - Support calculated string values for evaluated formulas diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java index f3f7deba07..451cde7579 100644 --- a/src/java/org/apache/poi/hssf/model/Sheet.java +++ b/src/java/org/apache/poi/hssf/model/Sheet.java @@ -24,6 +24,7 @@ import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate; +import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate; import org.apache.poi.hssf.record.formula.Ptg; import org.apache.poi.hssf.util.PaneInformation; @@ -96,6 +97,7 @@ public class Sheet implements Model protected ObjectProtectRecord objprotect = null; protected ScenarioProtectRecord scenprotect = null; protected PasswordRecord password = null; + protected List condFormatting = new ArrayList();; /** Add an UncalcedRecord if not true indicating formulas have not been calculated */ protected boolean uncalced = false; @@ -184,6 +186,17 @@ public class Sheet implements Model retval.merged = ( MergeCellsRecord ) rec; retval.numMergedRegions += retval.merged.getNumAreas(); } + else if ( rec.getSid() == CFHeaderRecord.sid ) + { + CFRecordsAggregate cfAgg = CFRecordsAggregate.createCFAggregate(recs, k); + retval.condFormatting.add(cfAgg); + rec = cfAgg; + } + else if ( rec.getSid() == CFRuleRecord.sid ) + { + // Skip it since it is processed by CFRecordsAggregate + rec = null; + } else if (rec.getSid() == ColumnInfoRecord.sid) { ColumnInfoRecord col = (ColumnInfoRecord)rec; @@ -604,6 +617,66 @@ public class Sheet implements Model { return numMergedRegions; } + // Find correct position to add new CF record + private int findConditionalFormattingPosition() + { + // This is default. + // If the algorithm does not find the right position, + // this one will be used (this is a position before EOF record) + int index = records.size()-2; + + for( int i=index; i>=0; i-- ) + { + Record rec = (Record)records.get(i); + short sid = rec.getSid(); + + // CFRecordsAggregate records already exist, just add to the end + if (rec instanceof CFRecordsAggregate) { return i+1; } + + if( sid == (short)0x00ef ) { return i+1; }// PHONETICPR + if( sid == (short)0x015f ) { return i+1; }// LABELRANGES + if( sid == MergeCellsRecord.sid ) { return i+1; } + if( sid == (short)0x0099 ) { return i+1; }// STANDARDWIDTH + if( sid == SelectionRecord.sid ) { return i+1; } + if( sid == PaneRecord.sid ) { return i+1; } + if( sid == SCLRecord.sid ) { return i+1; } + if( sid == WindowTwoRecord.sid ) { return i+1; } + } + + return index; + } + + public int addConditionalFormatting(CFRecordsAggregate cfAggregate) + { + int index = findConditionalFormattingPosition(); + records.add(index, cfAggregate); + condFormatting.add(cfAggregate); + return condFormatting.size()-1; + } + + public void removeConditionalFormatting(int index) + { + if (index >= 0 && index <= condFormatting.size()-1 ) + { + CFRecordsAggregate cfAggregate = getCFRecordsAggregateAt(index); + records.remove(cfAggregate); + condFormatting.remove(index); + } + } + + public CFRecordsAggregate getCFRecordsAggregateAt(int index) + { + if (index >= 0 && index <= condFormatting.size()-1 ) + { + return (CFRecordsAggregate) condFormatting.get(index); + } + return null; + } + + public int getNumConditionalFormattings() + { + return condFormatting.size(); + } /** * Returns the number of low level binary records in this sheet. This adjusts things for the so called diff --git a/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java b/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java new file mode 100644 index 0000000000..00a8646b4f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java @@ -0,0 +1,223 @@ +/* ==================================================================== + 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. +==================================================================== */ + +/* + * ConditionalFormattingHeaderRecord.java + * + * Created on January 17, 2008, 3:05 AM + */ +package org.apache.poi.hssf.record; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.poi.hssf.record.cf.CellRange; +import org.apache.poi.util.LittleEndian; + +/** + * Conditional Formatting Header record (CFHEADER) + * + * @author Dmitriy Kumshayev + */ +public class CFHeaderRecord extends Record +{ + public static final short sid = 0x1B0; + + private int field_1_numcf; + private int field_2_need_recalculation; + private CellRange field_3_enclosing_cell_range; + private List field_4_cell_ranges; + + /** Creates new CFHeaderRecord */ + public CFHeaderRecord() + { + field_4_cell_ranges = new ArrayList(5); + } + + public CFHeaderRecord(RecordInputStream in) + { + super(in); + } + + protected void fillFields(RecordInputStream in) + { + field_1_numcf = in.readShort(); + field_2_need_recalculation = in.readShort(); + field_3_enclosing_cell_range = new CellRange(in.readShort(),in.readShort(),in.readShort(),in.readShort()); + int numCellRanges = in.readShort(); + field_4_cell_ranges = new ArrayList(5); + for( int i=0; i0) + { + buffer.append(" .cfranges=["); + for( int i=0; i