Merged revisions 642878-642946 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk ........ r642878 | josh | 2008-03-31 06:10:35 +0100 (Mon, 31 Mar 2008) | 1 line More work on Conditional Formatting (bug 30311) junit and fixes from Dmitriy. Some other clean-up. ........ r642880 | josh | 2008-03-31 06:19:00 +0100 (Mon, 31 Mar 2008) | 1 line removed incorrect test case methods ........ r642891 | josh | 2008-03-31 06:56:11 +0100 (Mon, 31 Mar 2008) | 1 line silenced noisy tests ........ r642904 | josh | 2008-03-31 07:55:04 +0100 (Mon, 31 Mar 2008) | 1 line changes/status for #44675, #44695, #44691 ........ r642946 | yegor | 2008-03-31 10:58:27 +0100 (Mon, 31 Mar 2008) | 1 line Implement Sheet.removeShape(Shape shape) in HSLF ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@645088 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a937f6c3d2
commit
641ab5bb06
@ -26,6 +26,7 @@
|
||||
<!-- in strict alphabetical order -->
|
||||
<person id="AO" name="Andrew C. Oliver" email="acoliver2@users.sourceforge.net"/>
|
||||
<person id="GJS" name="Glen Stampoultzis" email="user@poi.apache.org"/>
|
||||
<person id="JM" name="Josh Micich" email="josh@apache.org"/>
|
||||
<person id="MJ" name="Marc Johnson" email="mjohnson@apache.org"/>
|
||||
<person id="NKB" name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
|
||||
<person id="NB" name="Nick Burch" email="nick@torchbox.com"/>
|
||||
@ -36,6 +37,9 @@
|
||||
|
||||
<!-- Don't forget to update status.xml too! -->
|
||||
<release version="3.0.3-beta1" date="2008-04-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">Implement Sheet.removeShape(Shape shape) in HSLF</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Various fixes: Recognising var-arg built-in functions #44675, ExternalNameRecord serialisation bug #44695, PMT() bug #44691</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Move the Formula Evaluator code out of scratchpad</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Move the missing record aware eventusermodel code out of scratchpad</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">44652 / 44603 - Improved handling of Pictures in Word Documents</action>
|
||||
|
@ -22,6 +22,7 @@
|
||||
<!-- in strict alphabetical order -->
|
||||
<person id="AO" name="Andrew C. Oliver" email="acoliver2@users.sourceforge.net"/>
|
||||
<person id="GJS" name="Glen Stampoultzis" email="user@poi.apache.org"/>
|
||||
<person id="JM" name="Josh Micich" email="josh@apache.org"/>
|
||||
<person id="MJ" name="Marc Johnson" email="mjohnson@apache.org"/>
|
||||
<person id="NKB" name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
|
||||
<person id="NB" name="Nick Burch" email="nick@torchbox.com"/>
|
||||
@ -33,6 +34,9 @@
|
||||
<!-- Don't forget to update changes.xml too! -->
|
||||
<changes>
|
||||
<release version="3.0.3-beta1" date="2008-04-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">Implement Sheet.removeShape(Shape shape) in HSLF</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Various fixes: Recognising var-arg built-in functions #44675, ExternalNameRecord serialisation bug #44695, PMT() bug #44691</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Move the Formula Evaluator code out of scratchpad</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Move the missing record aware eventusermodel code out of scratchpad</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">44652 / 44603 - Improved handling of Pictures in Word Documents</action>
|
||||
|
@ -28,8 +28,6 @@ import org.apache.poi.hssf.record.formula.*;
|
||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
|
||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class parses a formula string into a List of tokens in RPN order.
|
||||
* Inspired by
|
||||
@ -48,11 +46,11 @@ import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
||||
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
|
||||
*/
|
||||
public final class FormulaParser {
|
||||
|
||||
|
||||
/**
|
||||
* Specific exception thrown when a supplied formula does not parse properly.<br/>
|
||||
* Primarily used by test cases when testing for specific parsing exceptions.</p>
|
||||
*
|
||||
*
|
||||
*/
|
||||
static final class FormulaParseException extends RuntimeException {
|
||||
// This class was given package scope until it would become clear that it is useful to
|
||||
|
@ -15,18 +15,10 @@
|
||||
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.hssf.util.Region;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -34,19 +26,27 @@ import org.apache.poi.util.LittleEndian;
|
||||
*
|
||||
* @author Dmitriy Kumshayev
|
||||
*/
|
||||
public class CFHeaderRecord extends Record
|
||||
public final class CFHeaderRecord extends Record
|
||||
{
|
||||
public static final short sid = 0x1B0;
|
||||
|
||||
private static final CellRange[] EMPTY_CELL_RANGE_ARRAY = { };
|
||||
|
||||
private int field_1_numcf;
|
||||
private int field_2_need_recalculation;
|
||||
private CellRange field_3_enclosing_cell_range;
|
||||
private List field_4_cell_ranges;
|
||||
private CellRange[] field_4_cell_ranges;
|
||||
|
||||
/** Creates new CFHeaderRecord */
|
||||
public CFHeaderRecord()
|
||||
{
|
||||
field_4_cell_ranges = new ArrayList(5);
|
||||
field_4_cell_ranges = EMPTY_CELL_RANGE_ARRAY;
|
||||
}
|
||||
public CFHeaderRecord(Region[] regions)
|
||||
{
|
||||
CellRange[] unmergedRanges = CellRange.convertRegionsToCellRanges(regions);
|
||||
CellRange[] mergeCellRanges = CellRange.mergeCellRanges(unmergedRanges);
|
||||
setCellRanges(mergeCellRanges);
|
||||
}
|
||||
|
||||
public CFHeaderRecord(RecordInputStream in)
|
||||
@ -60,11 +60,12 @@ public class CFHeaderRecord extends Record
|
||||
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);
|
||||
CellRange[] crs = new CellRange[numCellRanges];
|
||||
for( int i=0; i<numCellRanges; i++)
|
||||
{
|
||||
field_4_cell_ranges.add(new CellRange(in.readShort(),in.readShort(),in.readShort(),in.readShort()));
|
||||
crs[i] = new CellRange(in.readShort(),in.readShort(),in.readShort(),in.readShort());
|
||||
}
|
||||
field_4_cell_ranges = crs;
|
||||
}
|
||||
|
||||
public int getNumberOfConditionalFormats()
|
||||
@ -101,28 +102,24 @@ public class CFHeaderRecord extends Record
|
||||
* modify the enclosing cell range accordingly.
|
||||
* @param List cellRanges - list of CellRange objects
|
||||
*/
|
||||
public void setCellRanges( List cellRanges )
|
||||
public void setCellRanges(CellRange[] cellRanges)
|
||||
{
|
||||
field_4_cell_ranges.clear();
|
||||
if(cellRanges!=null)
|
||||
if(cellRanges == null)
|
||||
{
|
||||
field_3_enclosing_cell_range=null;
|
||||
for( int i=0; i<cellRanges.size(); i++)
|
||||
{
|
||||
field_4_cell_ranges.add(cellRanges.get(i));
|
||||
recalculateEnclosingRange((CellRange)cellRanges.get(i));
|
||||
}
|
||||
throw new IllegalArgumentException("cellRanges must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
private void recalculateEnclosingRange(CellRange cellRange)
|
||||
{
|
||||
field_3_enclosing_cell_range = cellRange.createEnclosingCellRange(field_3_enclosing_cell_range);
|
||||
field_4_cell_ranges = (CellRange[]) cellRanges.clone();
|
||||
CellRange enclosingRange = null;
|
||||
for (int i = 0; i < cellRanges.length; i++)
|
||||
{
|
||||
enclosingRange = cellRanges[i].createEnclosingCellRange(enclosingRange);
|
||||
}
|
||||
field_3_enclosing_cell_range=enclosingRange;
|
||||
}
|
||||
|
||||
public List getCellRanges()
|
||||
public CellRange[] getCellRanges()
|
||||
{
|
||||
return field_4_cell_ranges;
|
||||
return (CellRange[]) field_4_cell_ranges.clone();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
@ -130,16 +127,16 @@ public class CFHeaderRecord extends Record
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append("[CFHEADER]\n");
|
||||
buffer.append(" .id = ").append(Integer.toHexString(sid)).append("\n");
|
||||
buffer.append(" .numCF = ").append(getNumberOfConditionalFormats()).append("\n");
|
||||
buffer.append(" .needRecalc = ").append(getNeedRecalculation()).append("\n");
|
||||
buffer.append(" .enclosingCellRange= ").append(getEnclosingCellRange()).append("\n");
|
||||
if( field_4_cell_ranges.size()>0)
|
||||
buffer.append(" .id = ").append(Integer.toHexString(sid)).append("\n");
|
||||
buffer.append(" .numCF = ").append(getNumberOfConditionalFormats()).append("\n");
|
||||
buffer.append(" .needRecalc = ").append(getNeedRecalculation()).append("\n");
|
||||
buffer.append(" .enclosingCellRange= ").append(getEnclosingCellRange()).append("\n");
|
||||
if( field_4_cell_ranges.length>0)
|
||||
{
|
||||
buffer.append(" .cfranges=[");
|
||||
for( int i=0; i<field_4_cell_ranges.size(); i++)
|
||||
buffer.append(" .cfranges=[");
|
||||
for( int i=0; i<field_4_cell_ranges.length; i++)
|
||||
{
|
||||
buffer.append(i==0?"":",").append(field_4_cell_ranges.get(i));
|
||||
buffer.append(i==0?"":",").append(field_4_cell_ranges[i].toString());
|
||||
}
|
||||
buffer.append("]\n");
|
||||
}
|
||||
@ -163,24 +160,21 @@ public class CFHeaderRecord extends Record
|
||||
LittleEndian.putShort(data, 10 + offset, (short) field_3_enclosing_cell_range.getLastRow());
|
||||
LittleEndian.putShort(data, 12 + offset, (short) field_3_enclosing_cell_range.getFirstColumn());
|
||||
LittleEndian.putShort(data, 14 + offset, (short) field_3_enclosing_cell_range.getLastColumn());
|
||||
LittleEndian.putShort(data, 16 + offset, (short) field_4_cell_ranges.size());
|
||||
for( int i=0 ; i!=field_4_cell_ranges.size(); i++)
|
||||
LittleEndian.putShort(data, 16 + offset, (short) field_4_cell_ranges.length);
|
||||
for( int i=0 ; i!=field_4_cell_ranges.length; i++)
|
||||
{
|
||||
LittleEndian.putShort(data, 18 + 0 + 8 * i + offset,
|
||||
(short) ((CellRange) field_4_cell_ranges.get(i)).getFirstRow());
|
||||
LittleEndian.putShort(data, 18 + 2 + 8 * i + offset,
|
||||
(short) ((CellRange) field_4_cell_ranges.get(i)).getLastRow());
|
||||
LittleEndian.putShort(data, 18 + 4 + 8 * i + offset,
|
||||
(short) ((CellRange) field_4_cell_ranges.get(i)).getFirstColumn());
|
||||
LittleEndian.putShort(data, 18 + 6 + 8 * i + offset,
|
||||
(short) ((CellRange) field_4_cell_ranges.get(i)).getLastColumn());
|
||||
CellRange cr = field_4_cell_ranges[i];
|
||||
LittleEndian.putShort(data, 18 + 0 + 8 * i + offset, (short) cr.getFirstRow());
|
||||
LittleEndian.putShort(data, 18 + 2 + 8 * i + offset, (short) cr.getLastRow());
|
||||
LittleEndian.putShort(data, 18 + 4 + 8 * i + offset, (short) cr.getFirstColumn());
|
||||
LittleEndian.putShort(data, 18 + 6 + 8 * i + offset, (short) cr.getLastColumn());
|
||||
}
|
||||
return getRecordSize();
|
||||
}
|
||||
|
||||
public int getRecordSize()
|
||||
{
|
||||
return 18+8*field_4_cell_ranges.size();
|
||||
return 18+8*field_4_cell_ranges.length;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,20 +198,17 @@ public class CFHeaderRecord extends Record
|
||||
return sid;
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
CFHeaderRecord rec = new CFHeaderRecord();
|
||||
rec.field_1_numcf = field_1_numcf;
|
||||
rec.field_2_need_recalculation = field_2_need_recalculation;
|
||||
rec.field_3_enclosing_cell_range = field_3_enclosing_cell_range;
|
||||
rec.field_4_cell_ranges = new ArrayList(field_4_cell_ranges.size());
|
||||
Iterator iterator = field_4_cell_ranges.iterator();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
CellRange oldRange = (CellRange)iterator.next();
|
||||
rec.field_4_cell_ranges.add(oldRange.cloneCellRange());
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
CFHeaderRecord result = new CFHeaderRecord();
|
||||
result.field_1_numcf = field_1_numcf;
|
||||
result.field_2_need_recalculation = field_2_need_recalculation;
|
||||
result.field_3_enclosing_cell_range = field_3_enclosing_cell_range;
|
||||
CellRange[] crs = new CellRange[field_4_cell_ranges.length];
|
||||
for (int i = 0; i < crs.length; i++) {
|
||||
crs[i] = field_4_cell_ranges[i].cloneCellRange();
|
||||
}
|
||||
result.field_4_cell_ranges = crs;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,7 @@ public final class ExternalNameRecord extends Record {
|
||||
private static final int OPT_PICTURE_LINK = 0x0004;
|
||||
private static final int OPT_STD_DOCUMENT_NAME = 0x0008;
|
||||
private static final int OPT_OLE_LINK = 0x0010;
|
||||
// private static final int OPT_CLIP_FORMAT_MASK = 0x7FE0;
|
||||
// private static final int OPT_CLIP_FORMAT_MASK = 0x7FE0;
|
||||
private static final int OPT_ICONIFIED_PICTURE_LINK= 0x8000;
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ import org.apache.poi.hssf.record.CFHeaderRecord;
|
||||
import org.apache.poi.hssf.record.CFRuleRecord;
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.util.Region;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
@ -37,19 +38,38 @@ import org.apache.poi.util.POILogger;
|
||||
*/
|
||||
public final class CFRecordsAggregate extends Record
|
||||
{
|
||||
/** Excel allows up to 3 conditional formating rules */
|
||||
private static final int MAX_CONDTIONAL_FORMAT_RULES = 3;
|
||||
|
||||
public final static short sid = -2008; // not a real BIFF record
|
||||
|
||||
private static POILogger log = POILogFactory.getLogger(CFRecordsAggregate.class);
|
||||
private static POILogger log = POILogFactory.getLogger(CFRecordsAggregate.class);
|
||||
|
||||
private CFHeaderRecord header;
|
||||
private final CFHeaderRecord header;
|
||||
|
||||
// List of CFRuleRecord objects
|
||||
/** List of CFRuleRecord objects */
|
||||
private final List rules;
|
||||
|
||||
public CFRecordsAggregate()
|
||||
{
|
||||
header = null;
|
||||
rules = new ArrayList(3);
|
||||
private CFRecordsAggregate(CFHeaderRecord pHeader, CFRuleRecord[] pRules) {
|
||||
if(pHeader == null) {
|
||||
throw new IllegalArgumentException("header must not be null");
|
||||
}
|
||||
if(pRules == null) {
|
||||
throw new IllegalArgumentException("rules must not be null");
|
||||
}
|
||||
if(pRules.length > MAX_CONDTIONAL_FORMAT_RULES) {
|
||||
throw new IllegalArgumentException("No more than "
|
||||
+ MAX_CONDTIONAL_FORMAT_RULES + " rules may be specified");
|
||||
}
|
||||
header = pHeader;
|
||||
rules = new ArrayList(3);
|
||||
for (int i = 0; i < pRules.length; i++) {
|
||||
rules.add(pRules[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public CFRecordsAggregate(Region[] regions, CFRuleRecord[] rules) {
|
||||
this(new CFHeaderRecord(regions), rules);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,42 +80,46 @@ public final class CFRecordsAggregate extends Record
|
||||
*/
|
||||
public static CFRecordsAggregate createCFAggregate(List recs, int pOffset)
|
||||
{
|
||||
|
||||
int offset = pOffset;
|
||||
CFRecordsAggregate cfRecords = new CFRecordsAggregate();
|
||||
ArrayList records = new ArrayList(4);
|
||||
|
||||
Record rec = ( Record ) recs.get(offset++);
|
||||
|
||||
if (rec.getSid() == CFHeaderRecord.sid)
|
||||
{
|
||||
records.add(rec);
|
||||
cfRecords.header = (CFHeaderRecord)rec;
|
||||
|
||||
int nRules = cfRecords.header.getNumberOfConditionalFormats();
|
||||
int rulesCount = 0;
|
||||
while( offset<recs.size() &&
|
||||
(rec = (Record)recs.get(offset++)).getSid() == CFRuleRecord.sid &&
|
||||
rec instanceof CFRuleRecord &&
|
||||
rulesCount++ < nRules
|
||||
)
|
||||
{
|
||||
records.add(rec);
|
||||
cfRecords.rules.add(rec);
|
||||
}
|
||||
|
||||
if (nRules != cfRecords.rules.size())
|
||||
{
|
||||
if (log.check(POILogger.DEBUG))
|
||||
{
|
||||
log.log(POILogger.DEBUG, "Expected " + nRules + " Conditional Formats, "
|
||||
+ "but found " + cfRecords.rules.size() + " rules");
|
||||
}
|
||||
cfRecords.header.setNumberOfConditionalFormats(nRules);
|
||||
}
|
||||
|
||||
Record rec = ( Record ) recs.get(pOffset);
|
||||
if (rec.getSid() != CFHeaderRecord.sid) {
|
||||
throw new IllegalStateException("next record sid was " + rec.getSid()
|
||||
+ " instead of " + CFHeaderRecord.sid + " as expected");
|
||||
}
|
||||
return cfRecords;
|
||||
|
||||
CFHeaderRecord header = (CFHeaderRecord)rec;
|
||||
int nRules = header.getNumberOfConditionalFormats();
|
||||
|
||||
CFRuleRecord[] rules = new CFRuleRecord[nRules];
|
||||
int offset = pOffset;
|
||||
int countFound = 0;
|
||||
while (countFound < rules.length) {
|
||||
offset++;
|
||||
if(offset>=recs.size()) {
|
||||
break;
|
||||
}
|
||||
rec = (Record)recs.get(offset);
|
||||
if(rec instanceof CFRuleRecord) {
|
||||
rules[countFound] = (CFRuleRecord) rec;
|
||||
countFound++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (countFound < nRules)
|
||||
{ // TODO -(MAR-2008) can this ever happen? write junit
|
||||
|
||||
if (log.check(POILogger.DEBUG))
|
||||
{
|
||||
log.log(POILogger.DEBUG, "Expected " + nRules + " Conditional Formats, "
|
||||
+ "but found " + countFound + " rules");
|
||||
}
|
||||
header.setNumberOfConditionalFormats(nRules);
|
||||
CFRuleRecord[] lessRules = new CFRuleRecord[countFound];
|
||||
System.arraycopy(rules, 0, lessRules, 0, countFound);
|
||||
rules = lessRules;
|
||||
}
|
||||
return new CFRecordsAggregate(header, rules);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -104,22 +128,17 @@ public final class CFRecordsAggregate extends Record
|
||||
*/
|
||||
public CFRecordsAggregate cloneCFAggregate()
|
||||
{
|
||||
|
||||
ArrayList records = new ArrayList(this.rules.size()+1);
|
||||
|
||||
records.add(this.header.clone());
|
||||
|
||||
for (int i=0; i<this.rules.size();i++)
|
||||
{
|
||||
Record rec = (Record)((Record)this.rules.get(i)).clone();
|
||||
records.add(rec);
|
||||
}
|
||||
return createCFAggregate(records, 0);
|
||||
CFRuleRecord[] newRecs = new CFRuleRecord[rules.size()];
|
||||
for (int i = 0; i < newRecs.length; i++) {
|
||||
newRecs[i] = (CFRuleRecord) getRule(i).clone();
|
||||
}
|
||||
return new CFRecordsAggregate((CFHeaderRecord) header.clone(), newRecs);
|
||||
}
|
||||
|
||||
/** You never fill an aggregate */
|
||||
protected void fillFields(RecordInputStream in)
|
||||
{
|
||||
// You never fill an aggregate record
|
||||
}
|
||||
|
||||
public short getSid()
|
||||
@ -139,17 +158,14 @@ public final class CFRecordsAggregate extends Record
|
||||
|
||||
public int serialize(int offset, byte[] data)
|
||||
{
|
||||
int nRules = rules.size();
|
||||
header.setNumberOfConditionalFormats(nRules);
|
||||
|
||||
int pos = offset;
|
||||
if( header != null && rules.size()>0 )
|
||||
{
|
||||
header.setNumberOfConditionalFormats(rules.size());
|
||||
|
||||
pos += (( Record ) header).serialize(pos, data);
|
||||
|
||||
for(Iterator itr = rules.iterator(); itr.hasNext();)
|
||||
{
|
||||
pos += (( Record ) itr.next()).serialize(pos, data);
|
||||
}
|
||||
pos += header.serialize(pos, data);
|
||||
for(int i=0; i< nRules; i++) {
|
||||
pos += getRule(i).serialize(pos, data);
|
||||
}
|
||||
return pos - offset;
|
||||
}
|
||||
@ -160,19 +176,37 @@ public final class CFRecordsAggregate extends Record
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the header
|
||||
* @return the header. Never <code>null</code>.
|
||||
*/
|
||||
public CFHeaderRecord getHeader()
|
||||
{
|
||||
return header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rules
|
||||
*/
|
||||
public List getRules()
|
||||
{
|
||||
return rules;
|
||||
|
||||
private void checkRuleIndex(int idx) {
|
||||
if(idx < 0 || idx >= rules.size()) {
|
||||
throw new IllegalArgumentException("Bad rule record index (" + idx
|
||||
+ ") nRules=" + rules.size());
|
||||
}
|
||||
}
|
||||
public CFRuleRecord getRule(int idx) {
|
||||
checkRuleIndex(idx);
|
||||
return (CFRuleRecord) rules.get(idx);
|
||||
}
|
||||
public void setRule(int idx, CFRuleRecord r) {
|
||||
checkRuleIndex(idx);
|
||||
rules.set(idx, r);
|
||||
}
|
||||
public void addRule(CFRuleRecord r) {
|
||||
if(rules.size() >= MAX_CONDTIONAL_FORMAT_RULES) {
|
||||
throw new IllegalStateException("Cannot have more than "
|
||||
+ MAX_CONDTIONAL_FORMAT_RULES + " conditional format rules");
|
||||
}
|
||||
rules.add(r);
|
||||
header.setNumberOfConditionalFormats(rules.size());
|
||||
}
|
||||
public int getNumberOfRules() {
|
||||
return rules.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,79 +17,127 @@
|
||||
|
||||
package org.apache.poi.hssf.record.cf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hssf.util.Region;
|
||||
|
||||
/**
|
||||
* CellRange.java
|
||||
* Created on January 22, 2008, 10:05 PM
|
||||
*
|
||||
* @author Dmitriy Kumshayev
|
||||
*/
|
||||
|
||||
public class CellRange
|
||||
public final class CellRange
|
||||
{
|
||||
private int field_1_first_row;
|
||||
private int field_2_last_row;
|
||||
private short field_3_first_column;
|
||||
private short field_4_last_column;
|
||||
|
||||
public CellRange(int firstRow, int lastRow, short firstColumn, short lastColumn)
|
||||
{
|
||||
this.field_1_first_row = firstRow;
|
||||
this.field_2_last_row = lastRow;
|
||||
this.field_3_first_column = firstColumn;
|
||||
this.field_4_last_column = lastColumn;
|
||||
validateRegion();
|
||||
/**
|
||||
* max index for both row and column<p/>
|
||||
*
|
||||
* Note - this value converts to <tt>-1</tt> when cast to a <tt>short</tt>
|
||||
*/
|
||||
private static final int MAX_INDEX = Integer.MAX_VALUE;
|
||||
|
||||
private static final Region[] EMPTY_REGION_ARRAY = { };
|
||||
|
||||
private int _firstRow;
|
||||
private int _lastRow;
|
||||
private int _firstColumn;
|
||||
private int _lastColumn;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param firstRow
|
||||
* @param lastRow pass <tt>-1</tt> for full column ranges
|
||||
* @param firstColumn
|
||||
* @param lastColumn pass <tt>-1</tt> for full row ranges
|
||||
*/
|
||||
public CellRange(int firstRow, int lastRow, int firstColumn, int lastColumn)
|
||||
{
|
||||
if(!isValid(firstRow, lastRow, firstColumn, lastColumn)) {
|
||||
throw new IllegalArgumentException("invalid cell range (" + firstRow + ", " + lastRow
|
||||
+ ", " + firstColumn + ", " + lastColumn + ")");
|
||||
}
|
||||
_firstRow = firstRow;
|
||||
_lastRow = convertM1ToMax(lastRow);
|
||||
_firstColumn = firstColumn;
|
||||
_lastColumn = convertM1ToMax(lastColumn);
|
||||
}
|
||||
|
||||
private void validateRegion()
|
||||
{
|
||||
if( field_1_first_row < 0 ||
|
||||
field_2_last_row < -1 ||
|
||||
field_3_first_column < 0 ||
|
||||
field_4_last_column < -1 ||
|
||||
field_2_last_row>=0 && field_2_last_row<field_1_first_row ||
|
||||
field_4_last_column>=0 && field_4_last_column<field_3_first_column
|
||||
)
|
||||
{
|
||||
throw new IllegalArgumentException("Invalid cell region "+toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static int convertM1ToMax(int lastIx) {
|
||||
if(lastIx < 0) {
|
||||
return MAX_INDEX;
|
||||
}
|
||||
return lastIx;
|
||||
}
|
||||
private static int convertMaxToM1(int lastIx) {
|
||||
if(lastIx == MAX_INDEX) {
|
||||
return -1;
|
||||
}
|
||||
return lastIx;
|
||||
}
|
||||
|
||||
public boolean isFullColumnRange() {
|
||||
return _firstColumn == 0 && _lastColumn == MAX_INDEX;
|
||||
}
|
||||
public boolean isFullRowRange() {
|
||||
return _firstRow == 0 && _lastRow == MAX_INDEX;
|
||||
}
|
||||
|
||||
public CellRange(Region r) {
|
||||
this(r.getRowFrom(), r.getRowTo(), r.getColumnFrom(), r.getColumnTo());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static boolean isValid(int firstRow, int lastRow, int firstColumn, int lastColumn)
|
||||
{
|
||||
if(lastRow == -1) {
|
||||
if(firstRow !=0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(firstRow < 0 || lastRow < -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(lastColumn == -1) {
|
||||
if(firstColumn !=0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(firstColumn < 0 || lastColumn < -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getFirstRow()
|
||||
{
|
||||
return field_1_first_row;
|
||||
}
|
||||
private void setFirstRow(int firstRow)
|
||||
{
|
||||
this.field_1_first_row = firstRow;
|
||||
return _firstRow;
|
||||
}
|
||||
/**
|
||||
* @return <tt>-1</tt> for whole column ranges
|
||||
*/
|
||||
public int getLastRow()
|
||||
{
|
||||
return field_2_last_row;
|
||||
return convertMaxToM1(_lastRow);
|
||||
}
|
||||
private void setLastRow(int lastRow)
|
||||
public int getFirstColumn()
|
||||
{
|
||||
this.field_2_last_row = lastRow;
|
||||
return _firstColumn;
|
||||
}
|
||||
public short getFirstColumn()
|
||||
/**
|
||||
* @return <tt>-1</tt> for whole row ranges
|
||||
*/
|
||||
public int getLastColumn()
|
||||
{
|
||||
return field_3_first_column;
|
||||
}
|
||||
private void setFirstColumn(short firstColumn)
|
||||
{
|
||||
this.field_3_first_column = firstColumn;
|
||||
}
|
||||
public short getLastColumn()
|
||||
{
|
||||
return field_4_last_column;
|
||||
}
|
||||
private void setLastColumn(short lastColumn)
|
||||
{
|
||||
this.field_4_last_column = lastColumn;
|
||||
return convertMaxToM1(_lastColumn);
|
||||
}
|
||||
|
||||
public static final int NO_INTERSECTION = 1;
|
||||
public static final int OVERLAP = 2;
|
||||
/** first range is within the second range */
|
||||
public static final int INSIDE = 3;
|
||||
/** first range encloses or is equal to the second */
|
||||
public static final int ENCLOSES = 4;
|
||||
|
||||
/**
|
||||
@ -101,30 +149,31 @@ public class CellRange
|
||||
* NO_INTERSECTION - the specified range is outside of this range;<br/>
|
||||
* OVERLAP - both ranges partially overlap;<br/>
|
||||
* INSIDE - the specified range is inside of this one<br/>
|
||||
* ENCLOSES - the specified range encloses this range<br/>
|
||||
* ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/>
|
||||
*/
|
||||
public int intersect(CellRange another )
|
||||
{
|
||||
int firstRow = another.getFirstRow();
|
||||
int lastRow = another.getLastRow();
|
||||
short firstCol = another.getFirstColumn();
|
||||
short lastCol = another.getLastColumn();
|
||||
|
||||
int firstRow = another.getFirstRow();
|
||||
int lastRow = another.getLastRow();
|
||||
int firstCol = another.getFirstColumn();
|
||||
int lastCol = another.getLastColumn();
|
||||
|
||||
if
|
||||
(
|
||||
gt(this.getFirstRow(),lastRow) ||
|
||||
lt(this.getLastRow(),firstRow) ||
|
||||
gt(this.getFirstColumn(),lastCol) ||
|
||||
lt(this.getLastColumn(),firstCol)
|
||||
gt(getFirstRow(),lastRow) ||
|
||||
lt(getLastRow(),firstRow) ||
|
||||
gt(getFirstColumn(),lastCol) ||
|
||||
lt(getLastColumn(),firstCol)
|
||||
)
|
||||
{
|
||||
return NO_INTERSECTION;
|
||||
}
|
||||
else if( this.contains(another) )
|
||||
else if( contains(another) )
|
||||
{
|
||||
return INSIDE;
|
||||
}
|
||||
else if( another.contains(this) )
|
||||
else if( another.contains(this))
|
||||
{
|
||||
return ENCLOSES;
|
||||
}
|
||||
@ -134,7 +183,234 @@ public class CellRange
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Do all possible cell merges between cells of the list so that:<br>
|
||||
* <li>if a cell range is completely inside of another cell range, it gets removed from the list
|
||||
* <li>if two cells have a shared border, merge them into one bigger cell range
|
||||
* @param cellRangeList
|
||||
* @return updated List of cell ranges
|
||||
*/
|
||||
public static CellRange[] mergeCellRanges(CellRange[] cellRanges) {
|
||||
if(cellRanges.length < 1) {
|
||||
return cellRanges;
|
||||
}
|
||||
List temp = mergeCellRanges(Arrays.asList(cellRanges));
|
||||
return toArray(temp);
|
||||
}
|
||||
private static List mergeCellRanges(List cellRangeList)
|
||||
{
|
||||
|
||||
while(cellRangeList.size() > 1)
|
||||
{
|
||||
boolean somethingGotMerged = false;
|
||||
|
||||
for( int i=0; i<cellRangeList.size(); i++)
|
||||
{
|
||||
CellRange range1 = (CellRange)cellRangeList.get(i);
|
||||
for( int j=i+1; j<cellRangeList.size(); j++)
|
||||
{
|
||||
CellRange range2 = (CellRange)cellRangeList.get(j);
|
||||
|
||||
CellRange[] mergeResult = mergeRanges(range1, range2);
|
||||
if(mergeResult == null) {
|
||||
continue;
|
||||
}
|
||||
somethingGotMerged = true;
|
||||
// overwrite range1 with first result
|
||||
cellRangeList.set(i, mergeResult[0]);
|
||||
// remove range2
|
||||
cellRangeList.remove(j--);
|
||||
// add any extra results beyond the first
|
||||
for(int k=1; k<mergeResult.length; k++) {
|
||||
j++;
|
||||
cellRangeList.add(j, mergeResult[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!somethingGotMerged) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return cellRangeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the new range(s) to replace the supplied ones. <code>null</code> if no merge is possible
|
||||
*/
|
||||
private static CellRange[] mergeRanges(CellRange range1, CellRange range2) {
|
||||
|
||||
int x = range1.intersect(range2);
|
||||
switch(x)
|
||||
{
|
||||
case CellRange.NO_INTERSECTION:
|
||||
if( range1.hasExactSharedBorder(range2))
|
||||
{
|
||||
return new CellRange[] { range1.createEnclosingCellRange(range2), };
|
||||
}
|
||||
// else - No intersection and no shared border: do nothing
|
||||
return null;
|
||||
case CellRange.OVERLAP:
|
||||
return resolveRangeOverlap(range1, range2);
|
||||
case CellRange.INSIDE:
|
||||
// Remove range2, since it is completely inside of range1
|
||||
return new CellRange[] { range1, };
|
||||
case CellRange.ENCLOSES:
|
||||
// range2 encloses range1, so replace it with the enclosing one
|
||||
return new CellRange[] { range2, };
|
||||
}
|
||||
throw new RuntimeException("unexpected intersection result (" + x + ")");
|
||||
}
|
||||
|
||||
// TODO - write junit test for this
|
||||
static CellRange[] resolveRangeOverlap(CellRange rangeA, CellRange rangeB) {
|
||||
|
||||
if(rangeA.isFullColumnRange()) {
|
||||
if(rangeB.isFullRowRange()) {
|
||||
// Excel seems to leave these unresolved
|
||||
return null;
|
||||
}
|
||||
return rangeA.sliceUp(rangeB);
|
||||
}
|
||||
if(rangeA.isFullRowRange()) {
|
||||
if(rangeB.isFullColumnRange()) {
|
||||
// Excel seems to leave these unresolved
|
||||
return null;
|
||||
}
|
||||
return rangeA.sliceUp(rangeB);
|
||||
}
|
||||
if(rangeB.isFullColumnRange()) {
|
||||
return rangeB.sliceUp(rangeA);
|
||||
}
|
||||
if(rangeB.isFullRowRange()) {
|
||||
return rangeB.sliceUp(rangeA);
|
||||
}
|
||||
return rangeA.sliceUp(rangeB);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param range never a full row or full column range
|
||||
* @return an array including <b>this</b> <tt>CellRange</tt> and all parts of <tt>range</tt>
|
||||
* outside of this range
|
||||
*/
|
||||
private CellRange[] sliceUp(CellRange range) {
|
||||
|
||||
List temp = new ArrayList();
|
||||
|
||||
// Chop up range horizontally and vertically
|
||||
temp.add(range);
|
||||
if(!isFullColumnRange()) {
|
||||
temp = cutHorizontally(_firstRow, temp);
|
||||
temp = cutHorizontally(_lastRow+1, temp);
|
||||
}
|
||||
if(!isFullRowRange()) {
|
||||
temp = cutVertically(_firstColumn, temp);
|
||||
temp = cutVertically(_lastColumn+1, temp);
|
||||
}
|
||||
CellRange[] crParts = toArray(temp);
|
||||
|
||||
// form result array
|
||||
temp.clear();
|
||||
temp.add(this);
|
||||
|
||||
for (int i = 0; i < crParts.length; i++) {
|
||||
CellRange crPart = crParts[i];
|
||||
// only include parts that are not enclosed by this
|
||||
if(intersect(crPart) != ENCLOSES) {
|
||||
temp.add(crPart);
|
||||
}
|
||||
}
|
||||
return toArray(temp);
|
||||
}
|
||||
|
||||
private static List cutHorizontally(int cutRow, List input) {
|
||||
|
||||
List result = new ArrayList();
|
||||
CellRange[] crs = toArray(input);
|
||||
for (int i = 0; i < crs.length; i++) {
|
||||
CellRange cr = crs[i];
|
||||
if(cr._firstRow < cutRow && cutRow < cr._lastRow) {
|
||||
result.add(new CellRange(cr._firstRow, cutRow, cr._firstColumn, cr._lastColumn));
|
||||
result.add(new CellRange(cutRow+1, cr._lastRow, cr._firstColumn, cr._lastColumn));
|
||||
} else {
|
||||
result.add(cr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private static List cutVertically(int cutColumn, List input) {
|
||||
|
||||
List result = new ArrayList();
|
||||
CellRange[] crs = toArray(input);
|
||||
for (int i = 0; i < crs.length; i++) {
|
||||
CellRange cr = crs[i];
|
||||
if(cr._firstColumn < cutColumn && cutColumn < cr._lastColumn) {
|
||||
result.add(new CellRange(cr._firstRow, cr._lastRow, cr._firstColumn, cutColumn));
|
||||
result.add(new CellRange(cr._firstRow, cr._lastRow, cutColumn+1, cr._lastColumn));
|
||||
} else {
|
||||
result.add(cr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static CellRange[] toArray(List temp) {
|
||||
CellRange[] result = new CellRange[temp.size()];
|
||||
temp.toArray(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert array of regions to a List of CellRange objects
|
||||
*
|
||||
* @param regions
|
||||
* @return List of CellRange objects
|
||||
*/
|
||||
public static CellRange[] convertRegionsToCellRanges(Region[] regions)
|
||||
{
|
||||
CellRange[] result = new CellRange[regions.length];
|
||||
for( int i=0; i<regions.length; i++)
|
||||
{
|
||||
result[i] = new CellRange(regions[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a List of CellRange objects to an array of regions
|
||||
*
|
||||
* @param List of CellRange objects
|
||||
* @return regions
|
||||
*/
|
||||
public static Region[] convertCellRangesToRegions(CellRange[] cellRanges)
|
||||
{
|
||||
int size = cellRanges.length;
|
||||
if(size < 1) {
|
||||
return EMPTY_REGION_ARRAY;
|
||||
}
|
||||
|
||||
Region[] result = new Region[size];
|
||||
|
||||
for (int i = 0; i != size; i++)
|
||||
{
|
||||
result[i] = cellRanges[i].convertToRegion();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Region convertToRegion() {
|
||||
int lastRow = convertMaxToM1(_lastRow);
|
||||
int lastColumn = convertMaxToM1(_lastColumn);
|
||||
|
||||
return new Region(_firstRow, (short)_firstColumn, lastRow, (short)lastColumn);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the specified range is located inside of this cell range.
|
||||
*
|
||||
@ -145,44 +421,52 @@ public class CellRange
|
||||
{
|
||||
int firstRow = range.getFirstRow();
|
||||
int lastRow = range.getLastRow();
|
||||
short firstCol = range.getFirstColumn();
|
||||
short lastCol = range.getLastColumn();
|
||||
return le(this.getFirstRow(), firstRow) && ge(this.getLastRow(), lastRow)
|
||||
&& le(this.getFirstColumn(), firstCol) && ge(this.getLastColumn(), lastCol);
|
||||
int firstCol = range.getFirstColumn();
|
||||
int lastCol = range.getLastColumn();
|
||||
return le(getFirstRow(), firstRow) && ge(getLastRow(), lastRow)
|
||||
&& le(getFirstColumn(), firstCol) && ge(getLastColumn(), lastCol);
|
||||
}
|
||||
|
||||
public boolean contains(int row, short column)
|
||||
{
|
||||
return le(this.getFirstRow(), row) && ge(this.getLastRow(), row)
|
||||
&& le(this.getFirstColumn(), column) && ge(this.getLastColumn(), column);
|
||||
return le(getFirstRow(), row) && ge(getLastRow(), row)
|
||||
&& le(getFirstColumn(), column) && ge(getLastColumn(), column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the specified cell range has a shared border with the current range.
|
||||
*
|
||||
* @return true if the ranges have a shared border.
|
||||
*/
|
||||
public boolean hasSharedBorder(CellRange range)
|
||||
* Check if the specified cell range has a shared border with the current range.
|
||||
*
|
||||
* @return <code>true</code> if the ranges have a complete shared border (i.e.
|
||||
* the two ranges together make a simple rectangular region.
|
||||
*/
|
||||
public boolean hasExactSharedBorder(CellRange range)
|
||||
{
|
||||
int firstRow = range.getFirstRow();
|
||||
int lastRow = range.getLastRow();
|
||||
short firstCol = range.getFirstColumn();
|
||||
short lastCol = range.getLastColumn();
|
||||
return
|
||||
(this.getFirstRow()>0 && this.getFirstRow() - 1 == lastRow || firstRow>0 &&this.getLastRow() == firstRow -1)&&
|
||||
(this.getFirstColumn() == firstCol) &&
|
||||
(this.getLastColumn() == lastCol) ||
|
||||
(this.getFirstColumn()>0 && this.getFirstColumn() - 1 == lastCol || firstCol>0 && this.getLastColumn() == firstCol -1) &&
|
||||
(this.getFirstRow() == firstRow) &&
|
||||
(this.getLastRow() == lastRow)
|
||||
;
|
||||
int oFirstRow = range._firstRow;
|
||||
int oLastRow = range._lastRow;
|
||||
int oFirstCol = range._firstColumn;
|
||||
int oLastCol = range._lastColumn;
|
||||
|
||||
if (_firstRow > 0 && _firstRow-1 == oLastRow ||
|
||||
oFirstRow > 0 && oFirstRow-1 == _lastRow) {
|
||||
// ranges have a horizontal border in common
|
||||
// make sure columns are identical:
|
||||
return _firstColumn == oFirstCol && _lastColumn == oLastCol;
|
||||
}
|
||||
|
||||
if (_firstColumn>0 && _firstColumn - 1 == oLastCol ||
|
||||
oFirstCol>0 && _lastColumn == oFirstCol -1) {
|
||||
// ranges have a vertical border in common
|
||||
// make sure rows are identical:
|
||||
return _firstRow == oFirstRow && _lastRow == oLastRow;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an enclosing CellRange for the two cell ranges.
|
||||
*
|
||||
* @return enclosing CellRange
|
||||
*/
|
||||
/**
|
||||
* Create an enclosing CellRange for the two cell ranges.
|
||||
*
|
||||
* @return enclosing CellRange
|
||||
*/
|
||||
public CellRange createEnclosingCellRange(CellRange range)
|
||||
{
|
||||
if( range == null)
|
||||
@ -206,18 +490,6 @@ public class CellRange
|
||||
{
|
||||
return new CellRange(getFirstRow(),getLastRow(),getFirstColumn(),getLastColumn());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy data from antother cell range to this cell range
|
||||
* @param cr - another cell range
|
||||
*/
|
||||
public void setCellRange(CellRange cr)
|
||||
{
|
||||
setFirstRow(cr.getFirstRow());
|
||||
setLastRow(cr.getLastRow());
|
||||
setFirstColumn(cr.getFirstColumn());
|
||||
setLastColumn(cr.getLastColumn());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if a < b
|
||||
@ -253,7 +525,7 @@ public class CellRange
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "("+this.getFirstRow()+","+this.getLastRow()+","+this.getFirstColumn()+","+this.getLastColumn()+")";
|
||||
return "("+getFirstRow()+","+getLastRow()+","+getFirstColumn()+","+getLastColumn()+")";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,27 +23,27 @@ import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
||||
|
||||
|
||||
/**
|
||||
* This class provides the base functionality for Excel sheet functions
|
||||
* This class provides the base functionality for Excel sheet functions
|
||||
* There are two kinds of function Ptgs - tFunc and tFuncVar
|
||||
* Therefore, this class will have ONLY two subclasses
|
||||
* @author Avik Sengupta
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
*/
|
||||
public abstract class AbstractFunctionPtg extends OperationPtg {
|
||||
|
||||
|
||||
/**
|
||||
* The name of the IF function (i.e. "IF"). Extracted as a constant for clarity.
|
||||
*/
|
||||
*/
|
||||
public static final String FUNCTION_NAME_IF = "IF";
|
||||
/** All external functions have function index 255 */
|
||||
private static final short FUNCTION_INDEX_EXTERNAL = 255;
|
||||
|
||||
|
||||
protected byte returnClass;
|
||||
protected byte[] paramClass;
|
||||
|
||||
|
||||
protected byte field_1_num_args;
|
||||
protected short field_2_fnc_index;
|
||||
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer(64);
|
||||
sb.append(getClass().getName()).append(" [");
|
||||
@ -51,17 +51,17 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public int getType() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public short getFunctionIndex() {
|
||||
return field_2_fnc_index;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return lookupName(field_2_fnc_index);
|
||||
}
|
||||
@ -72,14 +72,14 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
||||
public boolean isExternalFunction() {
|
||||
return field_2_fnc_index == FUNCTION_INDEX_EXTERNAL;
|
||||
}
|
||||
|
||||
|
||||
public String toFormulaString(Workbook book) {
|
||||
return getName();
|
||||
}
|
||||
|
||||
|
||||
public String toFormulaString(String[] operands) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
if(isExternalFunction()) {
|
||||
buf.append(operands[0]); // first operand is actually the function name
|
||||
appendArgs(buf, 1, operands);
|
||||
@ -100,23 +100,23 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
||||
}
|
||||
buf.append(")");
|
||||
}
|
||||
|
||||
|
||||
public abstract void writeBytes(byte[] array, int offset);
|
||||
public abstract int getSize();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Used to detect whether a function name found in a formula is one of the standard excel functions
|
||||
* <p>
|
||||
* The name matching is case insensitive.
|
||||
* @return <code>true</code> if the name specifies a standard worksheet function,
|
||||
* @return <code>true</code> if the name specifies a standard worksheet function,
|
||||
* <code>false</code> if the name should be assumed to be an external function.
|
||||
*/
|
||||
public static final boolean isInternalFunctionName(String name) {
|
||||
short ix = FunctionMetadataRegistry.lookupIndexByName(name.toUpperCase());
|
||||
return ix >= 0;
|
||||
}
|
||||
|
||||
|
||||
protected String lookupName(short index) {
|
||||
if(index == FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL) {
|
||||
return "#external#";
|
||||
@ -127,7 +127,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
||||
}
|
||||
return fm.getName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolves internal function names into function indexes.
|
||||
* <p>
|
||||
@ -145,7 +145,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
||||
public byte getDefaultOperandClass() {
|
||||
return returnClass;
|
||||
}
|
||||
|
||||
|
||||
public byte getParameterClass(int index) {
|
||||
try {
|
||||
return paramClass[index];
|
||||
|
@ -27,11 +27,11 @@ import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
||||
* @author Danny Mui (dmui at apache dot org) (Leftover handling)
|
||||
*/
|
||||
public final class FuncPtg extends AbstractFunctionPtg {
|
||||
|
||||
|
||||
public final static byte sid = 0x21;
|
||||
public final static int SIZE = 3;
|
||||
private int numParams=0;
|
||||
|
||||
|
||||
/**
|
||||
* FuncPtgs are defined to be 4 bytes but the actual FuncPtg uses only 2 bytes.
|
||||
* If we have leftOvers that are read from the file we should serialize them back out.
|
||||
@ -39,18 +39,18 @@ public final class FuncPtg extends AbstractFunctionPtg {
|
||||
* If the leftovers are removed, a prompt "Warning: Data may have been lost occurs in Excel"
|
||||
*/
|
||||
//protected byte[] leftOvers = null;
|
||||
|
||||
|
||||
private FuncPtg() {
|
||||
//Required for clone methods
|
||||
//Required for clone methods
|
||||
}
|
||||
|
||||
/**Creates new function pointer from a byte array
|
||||
* usually called while reading an excel file.
|
||||
/**Creates new function pointer from a byte array
|
||||
* usually called while reading an excel file.
|
||||
*/
|
||||
public FuncPtg(RecordInputStream in) {
|
||||
//field_1_num_args = data[ offset + 0 ];
|
||||
field_2_fnc_index = in.readShort();
|
||||
|
||||
|
||||
FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(field_2_fnc_index);
|
||||
if(fm == null) {
|
||||
throw new RuntimeException("Invalid built-in function index (" + field_2_fnc_index + ")");
|
||||
@ -62,12 +62,12 @@ public final class FuncPtg extends AbstractFunctionPtg {
|
||||
numParams = numberOfParameters;
|
||||
paramClass = new byte[] { Ptg.CLASS_VALUE, }; // TODO
|
||||
}
|
||||
|
||||
|
||||
public void writeBytes(byte[] array, int offset) {
|
||||
array[offset+0]= (byte) (sid + ptgClass);
|
||||
LittleEndian.putShort(array,offset+1,field_2_fnc_index);
|
||||
}
|
||||
|
||||
|
||||
public int getNumberOfOperands() {
|
||||
return numParams;
|
||||
}
|
||||
@ -79,11 +79,11 @@ public final class FuncPtg extends AbstractFunctionPtg {
|
||||
ptg.setClass(ptgClass);
|
||||
return ptg;
|
||||
}
|
||||
|
||||
|
||||
public int getSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer(64);
|
||||
sb.append(getClass().getName()).append(" [");
|
||||
|
@ -15,7 +15,6 @@
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
@ -27,22 +26,22 @@ import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
*/
|
||||
public final class FuncVarPtg extends AbstractFunctionPtg{
|
||||
|
||||
|
||||
public final static byte sid = 0x22;
|
||||
private final static int SIZE = 4;
|
||||
|
||||
private final static int SIZE = 4;
|
||||
|
||||
private FuncVarPtg() {
|
||||
//Required for clone methods
|
||||
}
|
||||
|
||||
/**Creates new function pointer from a byte array
|
||||
* usually called while reading an excel file.
|
||||
/**Creates new function pointer from a byte array
|
||||
* usually called while reading an excel file.
|
||||
*/
|
||||
public FuncVarPtg(RecordInputStream in) {
|
||||
field_1_num_args = in.readByte();
|
||||
field_2_fnc_index = in.readShort();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a function ptg from a string tokenised by the parser
|
||||
*/
|
||||
@ -59,17 +58,17 @@ public final class FuncVarPtg extends AbstractFunctionPtg{
|
||||
paramClass = new byte[] {Ptg.CLASS_VALUE};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void writeBytes(byte[] array, int offset) {
|
||||
array[offset+0]=(byte) (sid + ptgClass);
|
||||
array[offset+1]=field_1_num_args;
|
||||
LittleEndian.putShort(array,offset+2,field_2_fnc_index);
|
||||
}
|
||||
|
||||
|
||||
public int getNumberOfOperands() {
|
||||
return field_1_num_args;
|
||||
}
|
||||
|
||||
|
||||
public Object clone() {
|
||||
FuncVarPtg ptg = new FuncVarPtg();
|
||||
ptg.field_1_num_args = field_1_num_args;
|
||||
@ -77,11 +76,11 @@ public final class FuncVarPtg extends AbstractFunctionPtg{
|
||||
ptg.setClass(ptgClass);
|
||||
return ptg;
|
||||
}
|
||||
|
||||
|
||||
public int getSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer(64);
|
||||
sb.append(getClass().getName()).append(" [");
|
||||
|
@ -23,7 +23,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Temporarily collects <tt>FunctionMetadata</tt> instances for creation of a
|
||||
* Temporarily collects <tt>FunctionMetadata</tt> instances for creation of a
|
||||
* <tt>FunctionMetadataRegistry</tt>.
|
||||
*
|
||||
* @author Josh Micich
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula.function;
|
||||
/**
|
||||
* Holds information about Excel built-in functions.
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
@ -46,7 +47,7 @@ public final class FunctionMetadata {
|
||||
return _maxParams;
|
||||
}
|
||||
public boolean hasFixedArgsLength() {
|
||||
return _minParams == _maxParams;
|
||||
return _minParams == _maxParams;
|
||||
}
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer(64);
|
||||
|
@ -46,7 +46,7 @@ final class FunctionMetadataReader {
|
||||
|
||||
public static FunctionMetadataRegistry createRegistry() {
|
||||
InputStream is = FunctionMetadataReader.class.getResourceAsStream(METADATA_FILE_NAME);
|
||||
if(is == null) {
|
||||
if (is == null) {
|
||||
throw new RuntimeException("resource '" + METADATA_FILE_NAME + "' not found");
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,11 @@ package org.apache.poi.hssf.record.formula.function;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Allows clients to get <tt>FunctionMetadata</tt> instances for any built-in function of Excel.
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class FunctionMetadataRegistry {
|
||||
/**
|
||||
* The name of the IF function (i.e. "IF"). Extracted as a constant for clarity.
|
||||
@ -35,7 +39,6 @@ public final class FunctionMetadataRegistry {
|
||||
private static FunctionMetadataRegistry getInstance() {
|
||||
if (_instance == null) {
|
||||
_instance = FunctionMetadataReader.createRegistry();
|
||||
// _instance = POIFunctionMetadataCreator.createInstance();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
@ -46,15 +46,15 @@ public final class Pmt extends FinanceFunction {
|
||||
if(args.length < 3 || args.length > 5) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
// evaluate first three (always present) args
|
||||
|
||||
try {
|
||||
// evaluate first three (always present) args
|
||||
double rate = evalArg(args[0], srcRow, srcCol);
|
||||
double nper = evalArg(args[1], srcRow, srcCol);
|
||||
double pv = evalArg(args[2], srcRow, srcCol);
|
||||
double pv = evalArg(args[2], srcRow, srcCol);
|
||||
double fv = 0;
|
||||
boolean arePaymentsAtPeriodBeginning = false;
|
||||
|
||||
|
||||
switch (args.length) {
|
||||
case 5:
|
||||
ValueEval ve = singleOperandNumericAsBoolean(args[4], srcRow, srcCol);
|
||||
@ -67,10 +67,10 @@ public final class Pmt extends FinanceFunction {
|
||||
}
|
||||
double d = FinanceLib.pmt(rate, nper, pv, fv, arePaymentsAtPeriodBeginning);
|
||||
if (Double.isNaN(d)) {
|
||||
return (ValueEval) ErrorEval.VALUE_INVALID;
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
if (Double.isInfinite(d)) {
|
||||
return (ValueEval) ErrorEval.NUM_ERROR;
|
||||
return ErrorEval.NUM_ERROR;
|
||||
}
|
||||
return new NumberEval(d);
|
||||
} catch (EvaluationException e) {
|
||||
|
@ -26,94 +26,39 @@ import org.apache.poi.hssf.record.cf.BorderFormatting;
|
||||
* @author Dmitriy Kumshayev
|
||||
*
|
||||
*/
|
||||
public class HSSFBorderFormatting
|
||||
public final class HSSFBorderFormatting
|
||||
{
|
||||
/**
|
||||
* No border
|
||||
*/
|
||||
/** 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;
|
||||
|
||||
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 BorderFormatting borderFormatting;
|
||||
|
||||
private final BorderFormatting borderFormatting;
|
||||
|
||||
public HSSFBorderFormatting()
|
||||
{
|
||||
@ -124,5 +69,124 @@ public class HSSFBorderFormatting
|
||||
{
|
||||
return borderFormatting;
|
||||
}
|
||||
|
||||
|
||||
public short getBorderBottom()
|
||||
{
|
||||
return borderFormatting.getBorderBottom();
|
||||
}
|
||||
|
||||
public short getBorderDiagonal()
|
||||
{
|
||||
return borderFormatting.getBorderDiagonal();
|
||||
}
|
||||
|
||||
public short getBorderLeft()
|
||||
{
|
||||
return borderFormatting.getBorderLeft();
|
||||
}
|
||||
|
||||
public short getBorderRight()
|
||||
{
|
||||
return borderFormatting.getBorderRight();
|
||||
}
|
||||
|
||||
public short getBorderTop()
|
||||
{
|
||||
return borderFormatting.getBorderTop();
|
||||
}
|
||||
|
||||
public short getBottomBorderColor()
|
||||
{
|
||||
return borderFormatting.getBottomBorderColor();
|
||||
}
|
||||
|
||||
public short getDiagonalBorderColor()
|
||||
{
|
||||
return borderFormatting.getDiagonalBorderColor();
|
||||
}
|
||||
|
||||
public short getLeftBorderColor()
|
||||
{
|
||||
return borderFormatting.getLeftBorderColor();
|
||||
}
|
||||
|
||||
public short getRightBorderColor()
|
||||
{
|
||||
return borderFormatting.getRightBorderColor();
|
||||
}
|
||||
|
||||
public short getTopBorderColor()
|
||||
{
|
||||
return borderFormatting.getTopBorderColor();
|
||||
}
|
||||
|
||||
public boolean isBackwardDiagonalOn()
|
||||
{
|
||||
return borderFormatting.isBackwardDiagonalOn();
|
||||
}
|
||||
|
||||
public boolean isForwardDiagonalOn()
|
||||
{
|
||||
return borderFormatting.isForwardDiagonalOn();
|
||||
}
|
||||
|
||||
public void setBackwardDiagonalOn(boolean on)
|
||||
{
|
||||
borderFormatting.setBackwardDiagonalOn(on);
|
||||
}
|
||||
|
||||
public void setBorderBottom(short border)
|
||||
{
|
||||
borderFormatting.setBorderBottom(border);
|
||||
}
|
||||
|
||||
public void setBorderDiagonal(short border)
|
||||
{
|
||||
borderFormatting.setBorderDiagonal(border);
|
||||
}
|
||||
|
||||
public void setBorderLeft(short border)
|
||||
{
|
||||
borderFormatting.setBorderLeft(border);
|
||||
}
|
||||
|
||||
public void setBorderRight(short border)
|
||||
{
|
||||
borderFormatting.setBorderRight(border);
|
||||
}
|
||||
|
||||
public void setBorderTop(short border)
|
||||
{
|
||||
borderFormatting.setBorderTop(border);
|
||||
}
|
||||
|
||||
public void setBottomBorderColor(short color)
|
||||
{
|
||||
borderFormatting.setBottomBorderColor(color);
|
||||
}
|
||||
|
||||
public void setDiagonalBorderColor(short color)
|
||||
{
|
||||
borderFormatting.setDiagonalBorderColor(color);
|
||||
}
|
||||
|
||||
public void setForwardDiagonalOn(boolean on)
|
||||
{
|
||||
borderFormatting.setForwardDiagonalOn(on);
|
||||
}
|
||||
|
||||
public void setLeftBorderColor(short color)
|
||||
{
|
||||
borderFormatting.setLeftBorderColor(color);
|
||||
}
|
||||
|
||||
public void setRightBorderColor(short color)
|
||||
{
|
||||
borderFormatting.setRightBorderColor(color);
|
||||
}
|
||||
|
||||
public void setTopBorderColor(short color)
|
||||
{
|
||||
borderFormatting.setTopBorderColor(color);
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,7 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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;
|
||||
@ -86,13 +84,9 @@ import org.apache.poi.hssf.util.Region;
|
||||
*/
|
||||
public final class HSSFConditionalFormatting
|
||||
{
|
||||
private final HSSFSheet sheet;
|
||||
private final Workbook workbook;
|
||||
private final CFRecordsAggregate cfAggregate;
|
||||
|
||||
HSSFConditionalFormatting(HSSFSheet sheet) {
|
||||
this(sheet, new CFRecordsAggregate());
|
||||
}
|
||||
|
||||
HSSFConditionalFormatting(HSSFSheet sheet, CFRecordsAggregate cfAggregate)
|
||||
{
|
||||
if(sheet == null) {
|
||||
@ -101,36 +95,25 @@ public final class HSSFConditionalFormatting
|
||||
if(cfAggregate == null) {
|
||||
throw new IllegalArgumentException("cfAggregate must not be null");
|
||||
}
|
||||
this.sheet = sheet;
|
||||
workbook = sheet.workbook.getWorkbook();
|
||||
this.cfAggregate = cfAggregate;
|
||||
}
|
||||
CFRecordsAggregate getCFRecordsAggregate() {
|
||||
return cfAggregate;
|
||||
}
|
||||
|
||||
public void setFormattingRegions(Region[] regions)
|
||||
{
|
||||
if( regions != null)
|
||||
{
|
||||
CFHeaderRecord header = cfAggregate.getHeader();
|
||||
header.setCellRanges(mergeCellRanges(toCellRangeList(regions)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array of <tt>Region</tt>s. never <code>null</code>
|
||||
* @return array of <tt>Region</tt>s. never <code>null</code>
|
||||
*/
|
||||
public Region[] getFormattingRegions()
|
||||
{
|
||||
CFHeaderRecord cfh = cfAggregate.getHeader();
|
||||
|
||||
List cellRanges = cfh.getCellRanges();
|
||||
|
||||
return toRegionArray(cellRanges);
|
||||
CellRange[] cellRanges = cfh.getCellRanges();
|
||||
return CellRange.convertCellRangesToRegions(cellRanges);
|
||||
}
|
||||
|
||||
/**
|
||||
* set a Conditional Formatting rule at position idx.
|
||||
* Replaces an existing Conditional Formatting rule at position idx.
|
||||
* Excel allows to create up to 3 Conditional Formatting rules.
|
||||
* This method can be useful to modify existing Conditional Formatting rules.
|
||||
*
|
||||
@ -139,11 +122,7 @@ public final class HSSFConditionalFormatting
|
||||
*/
|
||||
public void setRule(int idx, HSSFConditionalFormattingRule cfRule)
|
||||
{
|
||||
if (idx < 0 || idx > 2) {
|
||||
throw new IllegalArgumentException("idx must be between 0 and 2 but was ("
|
||||
+ idx + ")");
|
||||
}
|
||||
cfAggregate.getRules().set(idx, cfRule);
|
||||
cfAggregate.setRule(idx, cfRule.getCfRuleRecord());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,136 +132,24 @@ public final class HSSFConditionalFormatting
|
||||
*/
|
||||
public void addRule(HSSFConditionalFormattingRule cfRule)
|
||||
{
|
||||
cfAggregate.getRules().add(cfRule);
|
||||
cfAggregate.addRule(cfRule.getCfRuleRecord());
|
||||
}
|
||||
|
||||
/**
|
||||
* get a Conditional Formatting rule at position idx.
|
||||
* @param idx
|
||||
* @return a Conditional Formatting rule at position idx.
|
||||
* @return the Conditional Formatting rule at position idx.
|
||||
*/
|
||||
public HSSFConditionalFormattingRule getRule(int idx)
|
||||
{
|
||||
CFRuleRecord ruleRecord = (CFRuleRecord)cfAggregate.getRules().get(idx);
|
||||
return new HSSFConditionalFormattingRule(sheet.workbook, ruleRecord);
|
||||
CFRuleRecord ruleRecord = cfAggregate.getRule(idx);
|
||||
return new HSSFConditionalFormattingRule(workbook, ruleRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of Conditional Formatting rules.
|
||||
*/
|
||||
public int getNumbOfRules()
|
||||
public int getNumberOfRules()
|
||||
{
|
||||
return cfAggregate.getRules().size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do all possible cell merges between cells of the list so that:<br>
|
||||
* <li>if a cell range is completely inside of another cell range, it gets removed from the list
|
||||
* <li>if two cells have a shared border, merge them into one bigger cell range
|
||||
* @param cellRangeList
|
||||
* @return updated List of cell ranges
|
||||
*/
|
||||
private static List mergeCellRanges(List cellRangeList)
|
||||
{
|
||||
boolean merged = false;
|
||||
|
||||
do
|
||||
{
|
||||
merged = false;
|
||||
|
||||
if( cellRangeList.size()>1 )
|
||||
{
|
||||
for( int i=0; i<cellRangeList.size(); i++)
|
||||
{
|
||||
CellRange range1 = (CellRange)cellRangeList.get(i);
|
||||
for( int j=i+1; j<cellRangeList.size(); j++)
|
||||
{
|
||||
CellRange range2 = (CellRange)cellRangeList.get(j);
|
||||
|
||||
switch(range1.intersect(range2))
|
||||
{
|
||||
case CellRange.NO_INTERSECTION:
|
||||
{
|
||||
if( range1.hasSharedBorder(range2))
|
||||
{
|
||||
cellRangeList.set(i, range1.createEnclosingCellRange(range2));
|
||||
cellRangeList.remove(j--);
|
||||
merged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No intersection and no shared border: do nothing
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CellRange.OVERLAP:
|
||||
{
|
||||
// TODO split and re-merge the intersected area
|
||||
break;
|
||||
}
|
||||
case CellRange.INSIDE:
|
||||
{
|
||||
// Remove range2, since it is completely inside of range1
|
||||
cellRangeList.remove(j--);
|
||||
merged = true;
|
||||
break;
|
||||
}
|
||||
case CellRange.ENCLOSES:
|
||||
{
|
||||
// range2 encloses range1, so replace it with the enclosing one
|
||||
cellRangeList.set(i, range2);
|
||||
cellRangeList.remove(j--);
|
||||
merged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while( merged );
|
||||
|
||||
return cellRangeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a List of CellRange objects to an array of regions
|
||||
*
|
||||
* @param List of CellRange objects
|
||||
* @return regions
|
||||
*/
|
||||
private static Region[] toRegionArray(List cellRanges)
|
||||
{
|
||||
int size = cellRanges.size();
|
||||
Region[] regions = new Region[size];
|
||||
|
||||
for (int i = 0; i != size; i++)
|
||||
{
|
||||
CellRange cr = (CellRange) cellRanges.get(i);
|
||||
regions[i] = new Region(cr.getFirstRow(), cr.getFirstColumn(),
|
||||
cr.getLastRow(), cr.getLastColumn());
|
||||
}
|
||||
return regions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert array of regions to a List of CellRange objects
|
||||
*
|
||||
* @param regions
|
||||
* @return List of CellRange objects
|
||||
*/
|
||||
private static List toCellRangeList(Region[] regions)
|
||||
{
|
||||
List cellRangeList = new ArrayList();
|
||||
for( int i=0; i<regions.length; i++)
|
||||
{
|
||||
Region r = regions[i];
|
||||
CellRange cr = new CellRange(r.getRowFrom(), r.getRowTo(), r.getColumnFrom(), r
|
||||
.getColumnTo());
|
||||
cellRangeList.add(cr);
|
||||
}
|
||||
return cellRangeList;
|
||||
return cfAggregate.getNumberOfRules();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
|
@ -18,231 +18,105 @@
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
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;
|
||||
import org.apache.poi.hssf.record.cf.FontFormatting;
|
||||
import org.apache.poi.hssf.record.cf.PatternFormatting;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
|
||||
/**
|
||||
*
|
||||
* High level representation of Conditional Format
|
||||
* High level representation of Conditional Formatting Rule.
|
||||
* It allows to specify formula based conditions for the Conditional Formatting
|
||||
* and the formatting settings such as font, border and pattern.
|
||||
*
|
||||
* @author Dmitriy Kumshayev
|
||||
*/
|
||||
|
||||
public class HSSFConditionalFormattingRule
|
||||
public final class HSSFConditionalFormattingRule
|
||||
{
|
||||
public static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS;
|
||||
public static final byte FORMULA = CFRuleRecord.CONDITION_TYPE_FORMULA;
|
||||
private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS;
|
||||
|
||||
|
||||
public static final byte COMPARISON_OPERATOR_NO_COMPARISON = CFRuleRecord.COMPARISON_OPERATOR_NO_COMPARISON;
|
||||
public static final byte COMPARISON_OPERATOR_BETWEEN = CFRuleRecord.COMPARISON_OPERATOR_BETWEEN;
|
||||
public static final byte COMPARISON_OPERATOR_NOT_BETWEEN = CFRuleRecord.COMPARISON_OPERATOR_NOT_BETWEEN;
|
||||
public static final byte COMPARISON_OPERATOR_EQUAL = CFRuleRecord.COMPARISON_OPERATOR_EQUAL;
|
||||
public static final byte COMPARISON_OPERATOR_NOT_EQUAL = CFRuleRecord.COMPARISON_OPERATOR_NOT_EQUAL;
|
||||
public static final byte COMPARISON_OPERATOR_GT = CFRuleRecord.COMPARISON_OPERATOR_GT;
|
||||
public static final byte COMPARISON_OPERATOR_LT = CFRuleRecord.COMPARISON_OPERATOR_LT;
|
||||
public static final byte COMPARISON_OPERATOR_GE = CFRuleRecord.COMPARISON_OPERATOR_GE;
|
||||
public static final byte COMPARISON_OPERATOR_LE = CFRuleRecord.COMPARISON_OPERATOR_LE;
|
||||
|
||||
|
||||
|
||||
private CFRuleRecord cfRuleRecord;
|
||||
private HSSFWorkbook workbook;
|
||||
|
||||
private final CFRuleRecord cfRuleRecord;
|
||||
private final Workbook workbook;
|
||||
|
||||
HSSFConditionalFormattingRule(Workbook pWorkbook, CFRuleRecord pRuleRecord) {
|
||||
workbook = pWorkbook;
|
||||
cfRuleRecord = pRuleRecord;
|
||||
}
|
||||
HSSFConditionalFormattingRule(Workbook pWorkbook, CFRuleRecord pRuleRecord,
|
||||
HSSFFontFormatting fontFmt, HSSFBorderFormatting bordFmt, HSSFPatternFormatting patternFmt) {
|
||||
this(pWorkbook, pRuleRecord);
|
||||
setFontFormatting(fontFmt);
|
||||
setBorderFormatting(bordFmt);
|
||||
setPatternFormatting(patternFmt);
|
||||
}
|
||||
|
||||
CFRuleRecord getCfRuleRecord()
|
||||
{
|
||||
return cfRuleRecord;
|
||||
}
|
||||
|
||||
protected HSSFConditionalFormattingRule(HSSFWorkbook workbook)
|
||||
{
|
||||
this.workbook = workbook;
|
||||
this.cfRuleRecord = new CFRuleRecord();
|
||||
}
|
||||
|
||||
protected HSSFConditionalFormattingRule(HSSFWorkbook workbook, CFRuleRecord cfRuleRecord)
|
||||
{
|
||||
this.workbook = workbook;
|
||||
this.cfRuleRecord = cfRuleRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep Font Formatting unchanged for this Conditional Formatting Rule
|
||||
|
||||
/**
|
||||
* @param fontFmt pass <code>null</code> to signify 'font unchanged'
|
||||
*/
|
||||
public void setFontFormattingUnchanged()
|
||||
public void setFontFormatting(HSSFFontFormatting fontFmt)
|
||||
{
|
||||
cfRuleRecord.setFontFormattingUnchanged();
|
||||
FontFormatting block = fontFmt==null ? null : fontFmt.getFontFormattingBlock();
|
||||
cfRuleRecord.setFontFormatting(block);
|
||||
}
|
||||
/**
|
||||
* Keep Border Formatting unchanged for this Conditional Formatting Rule
|
||||
/**
|
||||
* @param borderFmt pass <code>null</code> to signify 'border unchanged'
|
||||
*/
|
||||
public void setBorderFormattingUnchanged()
|
||||
public void setBorderFormatting(HSSFBorderFormatting borderFmt)
|
||||
{
|
||||
cfRuleRecord.setBorderFormattingUnchanged();
|
||||
BorderFormatting block = borderFmt==null ? null : borderFmt.getBorderFormattingBlock();
|
||||
cfRuleRecord.setBorderFormatting(block);
|
||||
}
|
||||
/**
|
||||
* Keep Pattern Formatting unchanged for this Conditional Formatting Rule
|
||||
/**
|
||||
* @param patternFmt pass <code>null</code> to signify 'pattern unchanged'
|
||||
*/
|
||||
public void setPatternFormattingUnchanged()
|
||||
public void setPatternFormatting(HSSFPatternFormatting patternFmt)
|
||||
{
|
||||
cfRuleRecord.setPatternFormattingUnchanged();
|
||||
}
|
||||
|
||||
public void setFontFormatting(HSSFFontFormatting fontFormatting)
|
||||
{
|
||||
if( fontFormatting!=null )
|
||||
{
|
||||
cfRuleRecord.setFontFormatting(fontFormatting.getFontFormattingBlock());
|
||||
}
|
||||
else
|
||||
{
|
||||
setFontFormattingUnchanged();
|
||||
}
|
||||
}
|
||||
public void setBorderFormatting(HSSFBorderFormatting borderFormatting)
|
||||
{
|
||||
if( borderFormatting != null )
|
||||
{
|
||||
cfRuleRecord.setBorderFormatting(borderFormatting.getBorderFormattingBlock());
|
||||
}
|
||||
else
|
||||
{
|
||||
setBorderFormattingUnchanged();
|
||||
}
|
||||
}
|
||||
public void setPatternFormatting(HSSFPatternFormatting patternFormatting)
|
||||
{
|
||||
if( patternFormatting != null)
|
||||
{
|
||||
cfRuleRecord.setPatternFormatting(patternFormatting.getPatternFormattingBlock());
|
||||
}
|
||||
else
|
||||
{
|
||||
setPatternFormattingUnchanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCellComparisonCondition(byte comparisonOperation, String formula1, String formula2)
|
||||
{
|
||||
cfRuleRecord.setConditionType(CELL_COMPARISON);
|
||||
cfRuleRecord.setComparisonOperation(comparisonOperation);
|
||||
|
||||
// Formula 1
|
||||
setFormula1(formula1);
|
||||
|
||||
// Formula 2
|
||||
setFormula1(formula2);
|
||||
}
|
||||
|
||||
public void setFormulaCondition(String formula)
|
||||
{
|
||||
cfRuleRecord.setConditionType(FORMULA);
|
||||
// Formula 1
|
||||
setFormula1(formula);
|
||||
}
|
||||
|
||||
public void setFormula1(String formula)
|
||||
{
|
||||
// Formula 1
|
||||
if( formula != null)
|
||||
{
|
||||
Stack parsedExpression = parseFormula(formula);
|
||||
if( parsedExpression != null )
|
||||
{
|
||||
cfRuleRecord.setParsedExpression1(parsedExpression);
|
||||
}
|
||||
else
|
||||
{
|
||||
cfRuleRecord.setParsedExpression1(null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cfRuleRecord.setParsedExpression1(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFormula2(String formula)
|
||||
{
|
||||
// Formula 2
|
||||
if( formula != null)
|
||||
{
|
||||
Stack parsedExpression = parseFormula(formula);
|
||||
if( parsedExpression != null )
|
||||
{
|
||||
cfRuleRecord.setParsedExpression2(parsedExpression);
|
||||
}
|
||||
else
|
||||
{
|
||||
cfRuleRecord.setParsedExpression2(null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cfRuleRecord.setParsedExpression2(null);
|
||||
}
|
||||
PatternFormatting block = patternFmt==null ? null : patternFmt.getPatternFormattingBlock();
|
||||
cfRuleRecord.setPatternFormatting(block);
|
||||
}
|
||||
|
||||
public String getFormula1()
|
||||
{
|
||||
return toFormulaString(cfRuleRecord.getParsedExpression1());
|
||||
return toFormulaString(cfRuleRecord.getParsedExpression1());
|
||||
}
|
||||
|
||||
public String getFormula2()
|
||||
{
|
||||
byte conditionType = cfRuleRecord.getConditionType();
|
||||
switch(conditionType)
|
||||
{
|
||||
case CELL_COMPARISON:
|
||||
if (conditionType == CELL_COMPARISON) {
|
||||
byte comparisonOperation = cfRuleRecord.getComparisonOperation();
|
||||
switch(comparisonOperation)
|
||||
{
|
||||
byte comparisonOperation = cfRuleRecord.getComparisonOperation();
|
||||
switch(comparisonOperation)
|
||||
{
|
||||
case COMPARISON_OPERATOR_BETWEEN:
|
||||
case COMPARISON_OPERATOR_NOT_BETWEEN:
|
||||
return toFormulaString(cfRuleRecord.getParsedExpression2());
|
||||
}
|
||||
case ComparisonOperator.BETWEEN:
|
||||
case ComparisonOperator.NOT_BETWEEN:
|
||||
return toFormulaString(cfRuleRecord.getParsedExpression2());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String toFormulaString(List parsedExpression)
|
||||
private String toFormulaString(Ptg[] parsedExpression)
|
||||
{
|
||||
String formula = null;
|
||||
if(parsedExpression!=null)
|
||||
{
|
||||
formula = FormulaParser.toFormulaString(workbook.getWorkbook(),parsedExpression);
|
||||
formula = FormulaParser.toFormulaString(workbook, parsedExpression);
|
||||
}
|
||||
return formula;
|
||||
}
|
||||
|
||||
|
||||
private Stack parseFormula(String formula2)
|
||||
{
|
||||
FormulaParser parser =
|
||||
new FormulaParser(formula2, workbook.getWorkbook());
|
||||
parser.parse();
|
||||
|
||||
Stack parsedExpression = convertToTokenStack(parser.getRPNPtg());
|
||||
parsedExpression = convertToTokenStack(parser.getRPNPtg());
|
||||
return parsedExpression;
|
||||
}
|
||||
|
||||
private static Stack convertToTokenStack(Ptg[] ptgs)
|
||||
{
|
||||
if( ptgs != null)
|
||||
{
|
||||
Stack parsedExpression = new Stack();
|
||||
// fill the Ptg Stack with Ptgs of new formula
|
||||
for (int k = 0; k < ptgs.length; k++)
|
||||
{
|
||||
parsedExpression.push(ptgs[ k ]);
|
||||
}
|
||||
return parsedExpression;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class HSSFPatriarch
|
||||
*/
|
||||
HSSFPatriarch(HSSFSheet sheet, EscherAggregate boundAggregate)
|
||||
{
|
||||
this.boundAggregate = boundAggregate;
|
||||
this.boundAggregate = boundAggregate;
|
||||
this.sheet = sheet;
|
||||
}
|
||||
|
||||
@ -197,29 +197,29 @@ public class HSSFPatriarch
|
||||
* to work on some charts so far)
|
||||
*/
|
||||
public boolean containsChart() {
|
||||
// TODO - support charts properly in usermodel
|
||||
|
||||
// We're looking for a EscherOptRecord
|
||||
EscherOptRecord optRecord = (EscherOptRecord)
|
||||
boundAggregate.findFirstWithId(EscherOptRecord.RECORD_ID);
|
||||
if(optRecord == null) {
|
||||
// No opt record, can't have chart
|
||||
return false;
|
||||
}
|
||||
|
||||
for(Iterator it = optRecord.getEscherProperties().iterator(); it.hasNext();) {
|
||||
EscherProperty prop = (EscherProperty)it.next();
|
||||
if(prop.getPropertyNumber() == 896 && prop.isComplex()) {
|
||||
EscherComplexProperty cp = (EscherComplexProperty)prop;
|
||||
String str = StringUtil.getFromUnicodeLE(cp.getComplexData());
|
||||
System.err.println(str);
|
||||
if(str.equals("Chart 1\0")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO - support charts properly in usermodel
|
||||
|
||||
// We're looking for a EscherOptRecord
|
||||
EscherOptRecord optRecord = (EscherOptRecord)
|
||||
boundAggregate.findFirstWithId(EscherOptRecord.RECORD_ID);
|
||||
if(optRecord == null) {
|
||||
// No opt record, can't have chart
|
||||
return false;
|
||||
}
|
||||
|
||||
for(Iterator it = optRecord.getEscherProperties().iterator(); it.hasNext();) {
|
||||
EscherProperty prop = (EscherProperty)it.next();
|
||||
if(prop.getPropertyNumber() == 896 && prop.isComplex()) {
|
||||
EscherComplexProperty cp = (EscherComplexProperty)prop;
|
||||
String str = StringUtil.getFromUnicodeLE(cp.getComplexData());
|
||||
//System.err.println(str);
|
||||
if(str.equals("Chart 1\0")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,6 +258,6 @@ public class HSSFPatriarch
|
||||
* Returns the aggregate escher record we're bound to
|
||||
*/
|
||||
protected EscherAggregate _getBoundAggregate() {
|
||||
return boundAggregate;
|
||||
return boundAggregate;
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ 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.CellValueRecordInterface;
|
||||
import org.apache.poi.hssf.record.CFRuleRecord;
|
||||
import org.apache.poi.hssf.record.DVALRecord;
|
||||
import org.apache.poi.hssf.record.DVRecord;
|
||||
import org.apache.poi.hssf.record.EOFRecord;
|
||||
@ -1106,8 +1107,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
|
||||
* @param leftcol the left column to show in desktop window pane
|
||||
*/
|
||||
public void showInPane(short toprow, short leftcol){
|
||||
this.sheet.setTopRow((short)toprow);
|
||||
this.sheet.setLeftCol((short)leftcol);
|
||||
this.sheet.setTopRow(toprow);
|
||||
this.sheet.setLeftCol(leftcol);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1454,7 +1455,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
|
||||
int i = 0;
|
||||
while (iterator.hasNext()) {
|
||||
PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next();
|
||||
returnValue[i++] = (int)breakItem.main;
|
||||
returnValue[i++] = breakItem.main;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
@ -1822,7 +1823,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
|
||||
*
|
||||
* @return cell comment or <code>null</code> if not found
|
||||
*/
|
||||
public HSSFComment getCellComment(int row, int column){
|
||||
public HSSFComment getCellComment(int row, int column) {
|
||||
// Don't call findCellComment directly, otherwise
|
||||
// two calls to this method will result in two
|
||||
// new HSSFComment instances, which is bad
|
||||
@ -1846,25 +1847,26 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
|
||||
* with a cell comparison operator and
|
||||
* formatting rules such as font format, border format and pattern format
|
||||
*
|
||||
* @param comparisonOperation - one of the following values: <p>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_BETWEEN}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_BETWEEN}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_EQUAL}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_EQUAL}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_GT}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_LT}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_GE}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_LE}</li>
|
||||
* @param comparisonOperation - a constant value from
|
||||
* <tt>{@link HSSFConditionalFormattingRule.ComparisonOperator}</tt>: <p>
|
||||
* <ul>
|
||||
* <li>BETWEEN</li>
|
||||
* <li>NOT_BETWEEN</li>
|
||||
* <li>EQUAL</li>
|
||||
* <li>NOT_EQUAL</li>
|
||||
* <li>GT</li>
|
||||
* <li>LT</li>
|
||||
* <li>GE</li>
|
||||
* <li>LE</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* @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
|
||||
* @param bordFmt - border formatting rules
|
||||
* @param patternFmt - pattern formatting rules
|
||||
* @return
|
||||
*
|
||||
* @param fontFmt - font formatting rules (may be <code>null</code>)
|
||||
* @param bordFmt - border formatting rules (may be <code>null</code>)
|
||||
* @param patternFmt - pattern formatting rules (may be <code>null</code>)
|
||||
*/
|
||||
public HSSFConditionalFormattingRule createConditionalFormattingRule(
|
||||
byte comparisonOperation,
|
||||
@ -1872,14 +1874,11 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
|
||||
String formula2,
|
||||
HSSFFontFormatting fontFmt,
|
||||
HSSFBorderFormatting bordFmt,
|
||||
HSSFPatternFormatting patternFmt)
|
||||
{
|
||||
HSSFConditionalFormattingRule cf = new HSSFConditionalFormattingRule(workbook);
|
||||
cf.setFontFormatting(fontFmt);
|
||||
cf.setBorderFormatting(bordFmt);
|
||||
cf.setPatternFormatting(patternFmt);
|
||||
cf.setCellComparisonCondition(comparisonOperation, formula1, formula2);
|
||||
return cf;
|
||||
HSSFPatternFormatting patternFmt) {
|
||||
|
||||
Workbook wb = workbook.getWorkbook();
|
||||
CFRuleRecord rr = CFRuleRecord.create(wb, comparisonOperation, formula1, formula2);
|
||||
return new HSSFConditionalFormattingRule(wb, rr, fontFmt, bordFmt, patternFmt);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1888,38 +1887,19 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
|
||||
*
|
||||
* The formatting rules are applied by Excel when the value of the formula not equal to 0.
|
||||
*
|
||||
* @param comparisonOperation - one of the following values: <p>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_BETWEEN}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_BETWEEN}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_EQUAL}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_NOT_EQUAL}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_GT}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_LT}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_GE}</li>
|
||||
* <li>{@link HSSFConditionalFormattingRule#COMPARISON_OPERATOR_LE}</li>
|
||||
* </p>
|
||||
* @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
|
||||
* @param bordFmt - border formatting rules
|
||||
* @param patternFmt - pattern formatting rules
|
||||
* @return
|
||||
*
|
||||
* @param formula - formula for the valued, compared with the cell
|
||||
* @param fontFmt - font formatting rules (may be <code>null</code>)
|
||||
* @param bordFmt - border formatting rules (may be <code>null</code>)
|
||||
* @param patternFmt - pattern formatting rules (may be <code>null</code>)
|
||||
*/
|
||||
public HSSFConditionalFormattingRule createConditionalFormattingRule(
|
||||
String formula,
|
||||
HSSFFontFormatting fontFmt,
|
||||
HSSFBorderFormatting bordFmt,
|
||||
HSSFPatternFormatting patternFmt)
|
||||
{
|
||||
HSSFConditionalFormattingRule cf = new HSSFConditionalFormattingRule(workbook);
|
||||
cf.setFontFormatting(fontFmt);
|
||||
cf.setBorderFormatting(bordFmt);
|
||||
cf.setPatternFormatting(patternFmt);
|
||||
cf.setFormulaCondition(formula);
|
||||
return cf;
|
||||
HSSFPatternFormatting patternFmt) {
|
||||
Workbook wb = workbook.getWorkbook();
|
||||
CFRuleRecord rr = CFRuleRecord.create(wb, formula);
|
||||
return new HSSFConditionalFormattingRule(wb, rr, fontFmt, bordFmt, patternFmt);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1934,8 +1914,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
|
||||
* @param cf HSSFConditionalFormatting object
|
||||
* @return index of the new Conditional Formatting object
|
||||
*/
|
||||
public int addConditionalFormatting( HSSFConditionalFormatting cf )
|
||||
{
|
||||
public int addConditionalFormatting( HSSFConditionalFormatting cf ) {
|
||||
CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate();
|
||||
|
||||
return sheet.addConditionalFormatting(cfraClone);
|
||||
@ -1945,46 +1924,46 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
|
||||
* 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
|
||||
* @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 [] cfRules )
|
||||
{
|
||||
HSSFConditionalFormatting cf = new HSSFConditionalFormatting(this);
|
||||
cf.setFormattingRegions(regions);
|
||||
if( cfRules != null )
|
||||
{
|
||||
for( int i=0; i!= cfRules.length; i++ )
|
||||
{
|
||||
cf.addRule(cfRules[i]);
|
||||
}
|
||||
}
|
||||
return sheet.addConditionalFormatting(cf.getCFRecordsAggregate());
|
||||
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
|
||||
*
|
||||
* @param index
|
||||
* of the Conditional Formatting object to fetch
|
||||
* @return Conditional Formatting object
|
||||
*/
|
||||
|
||||
public HSSFConditionalFormatting getConditionalFormattingAt(int index)
|
||||
{
|
||||
public HSSFConditionalFormatting getConditionalFormattingAt(int index) {
|
||||
CFRecordsAggregate cf = sheet.getCFRecordsAggregateAt(index);
|
||||
if( cf != null )
|
||||
{
|
||||
return new HSSFConditionalFormatting(this,cf);
|
||||
if (cf == null) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return new HSSFConditionalFormatting(this,cf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of Conditional Formatting objects of the sheet
|
||||
*/
|
||||
public int getNumConditionalFormattings()
|
||||
{
|
||||
public int getNumConditionalFormattings() {
|
||||
return sheet.getNumConditionalFormattings();
|
||||
}
|
||||
|
||||
@ -1992,8 +1971,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
|
||||
* removes a Conditional Formatting object by index
|
||||
* @param index of a Conditional Formatting object to remove
|
||||
*/
|
||||
public void removeConditionalFormatting(int index)
|
||||
{
|
||||
public void removeConditionalFormatting(int index) {
|
||||
sheet.removeConditionalFormatting(index);
|
||||
}
|
||||
}
|
||||
|
@ -265,6 +265,31 @@ public abstract class Sheet {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified shape from this sheet.
|
||||
*
|
||||
* @param shape shape to be removed from this sheet, if present.
|
||||
* @return <tt>true</tt> if the shape was deleted.
|
||||
*/
|
||||
public boolean removeShape(Shape shape) {
|
||||
PPDrawing ppdrawing = getPPDrawing();
|
||||
|
||||
EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
|
||||
EscherContainerRecord spgr = null;
|
||||
|
||||
for (Iterator it = dg.getChildRecords().iterator(); it.hasNext();) {
|
||||
EscherRecord rec = (EscherRecord) it.next();
|
||||
if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
|
||||
spgr = (EscherContainerRecord) rec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(spgr == null) return false;
|
||||
|
||||
List lst = spgr.getChildRecords();
|
||||
return lst.remove(shape.getSpContainer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the master sheet .
|
||||
*/
|
||||
|
@ -26,6 +26,7 @@ import java.awt.Rectangle;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
@ -279,4 +280,31 @@ public class TestShapes extends TestCase {
|
||||
line = (Line)grshape[1];
|
||||
assertEquals(new Rectangle(300, 300, 500, 0), line.getAnchor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test functionality of Sheet.removeShape(Shape shape)
|
||||
*/
|
||||
public void testRemoveShapes() throws IOException {
|
||||
String file = System.getProperty("HSLF.testdata.path")+ "/with_textbox.ppt";
|
||||
SlideShow ppt = new SlideShow(new HSLFSlideShow(file));
|
||||
Slide sl = ppt.getSlides()[0];
|
||||
Shape[] sh = sl.getShapes();
|
||||
assertEquals("expected four shaped in " + file, 4, sh.length);
|
||||
//remove all
|
||||
for (int i = 0; i < sh.length; i++) {
|
||||
boolean ok = sl.removeShape(sh[i]);
|
||||
assertTrue("Failed to delete shape #" + i, ok);
|
||||
}
|
||||
//now Slide.getShapes() should return an empty array
|
||||
assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().length);
|
||||
|
||||
//serialize and read again. The file should be readable and contain no shapes
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ppt.write(out);
|
||||
out.close();
|
||||
|
||||
ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray()));
|
||||
sl = ppt.getSlides()[0];
|
||||
assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().length);
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.model;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
@ -54,7 +54,7 @@ import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
* Test the low level formula parser functionality. High level tests are to
|
||||
* Test the low level formula parser functionality. High level tests are to
|
||||
* be done via usermodel/HSSFCell.setFormulaValue() .
|
||||
* Some tests are also done in scratchpad, if they need
|
||||
* HSSFFormulaEvaluator, which is there
|
||||
@ -71,7 +71,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertNotNull("Ptg array should not be null", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public void testSimpleFormula() {
|
||||
FormulaParser fp = new FormulaParser("2+2",null);
|
||||
fp.parse();
|
||||
@ -86,9 +86,9 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertTrue("",(ptgs[0] instanceof IntPtg));
|
||||
assertTrue("",(ptgs[1] instanceof IntPtg));
|
||||
assertTrue("",(ptgs[2] instanceof AddPtg));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testFormulaWithSpace2() {
|
||||
Ptg[] ptgs;
|
||||
FormulaParser fp;
|
||||
@ -97,7 +97,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
ptgs = fp.getRPNPtg();
|
||||
assertTrue("five tokens expected, got "+ptgs.length,ptgs.length == 5);
|
||||
}
|
||||
|
||||
|
||||
public void testFormulaWithSpaceNRef() {
|
||||
Ptg[] ptgs;
|
||||
FormulaParser fp;
|
||||
@ -106,7 +106,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
ptgs = fp.getRPNPtg();
|
||||
assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2);
|
||||
}
|
||||
|
||||
|
||||
public void testFormulaWithString() {
|
||||
Ptg[] ptgs;
|
||||
FormulaParser fp;
|
||||
@ -172,7 +172,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make sure the ptgs are generated properly with two functions embedded
|
||||
*
|
||||
@ -225,7 +225,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertEquals("4 Ptgs expected", 4, asts.length);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bug Reported by xt-jens.riis@nokia.com (Jens Riis)
|
||||
* Refers to Bug <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=17582">#17582</a>
|
||||
@ -247,7 +247,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testSimpleLogical() {
|
||||
FormulaParser fp=new FormulaParser("IF(A1<A2,B1,B2)",null);
|
||||
fp.parse();
|
||||
@ -255,10 +255,10 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertTrue("Ptg array should not be null", ptgs !=null);
|
||||
assertEquals("Ptg array length", 9, ptgs.length);
|
||||
assertEquals("3rd Ptg is less than",LessThanPtg.class,ptgs[2].getClass());
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testParenIf() {
|
||||
FormulaParser fp=new FormulaParser("IF((A1+A2)<=3,\"yes\",\"no\")",null);
|
||||
fp.parse();
|
||||
@ -281,7 +281,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertEquals("15th Ptg is not the inner IF variable function ptg",FuncVarPtg.class,ptgs[14].getClass());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testMacroFunction() {
|
||||
Workbook w = Workbook.createWorkbook();
|
||||
FormulaParser fp = new FormulaParser("FOO()", w);
|
||||
@ -291,7 +291,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
// the name gets encoded as the first arg
|
||||
NamePtg tname = (NamePtg) ptg[0];
|
||||
assertEquals("FOO", tname.toFormulaString(w));
|
||||
|
||||
|
||||
AbstractFunctionPtg tfunc = (AbstractFunctionPtg) ptg[1];
|
||||
assertTrue(tfunc.isExternalFunction());
|
||||
}
|
||||
@ -302,9 +302,9 @@ public final class TestFormulaParser extends TestCase {
|
||||
Ptg[] ptg = fp.getRPNPtg();
|
||||
assertTrue("first ptg is string",ptg[0] instanceof StringPtg);
|
||||
assertTrue("second ptg is string",ptg[1] instanceof StringPtg);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testConcatenate(){
|
||||
FormulaParser fp = new FormulaParser("CONCATENATE(\"first\",\"second\")",null);
|
||||
fp.parse();
|
||||
@ -312,7 +312,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertTrue("first ptg is string",ptg[0] instanceof StringPtg);
|
||||
assertTrue("second ptg is string",ptg[1] instanceof StringPtg);
|
||||
}
|
||||
|
||||
|
||||
public void testWorksheetReferences()
|
||||
{
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
@ -330,7 +330,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
cell = row.createCell((short)1);
|
||||
cell.setCellFormula("'Quotes Needed Here &#$@'!A1");
|
||||
}
|
||||
|
||||
|
||||
public void testUnaryMinus()
|
||||
{
|
||||
FormulaParser fp = new FormulaParser("-A1", null);
|
||||
@ -340,7 +340,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertTrue("first ptg is reference",ptg[0] instanceof ReferencePtg);
|
||||
assertTrue("second ptg is Minus",ptg[1] instanceof UnaryMinusPtg);
|
||||
}
|
||||
|
||||
|
||||
public void testUnaryPlus()
|
||||
{
|
||||
FormulaParser fp = new FormulaParser("+A1", null);
|
||||
@ -350,14 +350,14 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertTrue("first ptg is reference",ptg[0] instanceof ReferencePtg);
|
||||
assertTrue("second ptg is Plus",ptg[1] instanceof UnaryPlusPtg);
|
||||
}
|
||||
|
||||
|
||||
public void testLeadingSpaceInString()
|
||||
{
|
||||
String value = " hi ";
|
||||
FormulaParser fp = new FormulaParser("\"" + value + "\"", null);
|
||||
fp.parse();
|
||||
Ptg[] ptg = fp.getRPNPtg();
|
||||
|
||||
|
||||
assertTrue("got 1 ptg", ptg.length == 1);
|
||||
assertTrue("ptg0 is a StringPtg", ptg[0] instanceof StringPtg);
|
||||
assertTrue("ptg0 contains exact value", ((StringPtg)ptg[0]).getValue().equals(value));
|
||||
@ -368,14 +368,14 @@ public final class TestFormulaParser extends TestCase {
|
||||
FormulaParser fp = new FormulaParser("lookup(A1, A3:A52, B3:B52)", null);
|
||||
fp.parse();
|
||||
Ptg[] ptg = fp.getRPNPtg();
|
||||
|
||||
|
||||
assertTrue("got 4 ptg", ptg.length == 4);
|
||||
assertTrue("ptg0 has Value class", ptg[0].getPtgClass() == Ptg.CLASS_VALUE);
|
||||
|
||||
fp = new FormulaParser("match(A1, A3:A52)", null);
|
||||
fp.parse();
|
||||
ptg = fp.getRPNPtg();
|
||||
|
||||
|
||||
assertTrue("got 3 ptg", ptg.length == 3);
|
||||
assertTrue("ptg0 has Value class", ptg[0].getPtgClass() == Ptg.CLASS_VALUE);
|
||||
}
|
||||
@ -521,77 +521,77 @@ public final class TestFormulaParser extends TestCase {
|
||||
System.out.println("Testing org.apache.poi.hssf.record.formula.FormulaParser");
|
||||
junit.textui.TestRunner.run(TestFormulaParser.class);
|
||||
}
|
||||
|
||||
|
||||
public void testNumbers() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
|
||||
|
||||
wb.createSheet("Cash_Flow");
|
||||
|
||||
|
||||
HSSFSheet sheet = wb.createSheet("Test");
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
HSSFCell cell = row.createCell((short)0);
|
||||
String formula = null;
|
||||
|
||||
|
||||
// starts from decimal point
|
||||
|
||||
|
||||
cell.setCellFormula(".1");
|
||||
formula = cell.getCellFormula();
|
||||
assertEquals("0.1", formula);
|
||||
|
||||
|
||||
cell.setCellFormula("+.1");
|
||||
formula = cell.getCellFormula();
|
||||
assertEquals("+0.1", formula);
|
||||
|
||||
|
||||
cell.setCellFormula("-.1");
|
||||
formula = cell.getCellFormula();
|
||||
assertEquals("-0.1", formula);
|
||||
|
||||
|
||||
// has exponent
|
||||
|
||||
|
||||
cell.setCellFormula("10E1");
|
||||
formula = cell.getCellFormula();
|
||||
assertEquals("100.0", formula);
|
||||
|
||||
|
||||
cell.setCellFormula("10E+1");
|
||||
formula = cell.getCellFormula();
|
||||
assertEquals("100.0", formula);
|
||||
|
||||
|
||||
cell.setCellFormula("10E-1");
|
||||
formula = cell.getCellFormula();
|
||||
assertEquals("1.0", formula);
|
||||
}
|
||||
|
||||
|
||||
public void testRanges() {
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
|
||||
|
||||
wb.createSheet("Cash_Flow");
|
||||
|
||||
|
||||
HSSFSheet sheet = wb.createSheet("Test");
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
HSSFCell cell = row.createCell((short)0);
|
||||
String formula = null;
|
||||
|
||||
|
||||
cell.setCellFormula("A1.A2");
|
||||
formula = cell.getCellFormula();
|
||||
assertEquals("A1:A2", formula);
|
||||
|
||||
|
||||
cell.setCellFormula("A1..A2");
|
||||
formula = cell.getCellFormula();
|
||||
assertEquals("A1:A2", formula);
|
||||
|
||||
|
||||
cell.setCellFormula("A1...A2");
|
||||
formula = cell.getCellFormula();
|
||||
assertEquals("A1:A2", formula);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for bug observable at svn revision 618865 (5-Feb-2008)<br/>
|
||||
* a formula consisting of a single no-arg function got rendered without the function braces
|
||||
*/
|
||||
public void testToFormulaStringZeroArgFunction() {
|
||||
|
||||
|
||||
Workbook book = Workbook.createWorkbook(); // not really used in this test
|
||||
|
||||
|
||||
Ptg[] ptgs = {
|
||||
new FuncPtg(10, 0),
|
||||
};
|
||||
@ -610,21 +610,21 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertEquals(2, ptgs.length);
|
||||
assertEquals(ptgs[0].getClass(), IntPtg.class);
|
||||
assertEquals(ptgs[1].getClass(), PercentPtg.class);
|
||||
|
||||
|
||||
// double percent OK
|
||||
|
||||
|
||||
// double percent OK
|
||||
ptgs = parseFormula("12345.678%%");
|
||||
assertEquals(3, ptgs.length);
|
||||
assertEquals(ptgs[0].getClass(), NumberPtg.class);
|
||||
assertEquals(ptgs[1].getClass(), PercentPtg.class);
|
||||
assertEquals(ptgs[2].getClass(), PercentPtg.class);
|
||||
|
||||
|
||||
// percent of a bracketed expression
|
||||
ptgs = parseFormula("(A1+35)%*B1%");
|
||||
assertEquals(8, ptgs.length);
|
||||
assertEquals(ptgs[4].getClass(), PercentPtg.class);
|
||||
assertEquals(ptgs[6].getClass(), PercentPtg.class);
|
||||
|
||||
|
||||
// percent of a text quantity
|
||||
ptgs = parseFormula("\"8.75\"%");
|
||||
assertEquals(2, ptgs.length);
|
||||
@ -641,64 +641,64 @@ public final class TestFormulaParser extends TestCase {
|
||||
|
||||
//
|
||||
// things that parse OK but would *evaluate* to an error
|
||||
|
||||
|
||||
ptgs = parseFormula("\"abc\"%");
|
||||
assertEquals(2, ptgs.length);
|
||||
assertEquals(ptgs[0].getClass(), StringPtg.class);
|
||||
assertEquals(ptgs[1].getClass(), PercentPtg.class);
|
||||
|
||||
|
||||
ptgs = parseFormula("#N/A%");
|
||||
assertEquals(2, ptgs.length);
|
||||
assertEquals(ptgs[0].getClass(), ErrPtg.class);
|
||||
assertEquals(ptgs[1].getClass(), PercentPtg.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests combinations of various operators in the absence of brackets
|
||||
*/
|
||||
public void testPrecedenceAndAssociativity() {
|
||||
|
||||
Class[] expClss;
|
||||
|
||||
|
||||
// TRUE=TRUE=2=2 evaluates to FALSE
|
||||
expClss = new Class[] { BoolPtg.class, BoolPtg.class, EqualPtg.class,
|
||||
expClss = new Class[] { BoolPtg.class, BoolPtg.class, EqualPtg.class,
|
||||
IntPtg.class, EqualPtg.class, IntPtg.class, EqualPtg.class, };
|
||||
confirmTokenClasses("TRUE=TRUE=2=2", expClss);
|
||||
|
||||
|
||||
|
||||
// 2^3^2 evaluates to 64 not 512
|
||||
expClss = new Class[] { IntPtg.class, IntPtg.class, PowerPtg.class,
|
||||
expClss = new Class[] { IntPtg.class, IntPtg.class, PowerPtg.class,
|
||||
IntPtg.class, PowerPtg.class, };
|
||||
confirmTokenClasses("2^3^2", expClss);
|
||||
|
||||
|
||||
// "abc" & 2 + 3 & "def" evaluates to "abc5def"
|
||||
expClss = new Class[] { StringPtg.class, IntPtg.class, IntPtg.class,
|
||||
expClss = new Class[] { StringPtg.class, IntPtg.class, IntPtg.class,
|
||||
AddPtg.class, ConcatPtg.class, StringPtg.class, ConcatPtg.class, };
|
||||
confirmTokenClasses("\"abc\"&2+3&\"def\"", expClss);
|
||||
|
||||
|
||||
|
||||
|
||||
// (1 / 2) - (3 * 4)
|
||||
expClss = new Class[] { IntPtg.class, IntPtg.class, DividePtg.class,
|
||||
expClss = new Class[] { IntPtg.class, IntPtg.class, DividePtg.class,
|
||||
IntPtg.class, IntPtg.class, MultiplyPtg.class, SubtractPtg.class, };
|
||||
confirmTokenClasses("1/2-3*4", expClss);
|
||||
|
||||
|
||||
// 2 * (2^2)
|
||||
expClss = new Class[] { IntPtg.class, IntPtg.class, IntPtg.class, PowerPtg.class, MultiplyPtg.class, };
|
||||
// NOT: (2 *2) ^ 2 -> int int multiply int power
|
||||
confirmTokenClasses("2*2^2", expClss);
|
||||
|
||||
|
||||
// 2^200% -> 2 not 1.6E58
|
||||
expClss = new Class[] { IntPtg.class, IntPtg.class, PercentPtg.class, PowerPtg.class, };
|
||||
confirmTokenClasses("2^200%", expClss);
|
||||
}
|
||||
|
||||
|
||||
private static void confirmTokenClasses(String formula, Class[] expectedClasses) {
|
||||
Ptg[] ptgs = parseFormula(formula);
|
||||
assertEquals(expectedClasses.length, ptgs.length);
|
||||
for (int i = 0; i < expectedClasses.length; i++) {
|
||||
if(expectedClasses[i] != ptgs[i].getClass()) {
|
||||
fail("difference at token[" + i + "]: expected ("
|
||||
+ expectedClasses[i].getName() + ") but got ("
|
||||
+ expectedClasses[i].getName() + ") but got ("
|
||||
+ ptgs[i].getClass().getName() + ")");
|
||||
}
|
||||
}
|
||||
@ -718,38 +718,38 @@ public final class TestFormulaParser extends TestCase {
|
||||
|
||||
public void testParseNumber() {
|
||||
IntPtg ip;
|
||||
|
||||
|
||||
// bug 33160
|
||||
ip = (IntPtg) parseSingleToken("40", IntPtg.class);
|
||||
assertEquals(40, ip.getValue());
|
||||
ip = (IntPtg) parseSingleToken("40000", IntPtg.class);
|
||||
assertEquals(40000, ip.getValue());
|
||||
|
||||
|
||||
// check the upper edge of the IntPtg range:
|
||||
ip = (IntPtg) parseSingleToken("65535", IntPtg.class);
|
||||
assertEquals(65535, ip.getValue());
|
||||
NumberPtg np = (NumberPtg) parseSingleToken("65536", NumberPtg.class);
|
||||
assertEquals(65536, np.getValue(), 0);
|
||||
|
||||
|
||||
np = (NumberPtg) parseSingleToken("65534.6", NumberPtg.class);
|
||||
assertEquals(65534.6, np.getValue(), 0);
|
||||
}
|
||||
|
||||
|
||||
public void testMissingArgs() {
|
||||
|
||||
|
||||
Class[] expClss;
|
||||
|
||||
expClss = new Class[] { ReferencePtg.class, MissingArgPtg.class, ReferencePtg.class,
|
||||
|
||||
expClss = new Class[] { ReferencePtg.class, MissingArgPtg.class, ReferencePtg.class,
|
||||
FuncVarPtg.class, };
|
||||
confirmTokenClasses("if(A1, ,C1)", expClss);
|
||||
|
||||
|
||||
expClss = new Class[] { MissingArgPtg.class, AreaPtg.class, MissingArgPtg.class,
|
||||
FuncVarPtg.class, };
|
||||
confirmTokenClasses("counta( , A1:B2, )", expClss);
|
||||
}
|
||||
|
||||
public void testParseErrorLiterals() {
|
||||
|
||||
|
||||
confirmParseErrorLiteral(ErrPtg.NULL_INTERSECTION, "#NULL!");
|
||||
confirmParseErrorLiteral(ErrPtg.DIV_ZERO, "#DIV/0!");
|
||||
confirmParseErrorLiteral(ErrPtg.VALUE_INVALID, "#VALUE!");
|
||||
@ -762,7 +762,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
private static void confirmParseErrorLiteral(ErrPtg expectedToken, String formula) {
|
||||
assertEquals(expectedToken, parseSingleToken(formula, ErrPtg.class));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* To aid readability the parameters have been encoded with single quotes instead of double
|
||||
* quotes. This method converts single quotes to double quotes before performing the parse
|
||||
@ -772,23 +772,23 @@ public final class TestFormulaParser extends TestCase {
|
||||
// formula: internal quotes become double double, surround with double quotes
|
||||
String formula = '"' + singleQuotedValue.replaceAll("'", "\"\"") + '"';
|
||||
String expectedValue = singleQuotedValue.replace('\'', '"');
|
||||
|
||||
|
||||
StringPtg sp = (StringPtg) parseSingleToken(formula, StringPtg.class);
|
||||
assertEquals(expectedValue, sp.getValue());
|
||||
}
|
||||
|
||||
|
||||
public void testPaseStringLiterals() {
|
||||
confirmStringParse("goto considered harmful");
|
||||
|
||||
|
||||
confirmStringParse("goto 'considered' harmful");
|
||||
|
||||
|
||||
confirmStringParse("");
|
||||
confirmStringParse("'");
|
||||
confirmStringParse("''");
|
||||
confirmStringParse("' '");
|
||||
confirmStringParse(" ' ");
|
||||
}
|
||||
|
||||
|
||||
public void testParseSumIfSum() {
|
||||
String formulaString;
|
||||
Ptg[] ptgs;
|
||||
@ -809,14 +809,14 @@ public final class TestFormulaParser extends TestCase {
|
||||
parseExpectedException("1 + #N / A * 2");
|
||||
parseExpectedException("#value?");
|
||||
parseExpectedException("#DIV/ 0+2");
|
||||
|
||||
|
||||
|
||||
|
||||
if (false) { // TODO - add functionality to detect func arg count mismatch
|
||||
parseExpectedException("IF(TRUE)");
|
||||
parseExpectedException("countif(A1:B5, C1, D1)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void parseExpectedException(String formula) {
|
||||
try {
|
||||
parseFormula(formula);
|
||||
@ -831,11 +831,11 @@ public final class TestFormulaParser extends TestCase {
|
||||
}
|
||||
|
||||
public void testSetFormulaWithRowBeyond32768_Bug44539() {
|
||||
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
wb.setSheetName(0, "Sheet1");
|
||||
|
||||
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
HSSFCell cell = row.createCell((short)0);
|
||||
cell.setCellFormula("SUM(A32769:A32770)");
|
||||
@ -862,11 +862,11 @@ public final class TestFormulaParser extends TestCase {
|
||||
throw e;
|
||||
}
|
||||
// FormulaParser strips spaces anyway
|
||||
assertEquals("4", formulaString);
|
||||
assertEquals("4", formulaString);
|
||||
|
||||
ptgs = new Ptg[] { new IntPtg(3), spacePtg, new IntPtg(4), spacePtg, new AddPtg()};
|
||||
formulaString = FormulaParser.toFormulaString(null, ptgs);
|
||||
assertEquals("3+4", formulaString);
|
||||
assertEquals("3+4", formulaString);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -875,7 +875,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
public void testTooFewOperandArgs() {
|
||||
// Simulating badly encoded cell formula of "=/1"
|
||||
// Not sure if Excel could ever produce this
|
||||
Ptg[] ptgs = {
|
||||
Ptg[] ptgs = {
|
||||
// Excel would probably have put tMissArg here
|
||||
new IntPtg(1),
|
||||
new DividePtg(),
|
||||
|
@ -17,7 +17,9 @@
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.hssf.record.aggregates.AllRecordAggregateTests;
|
||||
import org.apache.poi.hssf.record.formula.AllFormulaTests;
|
||||
import org.apache.poi.hssf.record.formula.functions.AllIndividualFunctionEvaluationTests;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
@ -33,7 +35,8 @@ public final class AllRecordTests {
|
||||
TestSuite result = new TestSuite(AllRecordTests.class.getName());
|
||||
|
||||
result.addTest(AllFormulaTests.suite());
|
||||
|
||||
result.addTest(AllRecordAggregateTests.suite());
|
||||
|
||||
result.addTestSuite(TestAreaFormatRecord.class);
|
||||
result.addTestSuite(TestAreaRecord.class);
|
||||
result.addTestSuite(TestAxisLineFormatRecord.class);
|
||||
@ -45,6 +48,8 @@ public final class AllRecordTests {
|
||||
result.addTestSuite(TestBarRecord.class);
|
||||
result.addTestSuite(TestBoundSheetRecord.class);
|
||||
result.addTestSuite(TestCategorySeriesAxisRecord.class);
|
||||
result.addTestSuite(TestCFHeaderRecord.class);
|
||||
result.addTestSuite(TestCFRuleRecord.class);
|
||||
result.addTestSuite(TestChartRecord.class);
|
||||
result.addTestSuite(TestChartTitleFormatRecord.class);
|
||||
result.addTestSuite(TestCommonObjectDataSubRecord.class);
|
||||
|
@ -17,9 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.record.cf.CellRange;
|
||||
@ -30,116 +27,114 @@ import org.apache.poi.hssf.record.cf.CellRange;
|
||||
*
|
||||
* @author Dmitriy Kumshayev
|
||||
*/
|
||||
public class TestCFHeaderRecord
|
||||
extends TestCase
|
||||
public final class TestCFHeaderRecord extends TestCase
|
||||
{
|
||||
|
||||
public TestCFHeaderRecord(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
public void testCreateCFHeaderRecord ()
|
||||
{
|
||||
CFHeaderRecord record = new CFHeaderRecord();
|
||||
CellRange[] ranges = {
|
||||
new CellRange(0,-1,5,5),
|
||||
new CellRange(0,-1,6,6),
|
||||
new CellRange(0,1,0,1),
|
||||
new CellRange(0,1,2,3),
|
||||
new CellRange(2,3,0,1),
|
||||
new CellRange(2,3,2,3),
|
||||
};
|
||||
record.setCellRanges(ranges);
|
||||
ranges = record.getCellRanges();
|
||||
assertEquals(6,ranges.length);
|
||||
CellRange enclosingCellRange = record.getEnclosingCellRange();
|
||||
assertEquals(0, enclosingCellRange.getFirstRow());
|
||||
assertEquals(-1, enclosingCellRange.getLastRow());
|
||||
assertEquals(0, enclosingCellRange.getFirstColumn());
|
||||
assertEquals(6, enclosingCellRange.getLastColumn());
|
||||
record.setNeedRecalculation(true);
|
||||
assertTrue(record.getNeedRecalculation());
|
||||
record.setNeedRecalculation(false);
|
||||
assertFalse(record.getNeedRecalculation());
|
||||
}
|
||||
|
||||
public void testSerialization() {
|
||||
byte[] recordData = new byte[]
|
||||
{
|
||||
(byte)0x03, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
|
||||
(byte)0x04, (byte)0x00,
|
||||
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
(byte)0x02, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
|
||||
(byte)0x02, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
|
||||
(byte)0x02, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
(byte)0x02, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
};
|
||||
|
||||
CFHeaderRecord record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData));
|
||||
|
||||
assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats());
|
||||
assertTrue(record.getNeedRecalculation());
|
||||
CellRange enclosingCellRange = record.getEnclosingCellRange();
|
||||
assertEquals(0, enclosingCellRange.getFirstRow());
|
||||
assertEquals(3, enclosingCellRange.getLastRow());
|
||||
assertEquals(0, enclosingCellRange.getFirstColumn());
|
||||
assertEquals(3, enclosingCellRange.getLastColumn());
|
||||
CellRange[] ranges = record.getCellRanges();
|
||||
CellRange range0 = ranges[0];
|
||||
assertEquals(0, range0.getFirstRow());
|
||||
assertEquals(1, range0.getLastRow());
|
||||
assertEquals(0, range0.getFirstColumn());
|
||||
assertEquals(1, range0.getLastColumn());
|
||||
CellRange range1 = ranges[1];
|
||||
assertEquals(0, range1.getFirstRow());
|
||||
assertEquals(1, range1.getLastRow());
|
||||
assertEquals(2, range1.getFirstColumn());
|
||||
assertEquals(3, range1.getLastColumn());
|
||||
CellRange range2 = ranges[2];
|
||||
assertEquals(2, range2.getFirstRow());
|
||||
assertEquals(3, range2.getLastRow());
|
||||
assertEquals(0, range2.getFirstColumn());
|
||||
assertEquals(1, range2.getLastColumn());
|
||||
CellRange range3 = ranges[3];
|
||||
assertEquals(2, range3.getFirstRow());
|
||||
assertEquals(3, range3.getLastRow());
|
||||
assertEquals(2, range3.getFirstColumn());
|
||||
assertEquals(3, range3.getLastColumn());
|
||||
assertEquals(recordData.length+4, record.getRecordSize());
|
||||
|
||||
public void testCreateCFHeaderRecord ()
|
||||
{
|
||||
CFHeaderRecord record = new CFHeaderRecord();
|
||||
List ranges = new ArrayList();
|
||||
ranges.add(new CellRange(0,-1,(short)5,(short)5));
|
||||
ranges.add(new CellRange(0,-1,(short)6,(short)6));
|
||||
ranges.add(new CellRange(0,1,(short)0,(short)1));
|
||||
ranges.add(new CellRange(0,1,(short)2,(short)3));
|
||||
ranges.add(new CellRange(2,3,(short)0,(short)1));
|
||||
ranges.add(new CellRange(2,3,(short)2,(short)3));
|
||||
record.setCellRanges(ranges);
|
||||
ranges = record.getCellRanges();
|
||||
assertEquals(6,ranges.size());
|
||||
CellRange enclosingCellRange = record.getEnclosingCellRange();
|
||||
assertEquals(0, enclosingCellRange.getFirstRow());
|
||||
assertEquals(-1, enclosingCellRange.getLastRow());
|
||||
assertEquals(0, enclosingCellRange.getFirstColumn());
|
||||
assertEquals(6, enclosingCellRange.getLastColumn());
|
||||
record.setNeedRecalculation(true);
|
||||
assertTrue(record.getNeedRecalculation());
|
||||
record.setNeedRecalculation(false);
|
||||
assertFalse(record.getNeedRecalculation());
|
||||
}
|
||||
|
||||
public void testSerialization() {
|
||||
byte[] recordData = new byte[]
|
||||
{
|
||||
(byte)0x03, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
|
||||
(byte)0x04, (byte)0x00,
|
||||
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
(byte)0x02, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
|
||||
(byte)0x02, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00,
|
||||
(byte)0x01, (byte)0x00,
|
||||
|
||||
(byte)0x02, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
(byte)0x02, (byte)0x00,
|
||||
(byte)0x03, (byte)0x00,
|
||||
};
|
||||
|
||||
CFHeaderRecord record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData));
|
||||
|
||||
assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats());
|
||||
assertTrue(record.getNeedRecalculation());
|
||||
CellRange enclosingCellRange = record.getEnclosingCellRange();
|
||||
assertEquals(0, enclosingCellRange.getFirstRow());
|
||||
assertEquals(3, enclosingCellRange.getLastRow());
|
||||
assertEquals(0, enclosingCellRange.getFirstColumn());
|
||||
assertEquals(3, enclosingCellRange.getLastColumn());
|
||||
List ranges = record.getCellRanges();
|
||||
assertEquals(0, ((CellRange)ranges.get(0)).getFirstRow());
|
||||
assertEquals(1, ((CellRange)ranges.get(0)).getLastRow());
|
||||
assertEquals(0, ((CellRange)ranges.get(0)).getFirstColumn());
|
||||
assertEquals(1, ((CellRange)ranges.get(0)).getLastColumn());
|
||||
assertEquals(0, ((CellRange)ranges.get(1)).getFirstRow());
|
||||
assertEquals(1, ((CellRange)ranges.get(1)).getLastRow());
|
||||
assertEquals(2, ((CellRange)ranges.get(1)).getFirstColumn());
|
||||
assertEquals(3, ((CellRange)ranges.get(1)).getLastColumn());
|
||||
assertEquals(2, ((CellRange)ranges.get(2)).getFirstRow());
|
||||
assertEquals(3, ((CellRange)ranges.get(2)).getLastRow());
|
||||
assertEquals(0, ((CellRange)ranges.get(2)).getFirstColumn());
|
||||
assertEquals(1, ((CellRange)ranges.get(2)).getLastColumn());
|
||||
assertEquals(2, ((CellRange)ranges.get(3)).getFirstRow());
|
||||
assertEquals(3, ((CellRange)ranges.get(3)).getLastRow());
|
||||
assertEquals(2, ((CellRange)ranges.get(3)).getFirstColumn());
|
||||
assertEquals(3, ((CellRange)ranges.get(3)).getLastColumn());
|
||||
assertEquals(recordData.length+4, record.getRecordSize());
|
||||
|
||||
byte[] output = record.serialize();
|
||||
|
||||
|
||||
assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength
|
||||
|
||||
|
||||
for (int i = 0; i < recordData.length;i++)
|
||||
{
|
||||
assertEquals("CFHeaderRecord doesn't match", recordData[i], output[i+4]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] ignored_args)
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] ignored_args)
|
||||
{
|
||||
System.out.println("Testing org.apache.poi.hssf.record.CFHeaderRecord");
|
||||
junit.textui.TestRunner.run(TestCFHeaderRecord.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,109 +19,107 @@ package org.apache.poi.hssf.record;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
|
||||
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.hssf.util.HSSFColor;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* Tests the serialization and deserialization of the TestCFRuleRecord
|
||||
* class works correctly.
|
||||
* class works correctly.
|
||||
*
|
||||
* @author Dmitriy Kumshayev
|
||||
*/
|
||||
public class TestCFRuleRecord
|
||||
extends TestCase
|
||||
public final class TestCFRuleRecord extends TestCase
|
||||
{
|
||||
|
||||
public TestCFRuleRecord(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
public void testCreateCFRuleRecord ()
|
||||
{
|
||||
Workbook workbook = Workbook.createWorkbook();
|
||||
CFRuleRecord record = CFRuleRecord.create(workbook, "7");
|
||||
testCFRuleRecord(record);
|
||||
|
||||
public void testCreateCFRuleRecord ()
|
||||
{
|
||||
CFRuleRecord record = new CFRuleRecord();
|
||||
testCFRuleRecord(record);
|
||||
|
||||
// Serialize
|
||||
byte [] serializedRecord = record.serialize();
|
||||
// Serialize
|
||||
byte [] serializedRecord = record.serialize();
|
||||
|
||||
// Strip header
|
||||
byte [] recordData = new byte[serializedRecord.length-4];
|
||||
System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length);
|
||||
|
||||
// Deserialize
|
||||
record = new CFRuleRecord(new TestcaseRecordInputStream(CFRuleRecord.sid, (short)recordData.length, recordData));
|
||||
|
||||
// Serialize again
|
||||
// Strip header
|
||||
byte [] recordData = new byte[serializedRecord.length-4];
|
||||
System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length);
|
||||
|
||||
// Deserialize
|
||||
record = new CFRuleRecord(new TestcaseRecordInputStream(CFRuleRecord.sid, (short)recordData.length, recordData));
|
||||
|
||||
// Serialize again
|
||||
byte[] output = record.serialize();
|
||||
|
||||
|
||||
// Compare
|
||||
assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength
|
||||
|
||||
|
||||
for (int i = 0; i < recordData.length;i++)
|
||||
{
|
||||
assertEquals("CFRuleRecord doesn't match", recordData[i], output[i+4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testCFRuleRecord(CFRuleRecord record)
|
||||
{
|
||||
FontFormatting fontFormatting = new FontFormatting();
|
||||
testFontFormattingAccessors(fontFormatting);
|
||||
assertFalse(record.containsFontFormattingBlock());
|
||||
record.setFontFormatting(fontFormatting);
|
||||
assertTrue(record.containsFontFormattingBlock());
|
||||
|
||||
BorderFormatting borderFormatting = new BorderFormatting();
|
||||
testBorderFormattingAccessors(borderFormatting);
|
||||
assertFalse(record.containsBorderFormattingBlock());
|
||||
record.setBorderFormatting(borderFormatting);
|
||||
assertTrue(record.containsBorderFormattingBlock());
|
||||
|
||||
assertFalse(record.isLeftBorderModified());
|
||||
record.setLeftBorderModified(true);
|
||||
assertTrue(record.isLeftBorderModified());
|
||||
|
||||
assertFalse(record.isRightBorderModified());
|
||||
record.setRightBorderModified(true);
|
||||
assertTrue(record.isRightBorderModified());
|
||||
|
||||
assertFalse(record.isTopBorderModified());
|
||||
record.setTopBorderModified(true);
|
||||
assertTrue(record.isTopBorderModified());
|
||||
|
||||
assertFalse(record.isBottomBorderModified());
|
||||
record.setBottomBorderModified(true);
|
||||
assertTrue(record.isBottomBorderModified());
|
||||
|
||||
assertFalse(record.isTopLeftBottomRightBorderModified());
|
||||
record.setTopLeftBottomRightBorderModified(true);
|
||||
assertTrue(record.isTopLeftBottomRightBorderModified());
|
||||
|
||||
assertFalse(record.isBottomLeftTopRightBorderModified());
|
||||
record.setBottomLeftTopRightBorderModified(true);
|
||||
assertTrue(record.isBottomLeftTopRightBorderModified());
|
||||
|
||||
|
||||
PatternFormatting patternFormatting = new PatternFormatting();
|
||||
testPatternFormattingAccessors(patternFormatting);
|
||||
assertFalse(record.containsPatternFormattingBlock());
|
||||
record.setPatternFormatting(patternFormatting);
|
||||
assertTrue(record.containsPatternFormattingBlock());
|
||||
|
||||
assertFalse(record.isPatternBackgroundColorModified());
|
||||
record.setPatternBackgroundColorModified(true);
|
||||
assertTrue(record.isPatternBackgroundColorModified());
|
||||
|
||||
assertFalse(record.isPatternColorModified());
|
||||
record.setPatternColorModified(true);
|
||||
assertTrue(record.isPatternColorModified());
|
||||
testFontFormattingAccessors(fontFormatting);
|
||||
assertFalse(record.containsFontFormattingBlock());
|
||||
record.setFontFormatting(fontFormatting);
|
||||
assertTrue(record.containsFontFormattingBlock());
|
||||
|
||||
assertFalse(record.isPatternStyleModified());
|
||||
record.setPatternStyleModified(true);
|
||||
assertTrue(record.isPatternStyleModified());
|
||||
BorderFormatting borderFormatting = new BorderFormatting();
|
||||
testBorderFormattingAccessors(borderFormatting);
|
||||
assertFalse(record.containsBorderFormattingBlock());
|
||||
record.setBorderFormatting(borderFormatting);
|
||||
assertTrue(record.containsBorderFormattingBlock());
|
||||
|
||||
assertFalse(record.isLeftBorderModified());
|
||||
record.setLeftBorderModified(true);
|
||||
assertTrue(record.isLeftBorderModified());
|
||||
|
||||
assertFalse(record.isRightBorderModified());
|
||||
record.setRightBorderModified(true);
|
||||
assertTrue(record.isRightBorderModified());
|
||||
|
||||
assertFalse(record.isTopBorderModified());
|
||||
record.setTopBorderModified(true);
|
||||
assertTrue(record.isTopBorderModified());
|
||||
|
||||
assertFalse(record.isBottomBorderModified());
|
||||
record.setBottomBorderModified(true);
|
||||
assertTrue(record.isBottomBorderModified());
|
||||
|
||||
assertFalse(record.isTopLeftBottomRightBorderModified());
|
||||
record.setTopLeftBottomRightBorderModified(true);
|
||||
assertTrue(record.isTopLeftBottomRightBorderModified());
|
||||
|
||||
assertFalse(record.isBottomLeftTopRightBorderModified());
|
||||
record.setBottomLeftTopRightBorderModified(true);
|
||||
assertTrue(record.isBottomLeftTopRightBorderModified());
|
||||
|
||||
|
||||
PatternFormatting patternFormatting = new PatternFormatting();
|
||||
testPatternFormattingAccessors(patternFormatting);
|
||||
assertFalse(record.containsPatternFormattingBlock());
|
||||
record.setPatternFormatting(patternFormatting);
|
||||
assertTrue(record.containsPatternFormattingBlock());
|
||||
|
||||
assertFalse(record.isPatternBackgroundColorModified());
|
||||
record.setPatternBackgroundColorModified(true);
|
||||
assertTrue(record.isPatternBackgroundColorModified());
|
||||
|
||||
assertFalse(record.isPatternColorModified());
|
||||
record.setPatternColorModified(true);
|
||||
assertTrue(record.isPatternColorModified());
|
||||
|
||||
assertFalse(record.isPatternStyleModified());
|
||||
record.setPatternStyleModified(true);
|
||||
assertTrue(record.isPatternStyleModified());
|
||||
}
|
||||
|
||||
private void testPatternFormattingAccessors(PatternFormatting patternFormatting)
|
||||
@ -131,10 +129,9 @@ public class TestCFRuleRecord
|
||||
|
||||
patternFormatting.setFillForegroundColor(HSSFColor.INDIGO.index);
|
||||
assertEquals(HSSFColor.INDIGO.index,patternFormatting.getFillForegroundColor());
|
||||
|
||||
|
||||
patternFormatting.setFillPattern(PatternFormatting.DIAMONDS);
|
||||
assertEquals(PatternFormatting.DIAMONDS,patternFormatting.getFillPattern());
|
||||
|
||||
}
|
||||
|
||||
private void testBorderFormattingAccessors(BorderFormatting borderFormatting)
|
||||
@ -143,13 +140,13 @@ public class TestCFRuleRecord
|
||||
assertFalse(borderFormatting.isBackwardDiagonalOn());
|
||||
borderFormatting.setBackwardDiagonalOn(true);
|
||||
assertTrue(borderFormatting.isBackwardDiagonalOn());
|
||||
|
||||
|
||||
borderFormatting.setBorderBottom(BorderFormatting.BORDER_DOTTED);
|
||||
assertEquals(BorderFormatting.BORDER_DOTTED, borderFormatting.getBorderBottom());
|
||||
|
||||
|
||||
borderFormatting.setBorderDiagonal(BorderFormatting.BORDER_MEDIUM);
|
||||
assertEquals(BorderFormatting.BORDER_MEDIUM, borderFormatting.getBorderDiagonal());
|
||||
|
||||
|
||||
borderFormatting.setBorderLeft(BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT);
|
||||
assertEquals(BorderFormatting.BORDER_MEDIUM_DASH_DOT_DOT, borderFormatting.getBorderLeft());
|
||||
|
||||
@ -178,119 +175,137 @@ public class TestCFRuleRecord
|
||||
borderFormatting.setTopBorderColor(HSSFColor.GOLD.index);
|
||||
assertEquals(HSSFColor.GOLD.index, borderFormatting.getTopBorderColor());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void testFontFormattingAccessors(FontFormatting fontFormatting)
|
||||
{
|
||||
// Check for defaults
|
||||
assertFalse(fontFormatting.isEscapementTypeModified());
|
||||
assertFalse(fontFormatting.isFontCancellationModified());
|
||||
assertFalse(fontFormatting.isFontCondenseModified());
|
||||
assertFalse(fontFormatting.isFontOutlineModified());
|
||||
assertFalse(fontFormatting.isFontShadowModified());
|
||||
assertFalse(fontFormatting.isFontStyleModified());
|
||||
assertFalse(fontFormatting.isUnderlineTypeModified());
|
||||
|
||||
assertFalse(fontFormatting.isBold());
|
||||
assertFalse(fontFormatting.isCondenseOn());
|
||||
assertFalse(fontFormatting.isItalic());
|
||||
assertFalse(fontFormatting.isOutlineOn());
|
||||
assertFalse(fontFormatting.isShadowOn());
|
||||
assertFalse(fontFormatting.isStruckout());
|
||||
assertFalse(fontFormatting.isEscapementTypeModified());
|
||||
assertFalse(fontFormatting.isFontCancellationModified());
|
||||
assertFalse(fontFormatting.isFontCondenseModified());
|
||||
assertFalse(fontFormatting.isFontOutlineModified());
|
||||
assertFalse(fontFormatting.isFontShadowModified());
|
||||
assertFalse(fontFormatting.isFontStyleModified());
|
||||
assertFalse(fontFormatting.isUnderlineTypeModified());
|
||||
|
||||
assertEquals(0, fontFormatting.getEscapementType());
|
||||
assertEquals(-1, fontFormatting.getFontColorIndex());
|
||||
assertEquals(-1, fontFormatting.getFontHeight());
|
||||
assertEquals(400, fontFormatting.getFontWeight());
|
||||
assertEquals(0, fontFormatting.getUnderlineType());
|
||||
|
||||
fontFormatting.setBold(true);
|
||||
assertTrue(fontFormatting.isBold());
|
||||
fontFormatting.setBold(false);
|
||||
assertFalse(fontFormatting.isBold());
|
||||
|
||||
fontFormatting.setCondense(true);
|
||||
assertTrue(fontFormatting.isCondenseOn());
|
||||
fontFormatting.setCondense(false);
|
||||
assertFalse(fontFormatting.isCondenseOn());
|
||||
|
||||
fontFormatting.setEscapementType(FontFormatting.SS_SUB);
|
||||
assertEquals(FontFormatting.SS_SUB, fontFormatting.getEscapementType());
|
||||
fontFormatting.setEscapementType(FontFormatting.SS_SUPER);
|
||||
assertEquals(FontFormatting.SS_SUPER, fontFormatting.getEscapementType());
|
||||
fontFormatting.setEscapementType(FontFormatting.SS_NONE);
|
||||
assertEquals(FontFormatting.SS_NONE, fontFormatting.getEscapementType());
|
||||
|
||||
fontFormatting.setEscapementTypeModified(false);
|
||||
assertFalse(fontFormatting.isEscapementTypeModified());
|
||||
fontFormatting.setEscapementTypeModified(true);
|
||||
assertTrue(fontFormatting.isEscapementTypeModified());
|
||||
assertFalse(fontFormatting.isBold());
|
||||
assertFalse(fontFormatting.isCondenseOn());
|
||||
assertFalse(fontFormatting.isItalic());
|
||||
assertFalse(fontFormatting.isOutlineOn());
|
||||
assertFalse(fontFormatting.isShadowOn());
|
||||
assertFalse(fontFormatting.isStruckout());
|
||||
|
||||
fontFormatting.setFontCancellationModified(false);
|
||||
assertFalse(fontFormatting.isFontCancellationModified());
|
||||
fontFormatting.setFontCancellationModified(true);
|
||||
assertTrue(fontFormatting.isFontCancellationModified());
|
||||
|
||||
fontFormatting.setFontColorIndex((short)10);
|
||||
assertEquals(10,fontFormatting.getFontColorIndex());
|
||||
assertEquals(0, fontFormatting.getEscapementType());
|
||||
assertEquals(-1, fontFormatting.getFontColorIndex());
|
||||
assertEquals(-1, fontFormatting.getFontHeight());
|
||||
assertEquals(400, fontFormatting.getFontWeight());
|
||||
assertEquals(0, fontFormatting.getUnderlineType());
|
||||
|
||||
fontFormatting.setFontCondenseModified(false);
|
||||
assertFalse(fontFormatting.isFontCondenseModified());
|
||||
fontFormatting.setFontCondenseModified(true);
|
||||
assertTrue(fontFormatting.isFontCondenseModified());
|
||||
|
||||
fontFormatting.setFontHeight((short)100);
|
||||
assertEquals(100,fontFormatting.getFontHeight());
|
||||
|
||||
fontFormatting.setFontOutlineModified(false);
|
||||
assertFalse(fontFormatting.isFontOutlineModified());
|
||||
fontFormatting.setFontOutlineModified(true);
|
||||
assertTrue(fontFormatting.isFontOutlineModified());
|
||||
fontFormatting.setBold(true);
|
||||
assertTrue(fontFormatting.isBold());
|
||||
fontFormatting.setBold(false);
|
||||
assertFalse(fontFormatting.isBold());
|
||||
|
||||
fontFormatting.setFontShadowModified(false);
|
||||
assertFalse(fontFormatting.isFontShadowModified());
|
||||
fontFormatting.setFontShadowModified(true);
|
||||
assertTrue(fontFormatting.isFontShadowModified());
|
||||
fontFormatting.setCondense(true);
|
||||
assertTrue(fontFormatting.isCondenseOn());
|
||||
fontFormatting.setCondense(false);
|
||||
assertFalse(fontFormatting.isCondenseOn());
|
||||
|
||||
fontFormatting.setFontStyleModified(false);
|
||||
assertFalse(fontFormatting.isFontStyleModified());
|
||||
fontFormatting.setFontStyleModified(true);
|
||||
assertTrue(fontFormatting.isFontStyleModified());
|
||||
fontFormatting.setEscapementType(FontFormatting.SS_SUB);
|
||||
assertEquals(FontFormatting.SS_SUB, fontFormatting.getEscapementType());
|
||||
fontFormatting.setEscapementType(FontFormatting.SS_SUPER);
|
||||
assertEquals(FontFormatting.SS_SUPER, fontFormatting.getEscapementType());
|
||||
fontFormatting.setEscapementType(FontFormatting.SS_NONE);
|
||||
assertEquals(FontFormatting.SS_NONE, fontFormatting.getEscapementType());
|
||||
|
||||
fontFormatting.setItalic(false);
|
||||
assertFalse(fontFormatting.isItalic());
|
||||
fontFormatting.setItalic(true);
|
||||
assertTrue(fontFormatting.isItalic());
|
||||
fontFormatting.setEscapementTypeModified(false);
|
||||
assertFalse(fontFormatting.isEscapementTypeModified());
|
||||
fontFormatting.setEscapementTypeModified(true);
|
||||
assertTrue(fontFormatting.isEscapementTypeModified());
|
||||
|
||||
fontFormatting.setOutline(false);
|
||||
assertFalse(fontFormatting.isOutlineOn());
|
||||
fontFormatting.setOutline(true);
|
||||
assertTrue(fontFormatting.isOutlineOn());
|
||||
fontFormatting.setFontCancellationModified(false);
|
||||
assertFalse(fontFormatting.isFontCancellationModified());
|
||||
fontFormatting.setFontCancellationModified(true);
|
||||
assertTrue(fontFormatting.isFontCancellationModified());
|
||||
|
||||
fontFormatting.setShadow(false);
|
||||
assertFalse(fontFormatting.isShadowOn());
|
||||
fontFormatting.setShadow(true);
|
||||
assertTrue(fontFormatting.isShadowOn());
|
||||
|
||||
fontFormatting.setStrikeout(false);
|
||||
assertFalse(fontFormatting.isStruckout());
|
||||
fontFormatting.setStrikeout(true);
|
||||
assertTrue(fontFormatting.isStruckout());
|
||||
|
||||
fontFormatting.setUnderlineType(FontFormatting.U_DOUBLE_ACCOUNTING);
|
||||
assertEquals(FontFormatting.U_DOUBLE_ACCOUNTING, fontFormatting.getUnderlineType());
|
||||
fontFormatting.setFontColorIndex((short)10);
|
||||
assertEquals(10,fontFormatting.getFontColorIndex());
|
||||
|
||||
fontFormatting.setUnderlineTypeModified(false);
|
||||
assertFalse(fontFormatting.isUnderlineTypeModified());
|
||||
fontFormatting.setUnderlineTypeModified(true);
|
||||
assertTrue(fontFormatting.isUnderlineTypeModified());
|
||||
fontFormatting.setFontCondenseModified(false);
|
||||
assertFalse(fontFormatting.isFontCondenseModified());
|
||||
fontFormatting.setFontCondenseModified(true);
|
||||
assertTrue(fontFormatting.isFontCondenseModified());
|
||||
|
||||
fontFormatting.setFontHeight((short)100);
|
||||
assertEquals(100,fontFormatting.getFontHeight());
|
||||
|
||||
fontFormatting.setFontOutlineModified(false);
|
||||
assertFalse(fontFormatting.isFontOutlineModified());
|
||||
fontFormatting.setFontOutlineModified(true);
|
||||
assertTrue(fontFormatting.isFontOutlineModified());
|
||||
|
||||
fontFormatting.setFontShadowModified(false);
|
||||
assertFalse(fontFormatting.isFontShadowModified());
|
||||
fontFormatting.setFontShadowModified(true);
|
||||
assertTrue(fontFormatting.isFontShadowModified());
|
||||
|
||||
fontFormatting.setFontStyleModified(false);
|
||||
assertFalse(fontFormatting.isFontStyleModified());
|
||||
fontFormatting.setFontStyleModified(true);
|
||||
assertTrue(fontFormatting.isFontStyleModified());
|
||||
|
||||
fontFormatting.setItalic(false);
|
||||
assertFalse(fontFormatting.isItalic());
|
||||
fontFormatting.setItalic(true);
|
||||
assertTrue(fontFormatting.isItalic());
|
||||
|
||||
fontFormatting.setOutline(false);
|
||||
assertFalse(fontFormatting.isOutlineOn());
|
||||
fontFormatting.setOutline(true);
|
||||
assertTrue(fontFormatting.isOutlineOn());
|
||||
|
||||
fontFormatting.setShadow(false);
|
||||
assertFalse(fontFormatting.isShadowOn());
|
||||
fontFormatting.setShadow(true);
|
||||
assertTrue(fontFormatting.isShadowOn());
|
||||
|
||||
fontFormatting.setStrikeout(false);
|
||||
assertFalse(fontFormatting.isStruckout());
|
||||
fontFormatting.setStrikeout(true);
|
||||
assertTrue(fontFormatting.isStruckout());
|
||||
|
||||
fontFormatting.setUnderlineType(FontFormatting.U_DOUBLE_ACCOUNTING);
|
||||
assertEquals(FontFormatting.U_DOUBLE_ACCOUNTING, fontFormatting.getUnderlineType());
|
||||
|
||||
fontFormatting.setUnderlineTypeModified(false);
|
||||
assertFalse(fontFormatting.isUnderlineTypeModified());
|
||||
fontFormatting.setUnderlineTypeModified(true);
|
||||
assertTrue(fontFormatting.isUnderlineTypeModified());
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] ignored_args)
|
||||
|
||||
public void testWrite() {
|
||||
Workbook workbook = Workbook.createWorkbook();
|
||||
CFRuleRecord rr = CFRuleRecord.create(workbook, ComparisonOperator.BETWEEN, "5", "10");
|
||||
|
||||
PatternFormatting patternFormatting = new PatternFormatting();
|
||||
patternFormatting.setFillPattern(PatternFormatting.BRICKS);
|
||||
rr.setPatternFormatting(patternFormatting);
|
||||
|
||||
byte[] data = rr.serialize();
|
||||
assertEquals(26, data.length);
|
||||
assertEquals(3, LittleEndian.getShort(data, 6));
|
||||
assertEquals(3, LittleEndian.getShort(data, 8));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] ignored_args)
|
||||
{
|
||||
System.out.println("Testing org.apache.poi.hssf.record.CFRuleRecord");
|
||||
junit.textui.TestRunner.run(TestCFRuleRecord.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public final class TestExternalNameRecord extends TestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testBasicSize() {
|
||||
ExternalNameRecord enr = createSimpleENR();
|
||||
if(enr.getRecordSize() == 13) {
|
||||
|
@ -0,0 +1,40 @@
|
||||
/* ====================================================================
|
||||
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.record.aggregates;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Collects all tests for package <tt>org.apache.poi.hssf.record.aggregates</tt>.
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class AllRecordAggregateTests {
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite result = new TestSuite(AllRecordAggregateTests.class.getName());
|
||||
|
||||
result.addTestSuite(TestCFRecordsAggregate.class);
|
||||
result.addTestSuite(TestColumnInfoRecordsAggregate.class);
|
||||
result.addTestSuite(TestFormulaRecordAggregate.class);
|
||||
result.addTestSuite(TestRowRecordsAggregate.class);
|
||||
result.addTestSuite(TestValueRecordsAggregate.class);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -24,9 +24,11 @@ import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
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.RecordFactory;
|
||||
import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
|
||||
import org.apache.poi.hssf.record.cf.CellRange;
|
||||
|
||||
/**
|
||||
@ -35,77 +37,71 @@ import org.apache.poi.hssf.record.cf.CellRange;
|
||||
*
|
||||
* @author Dmitriy Kumshayev
|
||||
*/
|
||||
public class TestCFRecordsAggregate
|
||||
extends TestCase
|
||||
public final class TestCFRecordsAggregate extends TestCase
|
||||
{
|
||||
|
||||
public TestCFRecordsAggregate(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
public void testCFRecordsAggregate()
|
||||
{
|
||||
Workbook workbook = Workbook.createWorkbook();
|
||||
List recs = new ArrayList();
|
||||
CFHeaderRecord header = new CFHeaderRecord();
|
||||
CFRuleRecord rule1 = CFRuleRecord.create(workbook, "7");
|
||||
CFRuleRecord rule2 = CFRuleRecord.create(workbook, ComparisonOperator.BETWEEN, "2", "5");
|
||||
CFRuleRecord rule3 = CFRuleRecord.create(workbook, ComparisonOperator.GE, "100", null);
|
||||
header.setNumberOfConditionalFormats(3);
|
||||
CellRange[] cellRanges = {
|
||||
new CellRange(0,1,0,0),
|
||||
new CellRange(0,1,2,2),
|
||||
};
|
||||
header.setCellRanges(cellRanges);
|
||||
recs.add(header);
|
||||
recs.add(rule1);
|
||||
recs.add(rule2);
|
||||
recs.add(rule3);
|
||||
CFRecordsAggregate record;
|
||||
record = CFRecordsAggregate.createCFAggregate(recs, 0);
|
||||
|
||||
public void testCFRecordsAggregate()
|
||||
{
|
||||
CFRecordsAggregate record = new CFRecordsAggregate();
|
||||
List recs = new ArrayList();
|
||||
CFHeaderRecord header = new CFHeaderRecord();
|
||||
CFRuleRecord rule1 = new CFRuleRecord();
|
||||
CFRuleRecord rule2 = new CFRuleRecord();
|
||||
CFRuleRecord rule3 = new CFRuleRecord();
|
||||
header.setNumberOfConditionalFormats(3);
|
||||
CellRange range1 = new CellRange(0,1,(short)0,(short)0);
|
||||
CellRange range2 = new CellRange(0,1,(short)2,(short)2);
|
||||
List cellRanges = new ArrayList();
|
||||
cellRanges.add(range1);
|
||||
cellRanges.add(range2);
|
||||
header.setCellRanges(cellRanges);
|
||||
recs.add(header);
|
||||
recs.add(rule1);
|
||||
recs.add(rule2);
|
||||
recs.add(rule3);
|
||||
record = CFRecordsAggregate.createCFAggregate(recs, 0);
|
||||
|
||||
// Serialize
|
||||
byte [] serializedRecord = record.serialize();
|
||||
InputStream in = new ByteArrayInputStream(serializedRecord);
|
||||
|
||||
//Parse
|
||||
recs = RecordFactory.createRecords(in);
|
||||
|
||||
// Verify
|
||||
assertNotNull(recs);
|
||||
assertEquals(4, recs.size());
|
||||
|
||||
header = (CFHeaderRecord)recs.get(0);
|
||||
rule1 = (CFRuleRecord)recs.get(1);
|
||||
rule2 = (CFRuleRecord)recs.get(2);
|
||||
rule3 = (CFRuleRecord)recs.get(3);
|
||||
cellRanges = header.getCellRanges();
|
||||
|
||||
assertEquals(2, cellRanges.size());
|
||||
assertEquals(3, header.getNumberOfConditionalFormats());
|
||||
|
||||
record = CFRecordsAggregate.createCFAggregate(recs, 0);
|
||||
|
||||
record = record.cloneCFAggregate();
|
||||
|
||||
assertNotNull(record.getHeader());
|
||||
assertEquals(3,record.getRules().size());
|
||||
|
||||
header = record.getHeader();
|
||||
rule1 = (CFRuleRecord)record.getRules().get(0);
|
||||
rule2 = (CFRuleRecord)record.getRules().get(1);
|
||||
rule3 = (CFRuleRecord)record.getRules().get(2);
|
||||
cellRanges = header.getCellRanges();
|
||||
|
||||
assertEquals(2, cellRanges.size());
|
||||
assertEquals(3, header.getNumberOfConditionalFormats());
|
||||
}
|
||||
// Serialize
|
||||
byte [] serializedRecord = record.serialize();
|
||||
InputStream in = new ByteArrayInputStream(serializedRecord);
|
||||
|
||||
public static void main(String[] ignored_args)
|
||||
//Parse
|
||||
recs = RecordFactory.createRecords(in);
|
||||
|
||||
// Verify
|
||||
assertNotNull(recs);
|
||||
assertEquals(4, recs.size());
|
||||
|
||||
header = (CFHeaderRecord)recs.get(0);
|
||||
rule1 = (CFRuleRecord)recs.get(1);
|
||||
rule2 = (CFRuleRecord)recs.get(2);
|
||||
rule3 = (CFRuleRecord)recs.get(3);
|
||||
cellRanges = header.getCellRanges();
|
||||
|
||||
assertEquals(2, cellRanges.length);
|
||||
assertEquals(3, header.getNumberOfConditionalFormats());
|
||||
|
||||
record = CFRecordsAggregate.createCFAggregate(recs, 0);
|
||||
|
||||
record = record.cloneCFAggregate();
|
||||
|
||||
assertNotNull(record.getHeader());
|
||||
assertEquals(3,record.getNumberOfRules());
|
||||
|
||||
header = record.getHeader();
|
||||
rule1 = record.getRule(0);
|
||||
rule2 = record.getRule(1);
|
||||
rule3 = record.getRule(2);
|
||||
cellRanges = header.getCellRanges();
|
||||
|
||||
assertEquals(2, cellRanges.length);
|
||||
assertEquals(3, header.getNumberOfConditionalFormats());
|
||||
}
|
||||
|
||||
public static void main(String[] ignored_args)
|
||||
{
|
||||
System.out.println("Testing org.apache.poi.hssf.record.aggregates.CFRecordsAggregate");
|
||||
junit.textui.TestRunner.run(TestCFRecordsAggregate.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import org.apache.poi.hssf.record.ColumnInfoRecord;
|
||||
/**
|
||||
* @author Glen Stampoultzis
|
||||
*/
|
||||
public class TestColumnInfoRecordsAggregate extends TestCase
|
||||
public final class TestColumnInfoRecordsAggregate extends TestCase
|
||||
{
|
||||
ColumnInfoRecordsAggregate columnInfoRecordsAggregate;
|
||||
|
||||
@ -35,7 +35,7 @@ public class TestColumnInfoRecordsAggregate extends TestCase
|
||||
columnInfoRecordsAggregate.insertColumn( createColumn( (short)8, (short)8 ));
|
||||
// columnInfoRecordsAggregate.setColumn( (short)2, new Short( (short)200 ), new Integer( 1 ), new Boolean( true ), null);
|
||||
columnInfoRecordsAggregate.groupColumnRange( (short)2, (short)5, true );
|
||||
System.out.println( "columnInfoRecordsAggregate = " + columnInfoRecordsAggregate.getNumColumns() );
|
||||
assertEquals(6, columnInfoRecordsAggregate.getNumColumns());
|
||||
|
||||
assertEquals(columnInfoRecordsAggregate.getRecordSize(), columnInfoRecordsAggregate.serialize().length);
|
||||
|
||||
|
@ -24,13 +24,13 @@ import junit.framework.TestCase;
|
||||
*/
|
||||
public class TestCellRange extends TestCase
|
||||
{
|
||||
private static final CellRange biggest = new CellRange(0, -1,(short) 0,(short)-1);
|
||||
private static final CellRange tenthColumn = new CellRange(0, -1,(short)10,(short)10);
|
||||
private static final CellRange tenthRow = new CellRange(10,10,(short) 0,(short)-1);
|
||||
private static final CellRange box10x10 = new CellRange(0, 10,(short) 0,(short)10);
|
||||
private static final CellRange box9x9 = new CellRange(0, 9,(short) 0,(short) 9);
|
||||
private static final CellRange box10to20c = new CellRange(0, 10,(short)10,(short)20);
|
||||
private static final CellRange oneCell = new CellRange(10,10,(short)10,(short)10);
|
||||
private static final CellRange biggest = new CellRange( 0, -1, 0,-1);
|
||||
private static final CellRange tenthColumn = new CellRange( 0, -1,10,10);
|
||||
private static final CellRange tenthRow = new CellRange(10, 10, 0,-1);
|
||||
private static final CellRange box10x10 = new CellRange( 0, 10, 0,10);
|
||||
private static final CellRange box9x9 = new CellRange( 0, 9, 0, 9);
|
||||
private static final CellRange box10to20c = new CellRange( 0, 10,10,20);
|
||||
private static final CellRange oneCell = new CellRange(10, 10,10,10);
|
||||
|
||||
boolean [][] contanis = new boolean[][]
|
||||
{
|
||||
@ -61,62 +61,62 @@ public class TestCellRange extends TestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final CellRange col1 = new CellRange(0, -1,(short) 1,(short)1);
|
||||
private static final CellRange col2 = new CellRange(0, -1,(short) 2,(short)2);
|
||||
private static final CellRange row1 = new CellRange(1, 1,(short) 0,(short)-1);
|
||||
private static final CellRange row2 = new CellRange(2, 2,(short) 0,(short)-1);
|
||||
|
||||
private static final CellRange box0 = new CellRange( 0, 2,(short) 0,(short)2);
|
||||
private static final CellRange box1 = new CellRange( 0, 1,(short) 0,(short)1);
|
||||
private static final CellRange box2 = new CellRange( 0, 1,(short) 2,(short)3);
|
||||
private static final CellRange box3 = new CellRange( 2, 3,(short) 0,(short)1);
|
||||
private static final CellRange box4 = new CellRange( 2, 3,(short) 2,(short)3);
|
||||
private static final CellRange box5 = new CellRange( 1, 3,(short) 1,(short)3);
|
||||
private static final CellRange col1 = new CellRange( 0, -1, 1,1);
|
||||
private static final CellRange col2 = new CellRange( 0, -1, 2,2);
|
||||
private static final CellRange row1 = new CellRange( 1, 1, 0,-1);
|
||||
private static final CellRange row2 = new CellRange( 2, 2, 0,-1);
|
||||
|
||||
private static final CellRange box0 = new CellRange( 0, 2, 0,2);
|
||||
private static final CellRange box1 = new CellRange( 0, 1, 0,1);
|
||||
private static final CellRange box2 = new CellRange( 0, 1, 2,3);
|
||||
private static final CellRange box3 = new CellRange( 2, 3, 0,1);
|
||||
private static final CellRange box4 = new CellRange( 2, 3, 2,3);
|
||||
private static final CellRange box5 = new CellRange( 1, 3, 1,3);
|
||||
|
||||
public void testHasSharedBorderMethod()
|
||||
{
|
||||
assertFalse(col1.hasSharedBorder(col1));
|
||||
assertFalse(col2.hasSharedBorder(col2));
|
||||
assertTrue(col1.hasSharedBorder(col2));
|
||||
assertTrue(col2.hasSharedBorder(col1));
|
||||
assertFalse(col1.hasExactSharedBorder(col1));
|
||||
assertFalse(col2.hasExactSharedBorder(col2));
|
||||
assertTrue(col1.hasExactSharedBorder(col2));
|
||||
assertTrue(col2.hasExactSharedBorder(col1));
|
||||
|
||||
assertFalse(row1.hasSharedBorder(row1));
|
||||
assertFalse(row2.hasSharedBorder(row2));
|
||||
assertTrue(row1.hasSharedBorder(row2));
|
||||
assertTrue(row2.hasSharedBorder(row1));
|
||||
assertFalse(row1.hasExactSharedBorder(row1));
|
||||
assertFalse(row2.hasExactSharedBorder(row2));
|
||||
assertTrue(row1.hasExactSharedBorder(row2));
|
||||
assertTrue(row2.hasExactSharedBorder(row1));
|
||||
|
||||
assertFalse(row1.hasSharedBorder(col1));
|
||||
assertFalse(row1.hasSharedBorder(col2));
|
||||
assertFalse(col1.hasSharedBorder(row1));
|
||||
assertFalse(col2.hasSharedBorder(row1));
|
||||
assertFalse(row2.hasSharedBorder(col1));
|
||||
assertFalse(row2.hasSharedBorder(col2));
|
||||
assertFalse(col1.hasSharedBorder(row2));
|
||||
assertFalse(col2.hasSharedBorder(row2));
|
||||
assertTrue(col2.hasSharedBorder(col1));
|
||||
assertFalse(row1.hasExactSharedBorder(col1));
|
||||
assertFalse(row1.hasExactSharedBorder(col2));
|
||||
assertFalse(col1.hasExactSharedBorder(row1));
|
||||
assertFalse(col2.hasExactSharedBorder(row1));
|
||||
assertFalse(row2.hasExactSharedBorder(col1));
|
||||
assertFalse(row2.hasExactSharedBorder(col2));
|
||||
assertFalse(col1.hasExactSharedBorder(row2));
|
||||
assertFalse(col2.hasExactSharedBorder(row2));
|
||||
assertTrue(col2.hasExactSharedBorder(col1));
|
||||
|
||||
assertFalse(box1.hasSharedBorder(box1));
|
||||
assertTrue(box1.hasSharedBorder(box2));
|
||||
assertTrue(box1.hasSharedBorder(box3));
|
||||
assertFalse(box1.hasSharedBorder(box4));
|
||||
assertFalse(box1.hasExactSharedBorder(box1));
|
||||
assertTrue(box1.hasExactSharedBorder(box2));
|
||||
assertTrue(box1.hasExactSharedBorder(box3));
|
||||
assertFalse(box1.hasExactSharedBorder(box4));
|
||||
|
||||
assertTrue(box2.hasSharedBorder(box1));
|
||||
assertFalse(box2.hasSharedBorder(box2));
|
||||
assertFalse(box2.hasSharedBorder(box3));
|
||||
assertTrue(box2.hasSharedBorder(box4));
|
||||
assertTrue(box2.hasExactSharedBorder(box1));
|
||||
assertFalse(box2.hasExactSharedBorder(box2));
|
||||
assertFalse(box2.hasExactSharedBorder(box3));
|
||||
assertTrue(box2.hasExactSharedBorder(box4));
|
||||
|
||||
assertTrue(box3.hasSharedBorder(box1));
|
||||
assertFalse(box3.hasSharedBorder(box2));
|
||||
assertFalse(box3.hasSharedBorder(box3));
|
||||
assertTrue(box3.hasSharedBorder(box4));
|
||||
assertTrue(box3.hasExactSharedBorder(box1));
|
||||
assertFalse(box3.hasExactSharedBorder(box2));
|
||||
assertFalse(box3.hasExactSharedBorder(box3));
|
||||
assertTrue(box3.hasExactSharedBorder(box4));
|
||||
|
||||
assertFalse(box4.hasSharedBorder(box1));
|
||||
assertTrue(box4.hasSharedBorder(box2));
|
||||
assertTrue(box4.hasSharedBorder(box3));
|
||||
assertFalse(box4.hasSharedBorder(box4));
|
||||
assertFalse(box4.hasExactSharedBorder(box1));
|
||||
assertTrue(box4.hasExactSharedBorder(box2));
|
||||
assertTrue(box4.hasExactSharedBorder(box3));
|
||||
assertFalse(box4.hasExactSharedBorder(box4));
|
||||
}
|
||||
|
||||
|
||||
public void testIntersectMethod()
|
||||
{
|
||||
assertEquals( CellRange.OVERLAP,box0.intersect(box5));
|
||||
@ -135,5 +135,4 @@ public class TestCellRange extends TestCase
|
||||
assertEquals(CellRange.INSIDE,tenthColumn.intersect(tenthColumn));
|
||||
assertEquals(CellRange.INSIDE,tenthRow.intersect(tenthRow));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,13 +17,15 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AllFormulaEvalTests;
|
||||
import org.apache.poi.hssf.record.formula.function.AllFormulaFunctionTests;
|
||||
import org.apache.poi.hssf.record.formula.functions.AllIndividualFunctionEvaluationTests;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Collects all tests for this package.
|
||||
* Collects all tests for <tt>org.apache.poi.hssf.record.formula</tt>.
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
@ -31,6 +33,10 @@ public class AllFormulaTests {
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite result = new TestSuite(AllFormulaTests.class.getName());
|
||||
result.addTest(AllFormulaEvalTests.suite());
|
||||
result.addTest(AllFormulaFunctionTests.suite());
|
||||
result.addTest(AllIndividualFunctionEvaluationTests.suite());
|
||||
|
||||
result.addTestSuite(TestArea3DPtg.class);
|
||||
result.addTestSuite(TestAreaErrPtg.class);
|
||||
result.addTestSuite(TestAreaPtg.class);
|
||||
|
@ -21,7 +21,7 @@ import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Collects all tests for this package.
|
||||
* Collects all tests for this <tt>org.apache.poi.hssf.record.formula.function</tt>.
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
|
@ -49,14 +49,14 @@ import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* This class is not used during normal POI run-time but is used at development time to generate
|
||||
* This class is not used during normal POI run-time but is used at development time to generate
|
||||
* the file 'functionMetadata.txt'. There are more than 300 built-in functions in Excel and the
|
||||
* intention of this class is to make it easier to maintain the metadata, by extracting it from
|
||||
* a reliable source.
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public class ExcelFileFormatDocFunctionExtractor {
|
||||
public final class ExcelFileFormatDocFunctionExtractor {
|
||||
|
||||
private static final String SOURCE_DOC_FILE_NAME = "excelfileformat.odt";
|
||||
|
||||
@ -195,19 +195,19 @@ public class ExcelFileFormatDocFunctionExtractor {
|
||||
"table:table-row", "table:table-cell", "text:p", "text:span", "text:note-ref",
|
||||
};
|
||||
|
||||
|
||||
|
||||
private final Stack _elemNameStack;
|
||||
/** <code>true</code> only when parsing the target tables */
|
||||
private boolean _isInsideTable;
|
||||
|
||||
|
||||
private final List _rowData;
|
||||
private final StringBuffer _textNodeBuffer;
|
||||
private final List _rowNoteFlags;
|
||||
private boolean _cellHasNote;
|
||||
|
||||
|
||||
private final FunctionDataCollector _fdc;
|
||||
private String _lastHeadingText;
|
||||
|
||||
|
||||
public EFFDocHandler(FunctionDataCollector fdc) {
|
||||
_fdc = fdc;
|
||||
_elemNameStack = new Stack();
|
||||
@ -216,7 +216,7 @@ public class ExcelFileFormatDocFunctionExtractor {
|
||||
_textNodeBuffer = new StringBuffer();
|
||||
_rowNoteFlags = new ArrayList();
|
||||
}
|
||||
|
||||
|
||||
private boolean matchesTargetPath() {
|
||||
return matchesPath(0, TABLE_BASE_PATH_NAMES);
|
||||
}
|
||||
@ -365,7 +365,7 @@ public class ExcelFileFormatDocFunctionExtractor {
|
||||
xr.setContentHandler(new EFFDocHandler(fdc));
|
||||
|
||||
InputSource inSrc = new InputSource(is);
|
||||
|
||||
|
||||
try {
|
||||
xr.parse(inSrc);
|
||||
is.close();
|
||||
@ -407,30 +407,30 @@ public class ExcelFileFormatDocFunctionExtractor {
|
||||
}
|
||||
|
||||
private static void outputLicenseHeader(PrintStream ps) {
|
||||
String[] lines= {
|
||||
"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.",
|
||||
};
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
ps.print("# ");
|
||||
ps.println(lines[i]);
|
||||
}
|
||||
ps.println();
|
||||
}
|
||||
String[] lines= {
|
||||
"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.",
|
||||
};
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
ps.print("# ");
|
||||
ps.println(lines[i]);
|
||||
}
|
||||
ps.println();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Helps identify the source file
|
||||
*/
|
||||
private static String getFileCRC(File f) {
|
||||
@ -451,10 +451,10 @@ public class ExcelFileFormatDocFunctionExtractor {
|
||||
}
|
||||
return "0x" + Long.toHexString(crc.getValue()).toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
private static File getSourceFile() {
|
||||
if (true) {
|
||||
File dir = new File("c:/josh/ref-docs");
|
||||
if (false) {
|
||||
File dir = new File("c:/temp");
|
||||
File effDocFile = new File(dir, SOURCE_DOC_FILE_NAME);
|
||||
return effDocFile;
|
||||
}
|
||||
@ -464,7 +464,7 @@ public class ExcelFileFormatDocFunctionExtractor {
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
File result;
|
||||
byte[]buf = new byte[2048];
|
||||
try {
|
||||
@ -488,16 +488,15 @@ public class ExcelFileFormatDocFunctionExtractor {
|
||||
System.out.println("file downloaded ok");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
File effDocFile = getSourceFile();
|
||||
if(!effDocFile.exists()) {
|
||||
throw new RuntimeException("file '" + effDocFile.getAbsolutePath() + "' does not exist");
|
||||
}
|
||||
|
||||
|
||||
File outFile = new File("functionMetadata-asGenerated.txt");
|
||||
processFile(effDocFile, outFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,26 +18,27 @@
|
||||
package org.apache.poi.hssf.record.formula.function;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class TestFunctionMetadataRegistry extends TestCase {
|
||||
|
||||
public void testWellKnownFunctions() {
|
||||
confirmFunction(0, "COUNT");
|
||||
confirmFunction(1, "IF");
|
||||
|
||||
}
|
||||
public void testWellKnownFunctions() {
|
||||
confirmFunction(0, "COUNT");
|
||||
confirmFunction(1, "IF");
|
||||
|
||||
private static void confirmFunction(int index, String funcName) {
|
||||
FunctionMetadata fm;
|
||||
fm = FunctionMetadataRegistry.getFunctionByIndex(index);
|
||||
assertNotNull(fm);
|
||||
assertEquals(funcName, fm.getName());
|
||||
|
||||
fm = FunctionMetadataRegistry.getFunctionByName(funcName);
|
||||
assertNotNull(fm);
|
||||
assertEquals(index, fm.getIndex());
|
||||
}
|
||||
}
|
||||
|
||||
private static void confirmFunction(int index, String funcName) {
|
||||
FunctionMetadata fm;
|
||||
fm = FunctionMetadataRegistry.getFunctionByIndex(index);
|
||||
assertNotNull(fm);
|
||||
assertEquals(funcName, fm.getName());
|
||||
|
||||
fm = FunctionMetadataRegistry.getFunctionByName(funcName);
|
||||
assertNotNull(fm);
|
||||
assertEquals(index, fm.getIndex());
|
||||
}
|
||||
}
|
||||
|
@ -44,8 +44,8 @@ public final class TestParseMissingBuiltInFuncs extends TestCase {
|
||||
}
|
||||
AbstractFunctionPtg func = (AbstractFunctionPtg) ptgF;
|
||||
if(func.getFunctionIndex() == 255) {
|
||||
throw new AssertionFailedError("Failed to recognise built-in function in formula '"
|
||||
+ formula + "'");
|
||||
throw new AssertionFailedError("Failed to recognise built-in function in formula '"
|
||||
+ formula + "'");
|
||||
}
|
||||
|
||||
assertEquals(expPtgArraySize, ptgs.length);
|
||||
|
@ -48,7 +48,7 @@ public final class TestReadMissingBuiltInFuncs extends TestCase {
|
||||
}
|
||||
sht = wb.getSheetAt(0);
|
||||
}
|
||||
|
||||
|
||||
public void testDatedif() {
|
||||
|
||||
String formula;
|
||||
@ -56,9 +56,9 @@ public final class TestReadMissingBuiltInFuncs extends TestCase {
|
||||
formula = getCellFormula(0);
|
||||
} catch (IllegalStateException e) {
|
||||
if(e.getMessage().startsWith("Too few arguments")) {
|
||||
if(e.getMessage().indexOf("AttrPtg") > 0) {
|
||||
throw afe("tAttrVolatile not supported in FormulaParser.toFormulaString");
|
||||
}
|
||||
if(e.getMessage().indexOf("AttrPtg") > 0) {
|
||||
throw afe("tAttrVolatile not supported in FormulaParser.toFormulaString");
|
||||
}
|
||||
throw afe("NOW() registered with 1 arg instead of 0");
|
||||
}
|
||||
if(e.getMessage().startsWith("too much stuff")) {
|
||||
@ -70,7 +70,7 @@ public final class TestReadMissingBuiltInFuncs extends TestCase {
|
||||
assertEquals("DATEDIF(NOW(),NOW(),\"d\")", formula);
|
||||
}
|
||||
public void testDdb() {
|
||||
|
||||
|
||||
String formula = getCellFormula(1);
|
||||
if("externalflag(1,1,1,1,1)".equals(formula)) {
|
||||
throw afe("DDB() not registered");
|
||||
@ -78,14 +78,14 @@ public final class TestReadMissingBuiltInFuncs extends TestCase {
|
||||
assertEquals("DDB(1,1,1,1,1)", formula);
|
||||
}
|
||||
public void testAtan() {
|
||||
|
||||
|
||||
String formula = getCellFormula(2);
|
||||
if(formula.equals("ARCTAN(1)")) {
|
||||
throw afe("func ix 18 registered as ARCTAN() instead of ATAN()");
|
||||
}
|
||||
assertEquals("ATAN(1)", formula);
|
||||
}
|
||||
|
||||
|
||||
public void testUsdollar() {
|
||||
|
||||
String formula = getCellFormula(3);
|
||||
@ -128,7 +128,7 @@ public final class TestReadMissingBuiltInFuncs extends TestCase {
|
||||
}
|
||||
assertEquals("ISNONTEXT(\"abc\")", formula);
|
||||
}
|
||||
|
||||
|
||||
private String getCellFormula(int rowIx) {
|
||||
String result = sht.getRow(rowIx).getCell((short)0).getCellFormula();
|
||||
if (false) {
|
||||
|
@ -27,9 +27,8 @@ import junit.framework.TestSuite;
|
||||
*/
|
||||
public final class AllIndividualFunctionEvaluationTests {
|
||||
|
||||
// TODO - have this suite incorporated into a higher level one
|
||||
public static Test suite() {
|
||||
TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.functions");
|
||||
TestSuite result = new TestSuite(AllIndividualFunctionEvaluationTests.class.getName());
|
||||
result.addTestSuite(TestAverage.class);
|
||||
result.addTestSuite(TestCountFuncs.class);
|
||||
result.addTestSuite(TestDate.class);
|
||||
|
@ -30,7 +30,7 @@ import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class TestPmt extends TestCase {
|
||||
|
||||
|
||||
private static void confirm(double expected, NumberEval ne) {
|
||||
// only asserting accuracy to 4 fractional digits
|
||||
assertEquals(expected, ne.getNumberValue(), 0.00005);
|
||||
@ -61,12 +61,12 @@ public final class TestPmt extends TestCase {
|
||||
confirm(expected, invokeNormal(args));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void testBasic() {
|
||||
confirm(-1037.0321, (0.08/12), 10, 10000, 0, false);
|
||||
confirm(-1030.1643, (0.08/12), 10, 10000, 0, true);
|
||||
}
|
||||
|
||||
|
||||
public void test3args() {
|
||||
|
||||
Eval[] args = {
|
||||
|
@ -357,14 +357,14 @@ extends TestCase {
|
||||
book.createSheet("TEST");
|
||||
HSSFSheet sheet = book.cloneSheet(0);
|
||||
book.setSheetName(1,"CLONE");
|
||||
sheet.createRow(0).createCell((short)0).setCellValue("Test");
|
||||
sheet.createRow(0).createCell((short)0).setCellValue(new HSSFRichTextString("Test"));
|
||||
book.write(out);
|
||||
|
||||
book = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
|
||||
sheet = book.getSheet("CLONE");
|
||||
HSSFRow row = sheet.getRow(0);
|
||||
HSSFCell cell = row.getCell((short)0);
|
||||
System.out.println(cell.getStringCellValue());
|
||||
assertEquals("Test", cell.getRichStringCellValue().getString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,90 @@
|
||||
/* ====================================================================
|
||||
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 junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.hssf.util.Region;
|
||||
/**
|
||||
*
|
||||
* @author Dmitriy Kumshayev
|
||||
*/
|
||||
public final class TestHSSFConfditionalFormatting extends TestCase
|
||||
{
|
||||
public void testLastAndFirstColumns()
|
||||
{
|
||||
HSSFWorkbook workbook = new HSSFWorkbook();
|
||||
HSSFSheet sheet = workbook.createSheet();
|
||||
String formula = "7";
|
||||
|
||||
HSSFFontFormatting fontFmt = new HSSFFontFormatting();
|
||||
fontFmt.setFontStyle(true, false);
|
||||
|
||||
HSSFBorderFormatting bordFmt = new HSSFBorderFormatting();
|
||||
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);
|
||||
|
||||
HSSFConditionalFormattingRule [] cfRules =
|
||||
{
|
||||
sheet.createConditionalFormattingRule(formula, fontFmt, bordFmt, patternFmt),
|
||||
sheet.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "1", "2", fontFmt, bordFmt, patternFmt)
|
||||
};
|
||||
|
||||
short col = 1;
|
||||
Region [] regions =
|
||||
{
|
||||
new Region(0,col,-1,col)
|
||||
};
|
||||
|
||||
sheet.addConditionalFormatting(regions, cfRules);
|
||||
sheet.addConditionalFormatting(regions, cfRules);
|
||||
|
||||
// Verification
|
||||
assertEquals(2, sheet.getNumConditionalFormattings());
|
||||
sheet.removeConditionalFormatting(1);
|
||||
assertEquals(1, sheet.getNumConditionalFormattings());
|
||||
HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(0);
|
||||
assertNotNull(cf);
|
||||
|
||||
regions = cf.getFormattingRegions();
|
||||
assertNotNull(regions);
|
||||
assertEquals(1, regions.length);
|
||||
Region r = regions[0];
|
||||
assertEquals(1, r.getColumnFrom());
|
||||
assertEquals(1, r.getColumnTo());
|
||||
assertEquals(0, r.getRowFrom());
|
||||
assertEquals(-1, r.getRowTo());
|
||||
|
||||
assertEquals(2, cf.getNumberOfRules());
|
||||
|
||||
HSSFConditionalFormattingRule rule1 = cf.getRule(0);
|
||||
assertEquals("7",rule1.getFormula1());
|
||||
assertNull(rule1.getFormula2());
|
||||
|
||||
HSSFConditionalFormattingRule rule2 = cf.getRule(1);
|
||||
assertEquals("2",rule2.getFormula2());
|
||||
assertEquals("1",rule2.getFormula1());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user