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:
Nick Burch 2008-04-05 13:07:22 +00:00
parent a937f6c3d2
commit 641ab5bb06
42 changed files with 2160 additions and 1878 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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();
}
/**

View File

@ -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()+")";
}
}

View File

@ -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];

View File

@ -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(" [");

View File

@ -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(" [");

View File

@ -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

View File

@ -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);

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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()

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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 .
*/

View File

@ -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);
}
}

View File

@ -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(),

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -44,7 +44,7 @@ public final class TestExternalNameRecord extends TestCase {
}
}
}
public void testBasicSize() {
ExternalNameRecord enr = createSimpleENR();
if(enr.getRecordSize() == 13) {

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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
*/

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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 = {

View File

@ -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());
}
/**

View File

@ -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());
}
}