Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-645088 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk ........ r643625 | josh | 2008-04-01 23:18:25 +0100 (Tue, 01 Apr 2008) | 1 line Bug #44733 - DPRODUCT function should be index 189, not 191 ........ r643654 | josh | 2008-04-02 00:53:51 +0100 (Wed, 02 Apr 2008) | 1 line fix for bug 44710 - Incorrect skip() of second formula in DATAVALIDATION record ........ r643670 | klute | 2008-04-02 01:50:45 +0100 (Wed, 02 Apr 2008) | 1 line 44694 - HPSF: Support for property sets without sections ........ r643672 | klute | 2008-04-02 01:55:52 +0100 (Wed, 02 Apr 2008) | 1 line Restored an entry that had been deleted by chance. ........ r643831 | yegor | 2008-04-02 11:20:31 +0100 (Wed, 02 Apr 2008) | 1 line added set accessor to indentation level ........ r643834 | yegor | 2008-04-02 11:25:18 +0100 (Wed, 02 Apr 2008) | 1 line Fixed inconsistency between HSSFSHeet.getColumnWidth and HSSFSheet.getDefaultColumnWidth: getColumnWidth should always return width measured in 1/256th units. ........ r644343 | nick | 2008-04-03 16:04:52 +0100 (Thu, 03 Apr 2008) | 1 line Make a bit of a start on being able to edit chart titles, based on the email to user@poi from Russ on the 2nd of April. Not quite there though ........ r644473 | josh | 2008-04-03 21:25:53 +0100 (Thu, 03 Apr 2008) | 1 line Fix for bug 44739 - Conditional formatting (regions with max row/col index) ........ r644509 | josh | 2008-04-03 22:17:26 +0100 (Thu, 03 Apr 2008) | 1 line Follow up fix after r644473 (bug 44739) TestHSSFConditionalFormatting had a bug and wasn't yet included in the test suite hierarchy ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@645096 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
641ab5bb06
commit
8ff08c1c1a
@ -37,7 +37,9 @@
|
|||||||
|
|
||||||
<!-- Don't forget to update status.xml too! -->
|
<!-- Don't forget to update status.xml too! -->
|
||||||
<release version="3.0.3-beta1" date="2008-04-??">
|
<release version="3.0.3-beta1" date="2008-04-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">44739 - Small fixes for conditional formatting (regions with max row/col index)</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Implement Sheet.removeShape(Shape shape) in HSLF</action>
|
<action dev="POI-DEVELOPERS" type="add">Implement Sheet.removeShape(Shape shape) in HSLF</action>
|
||||||
|
<action dev="RK" type="add">44694 - HPSF: Support for property sets without sections</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">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">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 Formula Evaluator code out of scratchpad</action>
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
<!-- Don't forget to update changes.xml too! -->
|
<!-- Don't forget to update changes.xml too! -->
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.0.3-beta1" date="2008-04-??">
|
<release version="3.0.3-beta1" date="2008-04-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">44739 - Small fixes for conditional formatting (regions with max row/col index)</action>
|
||||||
|
<action dev="RK" type="add">44694 - HPSF: Support for property sets without sections</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Implement Sheet.removeShape(Shape shape) in HSLF</action>
|
<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">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">30311 - More work on Conditional Formatting</action>
|
||||||
|
@ -92,6 +92,8 @@ public class MutablePropertySet extends PropertySet
|
|||||||
osVersion = ps.getOSVersion();
|
osVersion = ps.getOSVersion();
|
||||||
setClassID(ps.getClassID());
|
setClassID(ps.getClassID());
|
||||||
clearSections();
|
clearSections();
|
||||||
|
if (sections == null)
|
||||||
|
sections = new LinkedList();
|
||||||
for (final Iterator i = ps.getSections().iterator(); i.hasNext();)
|
for (final Iterator i = ps.getSections().iterator(); i.hasNext();)
|
||||||
{
|
{
|
||||||
final MutableSection s = new MutableSection((Section) (i.next()));
|
final MutableSection s = new MutableSection((Section) (i.next()));
|
||||||
|
@ -387,7 +387,7 @@ public class PropertySet
|
|||||||
o += ClassID.LENGTH;
|
o += ClassID.LENGTH;
|
||||||
final long sectionCount = LittleEndian.getUInt(src, o);
|
final long sectionCount = LittleEndian.getUInt(src, o);
|
||||||
o += LittleEndian.INT_SIZE;
|
o += LittleEndian.INT_SIZE;
|
||||||
if (sectionCount < 1)
|
if (sectionCount < 0)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -426,9 +426,9 @@ public class PropertySet
|
|||||||
o += ClassID.LENGTH;
|
o += ClassID.LENGTH;
|
||||||
final int sectionCount = LittleEndian.getInt(src, o);
|
final int sectionCount = LittleEndian.getInt(src, o);
|
||||||
o += LittleEndian.INT_SIZE;
|
o += LittleEndian.INT_SIZE;
|
||||||
if (sectionCount <= 0)
|
if (sectionCount < 0)
|
||||||
throw new HPSFRuntimeException("Section count " + sectionCount +
|
throw new HPSFRuntimeException("Section count " + sectionCount +
|
||||||
" must be greater than 0.");
|
" is negative.");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the sections, which are following the header. They
|
* Read the sections, which are following the header. They
|
||||||
@ -468,6 +468,8 @@ public class PropertySet
|
|||||||
*/
|
*/
|
||||||
public boolean isSummaryInformation()
|
public boolean isSummaryInformation()
|
||||||
{
|
{
|
||||||
|
if (sections.size() <= 0)
|
||||||
|
return false;
|
||||||
return Util.equal(((Section) sections.get(0)).getFormatID().getBytes(),
|
return Util.equal(((Section) sections.get(0)).getFormatID().getBytes(),
|
||||||
SectionIDMap.SUMMARY_INFORMATION_ID);
|
SectionIDMap.SUMMARY_INFORMATION_ID);
|
||||||
}
|
}
|
||||||
@ -483,6 +485,8 @@ public class PropertySet
|
|||||||
*/
|
*/
|
||||||
public boolean isDocumentSummaryInformation()
|
public boolean isDocumentSummaryInformation()
|
||||||
{
|
{
|
||||||
|
if (sections.size() <= 0)
|
||||||
|
return false;
|
||||||
return Util.equal(((Section) sections.get(0)).getFormatID().getBytes(),
|
return Util.equal(((Section) sections.get(0)).getFormatID().getBytes(),
|
||||||
SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]);
|
SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]);
|
||||||
}
|
}
|
||||||
|
@ -1879,12 +1879,12 @@ public class Sheet implements Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the width of a given column in units of 1/20th of a point width (twips?)
|
* get the width of a given column in units of 1/256th of a character width
|
||||||
* @param column index
|
* @param column index
|
||||||
* @see org.apache.poi.hssf.record.DefaultColWidthRecord
|
* @see org.apache.poi.hssf.record.DefaultColWidthRecord
|
||||||
* @see org.apache.poi.hssf.record.ColumnInfoRecord
|
* @see org.apache.poi.hssf.record.ColumnInfoRecord
|
||||||
* @see #setColumnWidth(short,short)
|
* @see #setColumnWidth(short,short)
|
||||||
* @return column width in units of 1/20th of a point (twips?)
|
* @return column width in units of 1/256th of a character width
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public short getColumnWidth(short column)
|
public short getColumnWidth(short column)
|
||||||
@ -1912,7 +1912,9 @@ public class Sheet implements Model
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retval = defaultcolwidth.getColWidth();
|
//default column width is measured in characters
|
||||||
|
//multiply
|
||||||
|
retval = (short)(256*defaultcolwidth.getColWidth());
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -1951,9 +1953,9 @@ public class Sheet implements Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the width for a given column in 1/20th of a character width units
|
* set the width for a given column in 1/256th of a character width units
|
||||||
* @param column - the column number
|
* @param column - the column number
|
||||||
* @param width (in units of 1/20th of a character width)
|
* @param width (in units of 1/256th of a character width)
|
||||||
*/
|
*/
|
||||||
public void setColumnWidth(short column, short width)
|
public void setColumnWidth(short column, short width)
|
||||||
{
|
{
|
||||||
|
@ -58,12 +58,12 @@ public final class CFHeaderRecord extends Record
|
|||||||
{
|
{
|
||||||
field_1_numcf = in.readShort();
|
field_1_numcf = in.readShort();
|
||||||
field_2_need_recalculation = in.readShort();
|
field_2_need_recalculation = in.readShort();
|
||||||
field_3_enclosing_cell_range = new CellRange(in.readShort(),in.readShort(),in.readShort(),in.readShort());
|
field_3_enclosing_cell_range = new CellRange(in.readUShort(), in.readUShort(), in.readUShort(), in.readUShort());
|
||||||
int numCellRanges = in.readShort();
|
int numCellRanges = in.readShort();
|
||||||
CellRange[] crs = new CellRange[numCellRanges];
|
CellRange[] crs = new CellRange[numCellRanges];
|
||||||
for( int i=0; i<numCellRanges; i++)
|
for( int i=0; i<numCellRanges; i++)
|
||||||
{
|
{
|
||||||
crs[i] = new CellRange(in.readShort(),in.readShort(),in.readShort(),in.readShort());
|
crs[i] = new CellRange(in.readUShort(),in.readUShort(),in.readUShort(),in.readUShort());
|
||||||
}
|
}
|
||||||
field_4_cell_ranges = crs;
|
field_4_cell_ranges = crs;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
import org.apache.poi.util.StringUtil;
|
import org.apache.poi.util.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Title: DV Record<P>
|
* Title: DATAVALIDATION Record (0x01BE)<p/>
|
||||||
* Description: This record stores data validation settings and a list of cell ranges
|
* Description: This record stores data validation settings and a list of cell ranges
|
||||||
* which contain these settings. The data validation settings of a sheet
|
* which contain these settings. The data validation settings of a sheet
|
||||||
* are stored in a sequential list of DV records. This list is followed by
|
* are stored in a sequential list of DV records. This list is followed by
|
||||||
@ -36,7 +36,7 @@ import org.apache.poi.util.StringUtil;
|
|||||||
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
|
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
|
||||||
* @version 2.0-pre
|
* @version 2.0-pre
|
||||||
*/
|
*/
|
||||||
public class DVRecord extends Record
|
public final class DVRecord extends Record
|
||||||
{
|
{
|
||||||
public final static short sid = 0x01BE;
|
public final static short sid = 0x01BE;
|
||||||
|
|
||||||
@ -170,11 +170,6 @@ public class DVRecord extends Record
|
|||||||
this.field_not_used_1 = in.readShort();
|
this.field_not_used_1 = in.readShort();
|
||||||
|
|
||||||
//read first formula data condition
|
//read first formula data condition
|
||||||
// Not sure if this was needed or not...
|
|
||||||
// try {
|
|
||||||
// in.skip(this.field_size_first_formula);
|
|
||||||
// } catch(IOException e) { throw new IllegalStateException(e); }
|
|
||||||
|
|
||||||
int token_pos = 0;
|
int token_pos = 0;
|
||||||
while (token_pos < this.field_size_first_formula)
|
while (token_pos < this.field_size_first_formula)
|
||||||
{
|
{
|
||||||
@ -187,14 +182,14 @@ public class DVRecord extends Record
|
|||||||
this.field_not_used_2 = in.readShort();
|
this.field_not_used_2 = in.readShort();
|
||||||
|
|
||||||
//read sec formula data condition
|
//read sec formula data condition
|
||||||
//Not sure if this was needed or not...
|
if (false) { // TODO - prior to bug 44710 this 'skip' was being executed. write a junit to confirm this fix
|
||||||
try {
|
try {
|
||||||
in.skip(this.field_size_sec_formula);
|
in.skip(this.field_size_sec_formula);
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new IllegalStateException(e.getMessage());
|
throw new IllegalStateException(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
token_pos = 0;
|
token_pos = 0;
|
||||||
while (token_pos < this.field_size_sec_formula)
|
while (token_pos < this.field_size_sec_formula)
|
||||||
{
|
{
|
||||||
@ -516,7 +511,7 @@ public class DVRecord extends Record
|
|||||||
|
|
||||||
/**@todo DVRecord = Serializare */
|
/**@todo DVRecord = Serializare */
|
||||||
|
|
||||||
private class StringHandler
|
private static final class StringHandler
|
||||||
{
|
{
|
||||||
private int _string_length = 0x0001;
|
private int _string_length = 0x0001;
|
||||||
private byte _string_unicode_flag = 0x00;
|
private byte _string_unicode_flag = 0x00;
|
||||||
|
@ -29,12 +29,10 @@ import org.apache.poi.hssf.util.Region;
|
|||||||
*/
|
*/
|
||||||
public final class CellRange
|
public final class CellRange
|
||||||
{
|
{
|
||||||
/**
|
/** max 65536 rows in BIFF8 */
|
||||||
* max index for both row and column<p/>
|
private static final int LAST_ROW_INDEX = 0x00FFFF;
|
||||||
*
|
/** max 256 columns in BIFF8 */
|
||||||
* Note - this value converts to <tt>-1</tt> when cast to a <tt>short</tt>
|
private static final int LAST_COLUMN_INDEX = 0x00FF;
|
||||||
*/
|
|
||||||
private static final int MAX_INDEX = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
private static final Region[] EMPTY_REGION_ARRAY = { };
|
private static final Region[] EMPTY_REGION_ARRAY = { };
|
||||||
|
|
||||||
@ -57,54 +55,46 @@ public final class CellRange
|
|||||||
+ ", " + firstColumn + ", " + lastColumn + ")");
|
+ ", " + firstColumn + ", " + lastColumn + ")");
|
||||||
}
|
}
|
||||||
_firstRow = firstRow;
|
_firstRow = firstRow;
|
||||||
_lastRow = convertM1ToMax(lastRow);
|
_lastRow = convertM1ToMax(lastRow, LAST_ROW_INDEX);
|
||||||
_firstColumn = firstColumn;
|
_firstColumn = firstColumn;
|
||||||
_lastColumn = convertM1ToMax(lastColumn);
|
_lastColumn = convertM1ToMax(lastColumn, LAST_COLUMN_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int convertM1ToMax(int lastIx) {
|
/**
|
||||||
|
* Range arithmetic is easier when using a large positive number for 'max row or column'
|
||||||
|
* instead of <tt>-1</tt>.
|
||||||
|
*/
|
||||||
|
private static int convertM1ToMax(int lastIx, int maxIndex) {
|
||||||
if(lastIx < 0) {
|
if(lastIx < 0) {
|
||||||
return MAX_INDEX;
|
return maxIndex;
|
||||||
}
|
|
||||||
return lastIx;
|
|
||||||
}
|
|
||||||
private static int convertMaxToM1(int lastIx) {
|
|
||||||
if(lastIx == MAX_INDEX) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
return lastIx;
|
return lastIx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFullColumnRange() {
|
public boolean isFullColumnRange() {
|
||||||
return _firstColumn == 0 && _lastColumn == MAX_INDEX;
|
return _firstRow == 0 && _lastRow == LAST_ROW_INDEX;
|
||||||
}
|
}
|
||||||
public boolean isFullRowRange() {
|
public boolean isFullRowRange() {
|
||||||
return _firstRow == 0 && _lastRow == MAX_INDEX;
|
return _firstColumn == 0 && _lastColumn == LAST_COLUMN_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CellRange(Region r) {
|
private static CellRange createFromRegion(Region r) {
|
||||||
this(r.getRowFrom(), r.getRowTo(), r.getColumnFrom(), r.getColumnTo());
|
return new CellRange(r.getRowFrom(), r.getRowTo(), r.getColumnFrom(), r.getColumnTo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static boolean isValid(int firstRow, int lastRow, int firstColumn, int lastColumn)
|
private static boolean isValid(int firstRow, int lastRow, int firstColumn, int lastColumn)
|
||||||
{
|
{
|
||||||
if(lastRow == -1) {
|
if(lastRow < 0 || lastRow > LAST_ROW_INDEX) {
|
||||||
if(firstRow !=0) {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(firstRow < 0 || lastRow < -1) {
|
if(firstRow < 0 || firstRow > LAST_ROW_INDEX) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastColumn == -1) {
|
if(lastColumn < 0 || lastColumn > LAST_COLUMN_INDEX) {
|
||||||
if(firstColumn !=0) {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(firstColumn < 0 || lastColumn < -1) {
|
if(firstColumn < 0 || firstColumn > LAST_COLUMN_INDEX) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -114,23 +104,17 @@ public final class CellRange
|
|||||||
{
|
{
|
||||||
return _firstRow;
|
return _firstRow;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @return <tt>-1</tt> for whole column ranges
|
|
||||||
*/
|
|
||||||
public int getLastRow()
|
public int getLastRow()
|
||||||
{
|
{
|
||||||
return convertMaxToM1(_lastRow);
|
return _lastRow;
|
||||||
}
|
}
|
||||||
public int getFirstColumn()
|
public int getFirstColumn()
|
||||||
{
|
{
|
||||||
return _firstColumn;
|
return _firstColumn;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @return <tt>-1</tt> for whole row ranges
|
|
||||||
*/
|
|
||||||
public int getLastColumn()
|
public int getLastColumn()
|
||||||
{
|
{
|
||||||
return convertMaxToM1(_lastColumn);
|
return _lastColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int NO_INTERSECTION = 1;
|
public static final int NO_INTERSECTION = 1;
|
||||||
@ -374,7 +358,7 @@ public final class CellRange
|
|||||||
CellRange[] result = new CellRange[regions.length];
|
CellRange[] result = new CellRange[regions.length];
|
||||||
for( int i=0; i<regions.length; i++)
|
for( int i=0; i<regions.length; i++)
|
||||||
{
|
{
|
||||||
result[i] = new CellRange(regions[i]);
|
result[i] = createFromRegion(regions[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -404,10 +388,8 @@ public final class CellRange
|
|||||||
|
|
||||||
|
|
||||||
private Region convertToRegion() {
|
private Region convertToRegion() {
|
||||||
int lastRow = convertMaxToM1(_lastRow);
|
|
||||||
int lastColumn = convertMaxToM1(_lastColumn);
|
|
||||||
|
|
||||||
return new Region(_firstRow, (short)_firstColumn, lastRow, (short)lastColumn);
|
return new Region(_firstRow, (short)_firstColumn, _lastRow, (short)_lastColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,8 +143,8 @@
|
|||||||
169 COUNTA 0 30 V R
|
169 COUNTA 0 30 V R
|
||||||
183 PRODUCT 0 30 V R
|
183 PRODUCT 0 30 V R
|
||||||
184 FACT 1 1 V V
|
184 FACT 1 1 V V
|
||||||
|
189 DPRODUCT 3 3 V R R R
|
||||||
190 ISNONTEXT 1 1 V V
|
190 ISNONTEXT 1 1 V V
|
||||||
191 DPRODUCT 3 3 V R R R
|
|
||||||
193 STDEVP 1 30 V R
|
193 STDEVP 1 30 V R
|
||||||
194 VARP 1 30 V R
|
194 VARP 1 30 V R
|
||||||
195 DSTDEVP 3 3 V R R R
|
195 DSTDEVP 3 3 V R R R
|
||||||
|
@ -424,6 +424,15 @@ public class RichTextRun {
|
|||||||
return paragraphStyle == null ? 0 : paragraphStyle.getReservedField();
|
return paragraphStyle == null ? 0 : paragraphStyle.getReservedField();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets indentation level
|
||||||
|
*
|
||||||
|
* @param level indentation level. Must be in the range [0, 5]
|
||||||
|
*/
|
||||||
|
public void setIndentLevel(int level) {
|
||||||
|
if(paragraphStyle != null ) paragraphStyle.setReservedField((short)level);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this rich text run has bullets
|
* Sets whether this rich text run has bullets
|
||||||
*/
|
*/
|
||||||
|
@ -23,6 +23,7 @@ import org.apache.poi.hssf.record.*;
|
|||||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
@ -33,6 +34,15 @@ import java.util.Stack;
|
|||||||
*/
|
*/
|
||||||
public class HSSFChart
|
public class HSSFChart
|
||||||
{
|
{
|
||||||
|
private ChartRecord chartRecord;
|
||||||
|
private SeriesRecord seriesRecord;
|
||||||
|
|
||||||
|
private ChartTitleFormatRecord chartTitleFormat;
|
||||||
|
private SeriesTextRecord chartTitleText;
|
||||||
|
|
||||||
|
private HSSFChart(ChartRecord chartRecord) {
|
||||||
|
this.chartRecord = chartRecord;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a bar chart. API needs some work. :)
|
* Creates a bar chart. API needs some work. :)
|
||||||
@ -107,6 +117,74 @@ public class HSSFChart
|
|||||||
sheet.insertChartRecords( records );
|
sheet.insertChartRecords( records );
|
||||||
workbook.insertChartRecord();
|
workbook.insertChartRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the charts for the given sheet.
|
||||||
|
*
|
||||||
|
* NOTE: Does not yet work... checking it in just so others
|
||||||
|
* can take a look.
|
||||||
|
*/
|
||||||
|
public static HSSFChart[] getSheetCharts(HSSFSheet sheet) {
|
||||||
|
List charts = new ArrayList();
|
||||||
|
HSSFChart lastChart = null;
|
||||||
|
|
||||||
|
// Find records of interest
|
||||||
|
List records = sheet.getSheet().getRecords();
|
||||||
|
for(Iterator it = records.iterator(); it.hasNext();) {
|
||||||
|
Record r = (Record)it.next();
|
||||||
|
System.err.println(r);
|
||||||
|
|
||||||
|
if(r instanceof DrawingRecord) {
|
||||||
|
DrawingRecord dr = (DrawingRecord)r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(r instanceof ChartRecord) {
|
||||||
|
lastChart = new HSSFChart((ChartRecord)r);
|
||||||
|
charts.add(lastChart);
|
||||||
|
}
|
||||||
|
if(r instanceof SeriesRecord) {
|
||||||
|
lastChart.seriesRecord = (SeriesRecord)r;
|
||||||
|
}
|
||||||
|
if(r instanceof ChartTitleFormatRecord) {
|
||||||
|
lastChart.chartTitleFormat =
|
||||||
|
(ChartTitleFormatRecord)r;
|
||||||
|
}
|
||||||
|
if(r instanceof SeriesTextRecord) {
|
||||||
|
lastChart.chartTitleText =
|
||||||
|
(SeriesTextRecord)r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (HSSFChart[])
|
||||||
|
charts.toArray( new HSSFChart[charts.size()] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the chart's title, if there is one,
|
||||||
|
* or null if not
|
||||||
|
*/
|
||||||
|
public String getChartTitle() {
|
||||||
|
if(chartTitleText != null) {
|
||||||
|
return chartTitleText.getText();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the chart's title, but only if there
|
||||||
|
* was one already.
|
||||||
|
* TODO - add in the records if not
|
||||||
|
*/
|
||||||
|
public void setChartTitle(String title) {
|
||||||
|
if(chartTitleText != null) {
|
||||||
|
chartTitleText.setText(title);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("No chart title found to change");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private EOFRecord createEOFRecord()
|
private EOFRecord createEOFRecord()
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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 java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
public class TestHSSFChart extends TestCase {
|
||||||
|
private String dirName;
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
dirName = System.getProperty("HSSF.testdata.path");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSingleChart() throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTwoCharts() throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BROKENtestThreeCharts() throws Exception {
|
||||||
|
HSSFWorkbook wb = new HSSFWorkbook(
|
||||||
|
new FileInputStream(new File(dirName, "WithThreeCharts.xls"))
|
||||||
|
);
|
||||||
|
|
||||||
|
HSSFSheet s1 = wb.getSheetAt(0);
|
||||||
|
HSSFSheet s2 = wb.getSheetAt(1);
|
||||||
|
HSSFSheet s3 = wb.getSheetAt(2);
|
||||||
|
|
||||||
|
assertEquals(0, HSSFChart.getSheetCharts(s1).length);
|
||||||
|
assertEquals(2, HSSFChart.getSheetCharts(s2).length);
|
||||||
|
assertEquals(1, HSSFChart.getSheetCharts(s3).length);
|
||||||
|
|
||||||
|
HSSFChart[] charts;
|
||||||
|
|
||||||
|
charts = HSSFChart.getSheetCharts(s2);
|
||||||
|
assertNull(charts[0].getChartTitle());
|
||||||
|
assertEquals("Pie Chart Title Thingy", charts[1].getChartTitle());
|
||||||
|
|
||||||
|
charts = HSSFChart.getSheetCharts(s3);
|
||||||
|
assertEquals("Sheet 3 Chart with Title", charts[1].getChartTitle());
|
||||||
|
}
|
||||||
|
}
|
BIN
src/testcases/org/apache/poi/hpsf/data/Test_Humor-Generation.ppt
Normal file
BIN
src/testcases/org/apache/poi/hpsf/data/Test_Humor-Generation.ppt
Normal file
Binary file not shown.
BIN
src/testcases/org/apache/poi/hssf/data/WithThreeCharts.xls
Executable file
BIN
src/testcases/org/apache/poi/hssf/data/WithThreeCharts.xls
Executable file
Binary file not shown.
BIN
src/testcases/org/apache/poi/hssf/data/WithThreeCharts.xlsx
Executable file
BIN
src/testcases/org/apache/poi/hssf/data/WithThreeCharts.xlsx
Executable file
Binary file not shown.
BIN
src/testcases/org/apache/poi/hssf/data/colwidth.xls
Executable file
BIN
src/testcases/org/apache/poi/hssf/data/colwidth.xls
Executable file
Binary file not shown.
Binary file not shown.
@ -17,13 +17,13 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record;
|
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.Test;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.aggregates.AllRecordAggregateTests;
|
||||||
|
import org.apache.poi.hssf.record.cf.TestCellRange;
|
||||||
|
import org.apache.poi.hssf.record.formula.AllFormulaTests;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects all tests for package <tt>org.apache.poi.hssf.record</tt>.
|
* Collects all tests for package <tt>org.apache.poi.hssf.record</tt>.
|
||||||
*
|
*
|
||||||
@ -104,6 +104,7 @@ public final class AllRecordTests {
|
|||||||
result.addTestSuite(TestUnicodeString.class);
|
result.addTestSuite(TestUnicodeString.class);
|
||||||
result.addTestSuite(TestUnitsRecord.class);
|
result.addTestSuite(TestUnitsRecord.class);
|
||||||
result.addTestSuite(TestValueRangeRecord.class);
|
result.addTestSuite(TestValueRangeRecord.class);
|
||||||
|
result.addTestSuite(TestCellRange.class);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.cf.CellRange;
|
import org.apache.poi.hssf.record.cf.CellRange;
|
||||||
@ -34,8 +35,8 @@ public final class TestCFHeaderRecord extends TestCase
|
|||||||
{
|
{
|
||||||
CFHeaderRecord record = new CFHeaderRecord();
|
CFHeaderRecord record = new CFHeaderRecord();
|
||||||
CellRange[] ranges = {
|
CellRange[] ranges = {
|
||||||
new CellRange(0,-1,5,5),
|
new CellRange(0,0xFFFF,5,5),
|
||||||
new CellRange(0,-1,6,6),
|
new CellRange(0,0xFFFF,6,6),
|
||||||
new CellRange(0,1,0,1),
|
new CellRange(0,1,0,1),
|
||||||
new CellRange(0,1,2,3),
|
new CellRange(0,1,2,3),
|
||||||
new CellRange(2,3,0,1),
|
new CellRange(2,3,0,1),
|
||||||
@ -46,7 +47,7 @@ public final class TestCFHeaderRecord extends TestCase
|
|||||||
assertEquals(6,ranges.length);
|
assertEquals(6,ranges.length);
|
||||||
CellRange enclosingCellRange = record.getEnclosingCellRange();
|
CellRange enclosingCellRange = record.getEnclosingCellRange();
|
||||||
assertEquals(0, enclosingCellRange.getFirstRow());
|
assertEquals(0, enclosingCellRange.getFirstRow());
|
||||||
assertEquals(-1, enclosingCellRange.getLastRow());
|
assertEquals(65535, enclosingCellRange.getLastRow());
|
||||||
assertEquals(0, enclosingCellRange.getFirstColumn());
|
assertEquals(0, enclosingCellRange.getFirstColumn());
|
||||||
assertEquals(6, enclosingCellRange.getLastColumn());
|
assertEquals(6, enclosingCellRange.getLastColumn());
|
||||||
record.setNeedRecalculation(true);
|
record.setNeedRecalculation(true);
|
||||||
@ -56,7 +57,7 @@ public final class TestCFHeaderRecord extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testSerialization() {
|
public void testSerialization() {
|
||||||
byte[] recordData = new byte[]
|
byte[] recordData =
|
||||||
{
|
{
|
||||||
(byte)0x03, (byte)0x00,
|
(byte)0x03, (byte)0x00,
|
||||||
(byte)0x01, (byte)0x00,
|
(byte)0x01, (byte)0x00,
|
||||||
@ -66,7 +67,7 @@ public final class TestCFHeaderRecord extends TestCase
|
|||||||
(byte)0x00, (byte)0x00,
|
(byte)0x00, (byte)0x00,
|
||||||
(byte)0x03, (byte)0x00,
|
(byte)0x03, (byte)0x00,
|
||||||
|
|
||||||
(byte)0x04, (byte)0x00,
|
(byte)0x04, (byte)0x00, // nRegions
|
||||||
|
|
||||||
(byte)0x00, (byte)0x00,
|
(byte)0x00, (byte)0x00,
|
||||||
(byte)0x01, (byte)0x00,
|
(byte)0x01, (byte)0x00,
|
||||||
@ -93,44 +94,88 @@ public final class TestCFHeaderRecord extends TestCase
|
|||||||
|
|
||||||
assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats());
|
assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats());
|
||||||
assertTrue(record.getNeedRecalculation());
|
assertTrue(record.getNeedRecalculation());
|
||||||
CellRange enclosingCellRange = record.getEnclosingCellRange();
|
confirm(record.getEnclosingCellRange(), 0, 3, 0, 3);
|
||||||
assertEquals(0, enclosingCellRange.getFirstRow());
|
|
||||||
assertEquals(3, enclosingCellRange.getLastRow());
|
|
||||||
assertEquals(0, enclosingCellRange.getFirstColumn());
|
|
||||||
assertEquals(3, enclosingCellRange.getLastColumn());
|
|
||||||
CellRange[] ranges = record.getCellRanges();
|
CellRange[] ranges = record.getCellRanges();
|
||||||
CellRange range0 = ranges[0];
|
assertEquals(4, ranges.length);
|
||||||
assertEquals(0, range0.getFirstRow());
|
confirm(ranges[0], 0, 1, 0, 1);
|
||||||
assertEquals(1, range0.getLastRow());
|
confirm(ranges[1], 0, 1, 2, 3);
|
||||||
assertEquals(0, range0.getFirstColumn());
|
confirm(ranges[2], 2, 3, 0, 1);
|
||||||
assertEquals(1, range0.getLastColumn());
|
confirm(ranges[3], 2, 3, 2, 3);
|
||||||
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());
|
assertEquals(recordData.length+4, record.getRecordSize());
|
||||||
|
|
||||||
byte[] output = record.serialize();
|
byte[] output = record.serialize();
|
||||||
|
|
||||||
assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength
|
assertEquals("Output size", recordData.length+4, output.length); //includes sid+recordlength
|
||||||
|
|
||||||
for (int i = 0; i < recordData.length;i++)
|
for (int i = 0; i < recordData.length; i++)
|
||||||
{
|
{
|
||||||
assertEquals("CFHeaderRecord doesn't match", recordData[i], output[i+4]);
|
assertEquals("CFHeaderRecord doesn't match", recordData[i], output[i+4]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testExtremeRows() {
|
||||||
|
byte[] recordData = {
|
||||||
|
(byte)0x13, (byte)0x00, // nFormats
|
||||||
|
(byte)0x00, (byte)0x00,
|
||||||
|
|
||||||
|
(byte)0x00, (byte)0x00,
|
||||||
|
(byte)0xFF, (byte)0xFF,
|
||||||
|
(byte)0x00, (byte)0x00,
|
||||||
|
(byte)0xFF, (byte)0x00,
|
||||||
|
|
||||||
|
(byte)0x03, (byte)0x00, // nRegions
|
||||||
|
|
||||||
|
(byte)0x40, (byte)0x9C,
|
||||||
|
(byte)0x50, (byte)0xC3,
|
||||||
|
(byte)0x02, (byte)0x00,
|
||||||
|
(byte)0x02, (byte)0x00,
|
||||||
|
|
||||||
|
(byte)0x00, (byte)0x00,
|
||||||
|
(byte)0xFF, (byte)0xFF,
|
||||||
|
(byte)0x05, (byte)0x00,
|
||||||
|
(byte)0x05, (byte)0x00,
|
||||||
|
|
||||||
|
(byte)0x07, (byte)0x00,
|
||||||
|
(byte)0x07, (byte)0x00,
|
||||||
|
(byte)0x00, (byte)0x00,
|
||||||
|
(byte)0xFF, (byte)0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
CFHeaderRecord record;
|
||||||
|
try {
|
||||||
|
record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
if(e.getMessage().equals("invalid cell range (-25536, 2, -15536, 2)")) {
|
||||||
|
throw new AssertionFailedError("Identified bug 44739b");
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("#CFRULES", 19, record.getNumberOfConditionalFormats());
|
||||||
|
assertFalse(record.getNeedRecalculation());
|
||||||
|
confirm(record.getEnclosingCellRange(), 0, 65535, 0, 255);
|
||||||
|
CellRange[] ranges = record.getCellRanges();
|
||||||
|
assertEquals(3, ranges.length);
|
||||||
|
confirm(ranges[0], 40000, 50000, 2, 2);
|
||||||
|
confirm(ranges[1], 0, 65535, 5, 5);
|
||||||
|
confirm(ranges[2], 7, 7, 0, 255);
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void confirm(CellRange cr, int expFirstRow, int expLastRow, int expFirstCol, int expLastColumn) {
|
||||||
|
assertEquals("first row", expFirstRow, cr.getFirstRow());
|
||||||
|
assertEquals("last row", expLastRow, cr.getLastRow());
|
||||||
|
assertEquals("first column", expFirstCol, cr.getFirstColumn());
|
||||||
|
assertEquals("last column", expLastColumn, cr.getLastColumn());
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] ignored_args)
|
public static void main(String[] ignored_args)
|
||||||
{
|
{
|
||||||
|
@ -17,62 +17,76 @@ limitations under the License.
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record.cf;
|
package org.apache.poi.hssf.record.cf;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests CellRange operations.
|
* Tests CellRange operations.
|
||||||
*/
|
*/
|
||||||
public class TestCellRange extends TestCase
|
public final class TestCellRange extends TestCase
|
||||||
{
|
{
|
||||||
private static final CellRange biggest = new CellRange( 0, -1, 0,-1);
|
private static final CellRange biggest = createCR( 0, -1, 0,-1);
|
||||||
private static final CellRange tenthColumn = new CellRange( 0, -1,10,10);
|
private static final CellRange tenthColumn = createCR( 0, -1,10,10);
|
||||||
private static final CellRange tenthRow = new CellRange(10, 10, 0,-1);
|
private static final CellRange tenthRow = createCR(10, 10, 0,-1);
|
||||||
private static final CellRange box10x10 = new CellRange( 0, 10, 0,10);
|
private static final CellRange box10x10 = createCR( 0, 10, 0,10);
|
||||||
private static final CellRange box9x9 = new CellRange( 0, 9, 0, 9);
|
private static final CellRange box9x9 = createCR( 0, 9, 0, 9);
|
||||||
private static final CellRange box10to20c = new CellRange( 0, 10,10,20);
|
private static final CellRange box10to20c = createCR( 0, 10,10,20);
|
||||||
private static final CellRange oneCell = new CellRange(10, 10,10,10);
|
private static final CellRange oneCell = createCR(10, 10,10,10);
|
||||||
|
|
||||||
boolean [][] contanis = new boolean[][]
|
private static final CellRange[] sampleRanges = {
|
||||||
{
|
biggest, tenthColumn, tenthRow, box10x10, box9x9, box10to20c, oneCell,
|
||||||
// biggest, tenthColumn, tenthRow, box10x10, box9x9, box10to20c, oneCell
|
};
|
||||||
/*biggest */ new boolean[]{true, true , true , true , true , true , true},
|
|
||||||
/*tenthColumn*/ new boolean[]{false, true , false, false, false, false, true},
|
|
||||||
/*tenthRow */ new boolean[]{false, false, true , false, false, false, true},
|
|
||||||
/*box10x10 */ new boolean[]{false, false, false, true , true , false, true},
|
|
||||||
/*box9x9 */ new boolean[]{false, false, false, false, true , false, false},
|
|
||||||
/*box10to20c */ new boolean[]{false, false, false, false, false, true , true},
|
|
||||||
/*oneCell */ new boolean[]{false, false, false, false, false, false, true},
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
/** cross-reference of <tt>contains()</tt> operations for sampleRanges against itself */
|
||||||
|
private static final boolean [][] containsExpectedResults =
|
||||||
|
{
|
||||||
|
// biggest, tenthColumn, tenthRow, box10x10, box9x9, box10to20c, oneCell
|
||||||
|
/*biggest */ {true, true , true , true , true , true , true},
|
||||||
|
/*tenthColumn*/ {false, true , false, false, false, false, true},
|
||||||
|
/*tenthRow */ {false, false, true , false, false, false, true},
|
||||||
|
/*box10x10 */ {false, false, false, true , true , false, true},
|
||||||
|
/*box9x9 */ {false, false, false, false, true , false, false},
|
||||||
|
/*box10to20c */ {false, false, false, false, false, true , true},
|
||||||
|
/*oneCell */ {false, false, false, false, false, false, true},
|
||||||
|
} ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lastRow pass -1 for max row index
|
||||||
|
* @param lastCol pass -1 for max col index
|
||||||
|
*/
|
||||||
|
private static CellRange createCR(int firstRow, int lastRow, int firstCol, int lastCol) {
|
||||||
|
// max row & max col limit as per BIFF8
|
||||||
|
return new CellRange(
|
||||||
|
firstRow,
|
||||||
|
lastRow == -1 ? 0xFFFF : lastRow,
|
||||||
|
firstCol,
|
||||||
|
lastCol == -1 ? 0x00FF : lastCol);
|
||||||
|
}
|
||||||
|
|
||||||
public void testContainsMethod()
|
public void testContainsMethod()
|
||||||
{
|
{
|
||||||
CellRange [] ranges = new CellRange[]{biggest,tenthColumn,tenthRow,box10x10,box9x9,box10to20c,oneCell};
|
CellRange [] ranges = sampleRanges;
|
||||||
testContainsMethod(contanis,ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testContainsMethod(boolean[][]contains,CellRange[] ranges)
|
|
||||||
{
|
|
||||||
for(int i=0; i!=ranges.length;i++)
|
for(int i=0; i!=ranges.length;i++)
|
||||||
{
|
{
|
||||||
for(int j=0; j!=ranges.length;j++)
|
for(int j=0; j!=ranges.length;j++)
|
||||||
{
|
{
|
||||||
assertEquals("("+i+","+j+"): ",contains[i][j],ranges[i].contains(ranges[j]));
|
boolean expectedResult = containsExpectedResults[i][j];
|
||||||
|
assertEquals("("+i+","+j+"): ", expectedResult, ranges[i].contains(ranges[j]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final CellRange col1 = new CellRange( 0, -1, 1,1);
|
private static final CellRange col1 = createCR( 0, -1, 1,1);
|
||||||
private static final CellRange col2 = new CellRange( 0, -1, 2,2);
|
private static final CellRange col2 = createCR( 0, -1, 2,2);
|
||||||
private static final CellRange row1 = new CellRange( 1, 1, 0,-1);
|
private static final CellRange row1 = createCR( 1, 1, 0,-1);
|
||||||
private static final CellRange row2 = new CellRange( 2, 2, 0,-1);
|
private static final CellRange row2 = createCR( 2, 2, 0,-1);
|
||||||
|
|
||||||
private static final CellRange box0 = new CellRange( 0, 2, 0,2);
|
private static final CellRange box0 = createCR( 0, 2, 0,2);
|
||||||
private static final CellRange box1 = new CellRange( 0, 1, 0,1);
|
private static final CellRange box1 = createCR( 0, 1, 0,1);
|
||||||
private static final CellRange box2 = new CellRange( 0, 1, 2,3);
|
private static final CellRange box2 = createCR( 0, 1, 2,3);
|
||||||
private static final CellRange box3 = new CellRange( 2, 3, 0,1);
|
private static final CellRange box3 = createCR( 2, 3, 0,1);
|
||||||
private static final CellRange box4 = new CellRange( 2, 3, 2,3);
|
private static final CellRange box4 = createCR( 2, 3, 2,3);
|
||||||
private static final CellRange box5 = new CellRange( 1, 3, 1,3);
|
private static final CellRange box5 = createCR( 1, 3, 1,3);
|
||||||
|
|
||||||
public void testHasSharedBorderMethod()
|
public void testHasSharedBorderMethod()
|
||||||
{
|
{
|
||||||
@ -119,8 +133,8 @@ public class TestCellRange extends TestCase
|
|||||||
|
|
||||||
public void testIntersectMethod()
|
public void testIntersectMethod()
|
||||||
{
|
{
|
||||||
assertEquals( CellRange.OVERLAP,box0.intersect(box5));
|
assertEquals(CellRange.OVERLAP,box0.intersect(box5));
|
||||||
assertEquals( CellRange.OVERLAP,box5.intersect(box0));
|
assertEquals(CellRange.OVERLAP,box5.intersect(box0));
|
||||||
assertEquals(CellRange.NO_INTERSECTION,box1.intersect(box4));
|
assertEquals(CellRange.NO_INTERSECTION,box1.intersect(box4));
|
||||||
assertEquals(CellRange.NO_INTERSECTION,box4.intersect(box1));
|
assertEquals(CellRange.NO_INTERSECTION,box4.intersect(box1));
|
||||||
assertEquals(CellRange.NO_INTERSECTION,box2.intersect(box3));
|
assertEquals(CellRange.NO_INTERSECTION,box2.intersect(box3));
|
||||||
@ -135,4 +149,31 @@ public class TestCellRange extends TestCase
|
|||||||
assertEquals(CellRange.INSIDE,tenthColumn.intersect(tenthColumn));
|
assertEquals(CellRange.INSIDE,tenthColumn.intersect(tenthColumn));
|
||||||
assertEquals(CellRange.INSIDE,tenthRow.intersect(tenthRow));
|
assertEquals(CellRange.INSIDE,tenthRow.intersect(tenthRow));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cell ranges like the following are valid
|
||||||
|
* =$C:$IV,$B$1:$B$8,$B$10:$B$65536,$A:$A
|
||||||
|
*/
|
||||||
|
public void testCreate() {
|
||||||
|
CellRange cr;
|
||||||
|
|
||||||
|
cr = createCR(0, -1, 2, 255); // $C:$IV
|
||||||
|
confirmRange(cr, false, true);
|
||||||
|
cr = createCR(0, 7, 1, 1); // $B$1:$B$8
|
||||||
|
|
||||||
|
try {
|
||||||
|
cr = createCR(9, -1, 1, 1); // $B$65536
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
if(e.getMessage().startsWith("invalid cell range")) {
|
||||||
|
throw new AssertionFailedError("Identified bug 44739");
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
cr = createCR(0, -1, 0, 0); // $A:$A
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void confirmRange(CellRange cr, boolean isFullRow, boolean isFullColumn) {
|
||||||
|
assertEquals("isFullRowRange", isFullRow, cr.isFullRowRange());
|
||||||
|
assertEquals("isFullColumnRange", isFullColumn, cr.isFullColumnRange());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import junit.framework.TestSuite;
|
|||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
public class AllFormulaTests {
|
public final class AllFormulaTests {
|
||||||
|
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
TestSuite result = new TestSuite(AllFormulaTests.class.getName());
|
TestSuite result = new TestSuite(AllFormulaTests.class.getName());
|
||||||
@ -50,7 +50,6 @@ public class AllFormulaTests {
|
|||||||
result.addTestSuite(TestReferencePtg.class);
|
result.addTestSuite(TestReferencePtg.class);
|
||||||
result.addTestSuite(TestSheetNameFormatter.class);
|
result.addTestSuite(TestSheetNameFormatter.class);
|
||||||
result.addTestSuite(TestUnionPtg.class);
|
result.addTestSuite(TestUnionPtg.class);
|
||||||
result.addTest(AllFormulaFunctionTests.suite());
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,9 @@ import org.apache.poi.hssf.record.formula.FuncPtg;
|
|||||||
import org.apache.poi.hssf.record.formula.FuncVarPtg;
|
import org.apache.poi.hssf.record.formula.FuncVarPtg;
|
||||||
import org.apache.poi.hssf.record.formula.Ptg;
|
import org.apache.poi.hssf.record.formula.Ptg;
|
||||||
/**
|
/**
|
||||||
|
* Tests parsing of some built-in functions that were not properly
|
||||||
|
* registered in POI as bug #44675, #44733 (March/April 2008).
|
||||||
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
public final class TestParseMissingBuiltInFuncs extends TestCase {
|
public final class TestParseMissingBuiltInFuncs extends TestCase {
|
||||||
@ -39,6 +42,7 @@ public final class TestParseMissingBuiltInFuncs extends TestCase {
|
|||||||
Ptg[] ptgs = parse(formula);
|
Ptg[] ptgs = parse(formula);
|
||||||
Ptg ptgF = ptgs[ptgs.length-1]; // func is last RPN token in all these formulas
|
Ptg ptgF = ptgs[ptgs.length-1]; // func is last RPN token in all these formulas
|
||||||
|
|
||||||
|
// Check critical things in the Ptg array encoding.
|
||||||
if(!(ptgF instanceof AbstractFunctionPtg)) {
|
if(!(ptgF instanceof AbstractFunctionPtg)) {
|
||||||
throw new RuntimeException("function token missing");
|
throw new RuntimeException("function token missing");
|
||||||
}
|
}
|
||||||
@ -47,11 +51,15 @@ public final class TestParseMissingBuiltInFuncs extends TestCase {
|
|||||||
throw new AssertionFailedError("Failed to recognise built-in function in formula '"
|
throw new AssertionFailedError("Failed to recognise built-in function in formula '"
|
||||||
+ formula + "'");
|
+ formula + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(expPtgArraySize, ptgs.length);
|
assertEquals(expPtgArraySize, ptgs.length);
|
||||||
assertEquals(funcIx, func.getFunctionIndex());
|
assertEquals(funcIx, func.getFunctionIndex());
|
||||||
Class expCls = isVarArgFunc ? FuncVarPtg.class : FuncPtg.class;
|
Class expCls = isVarArgFunc ? FuncVarPtg.class : FuncPtg.class;
|
||||||
assertEquals(expCls, ptgF.getClass());
|
assertEquals(expCls, ptgF.getClass());
|
||||||
|
|
||||||
|
// check that parsed Ptg array converts back to formula text OK
|
||||||
|
Workbook book = Workbook.createWorkbook();
|
||||||
|
String reRenderedFormula = FormulaParser.toFormulaString(book, ptgs);
|
||||||
|
assertEquals(formula, reRenderedFormula);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDatedif() {
|
public void testDatedif() {
|
||||||
@ -76,4 +84,7 @@ public final class TestParseMissingBuiltInFuncs extends TestCase {
|
|||||||
public void testIsnontext() {
|
public void testIsnontext() {
|
||||||
confirmFunc("ISNONTEXT(\"abc\")", 2, false, 190);
|
confirmFunc("ISNONTEXT(\"abc\")", 2, false, 190);
|
||||||
}
|
}
|
||||||
|
public void testDproduct() {
|
||||||
|
confirmFunc("DPRODUCT(C1:E5,\"HarvestYield\",G1:H2)", 4, false, 189);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.RecordFormatException;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
|
||||||
@ -29,24 +31,31 @@ import junit.framework.AssertionFailedError;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
/**
|
/**
|
||||||
* Tests reading from a sample spreadsheet some built-in functions that were not properly
|
* Tests reading from a sample spreadsheet some built-in functions that were not properly
|
||||||
* registered in POI as bug #44675 (March 2008).
|
* registered in POI as bug #44675, #44733 (March/April 2008).
|
||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
public final class TestReadMissingBuiltInFuncs extends TestCase {
|
public final class TestReadMissingBuiltInFuncs extends TestCase {
|
||||||
|
|
||||||
private HSSFSheet sht;
|
/**
|
||||||
|
* This spreadsheet has examples of calls to the interesting built-in functions in cells A1:A7
|
||||||
|
*/
|
||||||
|
private static final String SAMPLE_SPREADSHEET_FILE_NAME = "missingFuncs44675.xls";
|
||||||
|
private static HSSFSheet _sheet;
|
||||||
|
|
||||||
protected void setUp() {
|
private static HSSFSheet getSheet() {
|
||||||
String cwd = System.getProperty("HSSF.testdata.path");
|
if (_sheet == null) {
|
||||||
HSSFWorkbook wb;
|
String cwd = System.getProperty("HSSF.testdata.path");
|
||||||
try {
|
HSSFWorkbook wb;
|
||||||
InputStream is = new FileInputStream(new File(cwd, "missingFuncs44675.xls"));
|
try {
|
||||||
wb = new HSSFWorkbook(is);
|
InputStream is = new FileInputStream(new File(cwd, SAMPLE_SPREADSHEET_FILE_NAME));
|
||||||
} catch (IOException e) {
|
wb = new HSSFWorkbook(is);
|
||||||
throw new RuntimeException(e);
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
_sheet = wb.getSheetAt(0);
|
||||||
}
|
}
|
||||||
sht = wb.getSheetAt(0);
|
return _sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDatedif() {
|
public void testDatedif() {
|
||||||
@ -128,9 +137,30 @@ public final class TestReadMissingBuiltInFuncs extends TestCase {
|
|||||||
}
|
}
|
||||||
assertEquals("ISNONTEXT(\"abc\")", formula);
|
assertEquals("ISNONTEXT(\"abc\")", formula);
|
||||||
}
|
}
|
||||||
|
public void testDproduct() {
|
||||||
|
|
||||||
|
String formula = getCellFormula(6);
|
||||||
|
assertEquals("DPRODUCT(C1:E5,\"HarvestYield\",G1:H2)", formula);
|
||||||
|
}
|
||||||
|
|
||||||
private String getCellFormula(int rowIx) {
|
private String getCellFormula(int rowIx) {
|
||||||
String result = sht.getRow(rowIx).getCell((short)0).getCellFormula();
|
HSSFSheet sheet;
|
||||||
|
try {
|
||||||
|
sheet = getSheet();
|
||||||
|
} catch (RecordFormatException e) {
|
||||||
|
if(e.getCause() instanceof InvocationTargetException) {
|
||||||
|
InvocationTargetException ite = (InvocationTargetException) e.getCause();
|
||||||
|
if(ite.getTargetException() instanceof RuntimeException) {
|
||||||
|
RuntimeException re = (RuntimeException) ite.getTargetException();
|
||||||
|
if(re.getMessage().equals("Invalid built-in function index (189)")) {
|
||||||
|
throw afe("DPRODUCT() registered with wrong index");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// some other unexpected error
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
String result = sheet.getRow(rowIx).getCell((short)0).getCellFormula();
|
||||||
if (false) {
|
if (false) {
|
||||||
System.err.println(result);
|
System.err.println(result);
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ public class AllUserModelTests {
|
|||||||
result.addTestSuite(TestFormulas.class);
|
result.addTestSuite(TestFormulas.class);
|
||||||
result.addTestSuite(TestHSSFCell.class);
|
result.addTestSuite(TestHSSFCell.class);
|
||||||
result.addTestSuite(TestHSSFClientAnchor.class);
|
result.addTestSuite(TestHSSFClientAnchor.class);
|
||||||
|
result.addTestSuite(TestHSSFConditionalFormatting.class);
|
||||||
result.addTestSuite(TestHSSFComment.class);
|
result.addTestSuite(TestHSSFComment.class);
|
||||||
result.addTestSuite(TestHSSFDateUtil.class);
|
result.addTestSuite(TestHSSFDateUtil.class);
|
||||||
result.addTestSuite(TestHSSFHeaderFooter.class);
|
result.addTestSuite(TestHSSFHeaderFooter.class);
|
||||||
|
@ -26,7 +26,7 @@ import org.apache.poi.hssf.util.Region;
|
|||||||
*
|
*
|
||||||
* @author Dmitriy Kumshayev
|
* @author Dmitriy Kumshayev
|
||||||
*/
|
*/
|
||||||
public final class TestHSSFConfditionalFormatting extends TestCase
|
public final class TestHSSFConditionalFormatting extends TestCase
|
||||||
{
|
{
|
||||||
public void testLastAndFirstColumns()
|
public void testLastAndFirstColumns()
|
||||||
{
|
{
|
||||||
@ -55,7 +55,7 @@ public final class TestHSSFConfditionalFormatting extends TestCase
|
|||||||
short col = 1;
|
short col = 1;
|
||||||
Region [] regions =
|
Region [] regions =
|
||||||
{
|
{
|
||||||
new Region(0,col,-1,col)
|
new Region(0,col,65535,col)
|
||||||
};
|
};
|
||||||
|
|
||||||
sheet.addConditionalFormatting(regions, cfRules);
|
sheet.addConditionalFormatting(regions, cfRules);
|
||||||
@ -75,7 +75,7 @@ public final class TestHSSFConfditionalFormatting extends TestCase
|
|||||||
assertEquals(1, r.getColumnFrom());
|
assertEquals(1, r.getColumnFrom());
|
||||||
assertEquals(1, r.getColumnTo());
|
assertEquals(1, r.getColumnTo());
|
||||||
assertEquals(0, r.getRowFrom());
|
assertEquals(0, r.getRowFrom());
|
||||||
assertEquals(-1, r.getRowTo());
|
assertEquals(65535, r.getRowTo());
|
||||||
|
|
||||||
assertEquals(2, cf.getNumberOfRules());
|
assertEquals(2, cf.getNumberOfRules());
|
||||||
|
|
@ -870,5 +870,65 @@ public class TestHSSFSheet
|
|||||||
|
|
||||||
public static void main(java.lang.String[] args) {
|
public static void main(java.lang.String[] args) {
|
||||||
junit.textui.TestRunner.run(TestHSSFSheet.class);
|
junit.textui.TestRunner.run(TestHSSFSheet.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testColumnWidth() throws Exception {
|
||||||
|
//check we can correctly read column widths from a reference workbook
|
||||||
|
String filename = System.getProperty("HSSF.testdata.path") + "/colwidth.xls";
|
||||||
|
HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(filename));
|
||||||
|
|
||||||
|
//reference values
|
||||||
|
int[] ref = {365, 548, 731, 914, 1097, 1280, 1462, 1645, 1828, 2011, 2194, 2377, 2560, 2742, 2925, 3108, 3291, 3474, 3657};
|
||||||
|
|
||||||
|
HSSFSheet sh = wb.getSheetAt(0);
|
||||||
|
for (char i = 'A'; i <= 'S'; i++) {
|
||||||
|
int idx = i - 'A';
|
||||||
|
int w = sh.getColumnWidth((short)idx);
|
||||||
|
assertEquals(ref[idx], w);
|
||||||
|
}
|
||||||
|
|
||||||
|
//the second sheet doesn't have overridden column widths
|
||||||
|
sh = wb.getSheetAt(1);
|
||||||
|
int def_width = sh.getDefaultColumnWidth();
|
||||||
|
for (char i = 'A'; i <= 'S'; i++) {
|
||||||
|
int idx = i - 'A';
|
||||||
|
int w = sh.getColumnWidth((short)idx);
|
||||||
|
//getDefaultColumnWidth returns width measued in characters
|
||||||
|
//getColumnWidth returns width measued in 1/256th units
|
||||||
|
assertEquals(def_width*256, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
//test new workbook
|
||||||
|
wb = new HSSFWorkbook();
|
||||||
|
sh = wb.createSheet();
|
||||||
|
sh.setDefaultColumnWidth((short)10);
|
||||||
|
assertEquals(10, sh.getDefaultColumnWidth());
|
||||||
|
assertEquals(256*10, sh.getColumnWidth((short)0));
|
||||||
|
assertEquals(256*10, sh.getColumnWidth((short)1));
|
||||||
|
assertEquals(256*10, sh.getColumnWidth((short)2));
|
||||||
|
for (char i = 'D'; i <= 'F'; i++) {
|
||||||
|
short w = (short)(256*12);
|
||||||
|
sh.setColumnWidth((short)i, w);
|
||||||
|
assertEquals(w, sh.getColumnWidth((short)i));
|
||||||
|
}
|
||||||
|
|
||||||
|
//serialize and read again
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
wb.write(out);
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
wb = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
|
||||||
|
sh = wb.getSheetAt(0);
|
||||||
|
assertEquals(10, sh.getDefaultColumnWidth());
|
||||||
|
//columns A-C have default width
|
||||||
|
assertEquals(256*10, sh.getColumnWidth((short)0));
|
||||||
|
assertEquals(256*10, sh.getColumnWidth((short)1));
|
||||||
|
assertEquals(256*10, sh.getColumnWidth((short)2));
|
||||||
|
//columns D-F have custom wodth
|
||||||
|
for (char i = 'D'; i <= 'F'; i++) {
|
||||||
|
short w = (short)(256*12);
|
||||||
|
assertEquals(w, sh.getColumnWidth((short)i));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user