Merged revisions 668156-671000 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk ........ r668257 | yegor | 2008-06-16 19:38:59 +0100 (Mon, 16 Jun 2008) | 1 line TextShape.getMarginLeft() returned incorrect value. Added a unit test for text margins. ........ r668259 | yegor | 2008-06-16 19:40:51 +0100 (Mon, 16 Jun 2008) | 1 line patch from bug #45177: Remove GPL reference in NOTICE ........ r669140 | nick | 2008-06-18 12:35:04 +0100 (Wed, 18 Jun 2008) | 1 line A partial fix for bug #30978, but something still remains, which seems to be related to changing the ptg ........ r669456 | nick | 2008-06-19 12:47:48 +0100 (Thu, 19 Jun 2008) | 1 line Improved HWPF Range.replaceText, from N. Hira in bug #45001 ........ r669658 | josh | 2008-06-19 20:07:20 +0100 (Thu, 19 Jun 2008) | 1 line Fix for bug 45234 - Removed incorrect shared formula conversion in CFRuleRecord ........ r669809 | josh | 2008-06-20 08:10:03 +0100 (Fri, 20 Jun 2008) | 1 line Fix for bug 30978 - small re-arrangement of class Ptg hierarchy for DeletedRef3DPtg and DeletedArea3DPtg. Similar to c664220 ........ r670190 | yegor | 2008-06-21 13:41:34 +0100 (Sat, 21 Jun 2008) | 1 line started a new section for poi-3.2 family, updated release date of 3.2-FINAL ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@674287 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fb38bcb821
commit
695b85049d
@ -10,14 +10,6 @@ Common Public License Version 1.0:
|
|||||||
http://www.opensource.org/licenses/cpl.php
|
http://www.opensource.org/licenses/cpl.php
|
||||||
See http://www.junit.org/
|
See http://www.junit.org/
|
||||||
|
|
||||||
A single data file of the POI component HDGF is based on VSDump,
|
|
||||||
and is under the GNU General Public Licence version 3 (GPL v3):
|
|
||||||
http://gplv3.fsf.org/
|
|
||||||
Since this is a data file, and has no compiled version (the original
|
|
||||||
file is distributed in both source and binary versions), there should
|
|
||||||
be little difference in licencing requirements compared to the ASL.
|
|
||||||
See http://www.gnome.ru/projects/vsdump_en.html
|
|
||||||
|
|
||||||
|
|
||||||
The Office Open XML experimental support had additional dependencies,
|
The Office Open XML experimental support had additional dependencies,
|
||||||
with their own licensing:
|
with their own licensing:
|
||||||
|
@ -45,7 +45,13 @@
|
|||||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
|
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.1-final" date="2008-06-??">
|
<release version="3.2-alpha1" date="2008-??-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="add"><!-- to keep forrest dtd quiet--></action>
|
||||||
|
</release>
|
||||||
|
<release version="3.1-final" date="2008-06-29">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">30978 - Fixed re-serialization of tRefErr3d and tAreaErr3d</action>
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">45234 - Removed incorrect shared formula conversion in CFRuleRecord</action>
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">45001 - Improved HWPF Range.replaceText()</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size</action>
|
<action dev="POI-DEVELOPERS" type="fix">44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Support custom image renderers in HSLF</action>
|
<action dev="POI-DEVELOPERS" type="add">Support custom image renderers in HSLF</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">Correctly increment the reference count of a blip when a picture is inserted</action>
|
<action dev="POI-DEVELOPERS" type="fix">Correctly increment the reference count of a blip when a picture is inserted</action>
|
||||||
|
@ -42,7 +42,13 @@
|
|||||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
|
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.1-final" date="2008-06-??">
|
<release version="3.2-alpha1" date="2008-??-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="add"><!-- to keep forrest dtd quiet--></action>
|
||||||
|
</release>
|
||||||
|
<release version="3.1-final" date="2008-06-29">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">30978 - Fixed re-serialization of tRefErr3d and tAreaErr3d</action>
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">45234 - Removed incorrect shared formula conversion in CFRuleRecord</action>
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">45001 - Improved HWPF Range.replaceText()</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size</action>
|
<action dev="POI-DEVELOPERS" type="fix">44692 - Fixed HSSFPicture.resize() to properly resize pictures if the underlying columns/rows have modified size</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Support custom image renderers in HSLF</action>
|
<action dev="POI-DEVELOPERS" type="add">Support custom image renderers in HSLF</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">Correctly increment the reference count of a blip when a picture is inserted</action>
|
<action dev="POI-DEVELOPERS" type="fix">Correctly increment the reference count of a blip when a picture is inserted</action>
|
||||||
|
@ -604,8 +604,28 @@ public class Workbook implements Model
|
|||||||
fixTabIdRecord();
|
fixTabIdRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we decide that we need to fix up
|
// Within NameRecords, it's ok to have the formula
|
||||||
// NameRecords, do it here
|
// part point at deleted sheets. It's also ok to
|
||||||
|
// have the ExternSheetNumber point at deleted
|
||||||
|
// sheets.
|
||||||
|
// However, the sheet index must be adjusted, or
|
||||||
|
// excel will break. (Sheet index is either 0 for
|
||||||
|
// global, or 1 based index to sheet)
|
||||||
|
int sheetNum1Based = sheetnum + 1;
|
||||||
|
for(int i=0; i<getNumNames(); i++) {
|
||||||
|
NameRecord nr = getNameRecord(i);
|
||||||
|
|
||||||
|
if(nr.getIndexToSheet() == sheetNum1Based) {
|
||||||
|
// Excel re-writes these to point to no sheet
|
||||||
|
nr.setEqualsToIndexToSheet((short)0);
|
||||||
|
} else if(nr.getIndexToSheet() > sheetNum1Based) {
|
||||||
|
// Bump down by one, so still points
|
||||||
|
// at the same sheet
|
||||||
|
nr.setEqualsToIndexToSheet((short)(
|
||||||
|
nr.getEqualsToIndexToSheet()-1
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,14 +14,10 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
|
|
||||||
package org.apache.poi.hssf.record;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.model.FormulaParser;
|
import org.apache.poi.hssf.model.FormulaParser;
|
||||||
import org.apache.poi.hssf.model.Workbook;
|
|
||||||
import org.apache.poi.hssf.record.cf.BorderFormatting;
|
import org.apache.poi.hssf.record.cf.BorderFormatting;
|
||||||
import org.apache.poi.hssf.record.cf.FontFormatting;
|
import org.apache.poi.hssf.record.cf.FontFormatting;
|
||||||
import org.apache.poi.hssf.record.cf.PatternFormatting;
|
import org.apache.poi.hssf.record.cf.PatternFormatting;
|
||||||
@ -30,7 +26,6 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|||||||
import org.apache.poi.util.BitField;
|
import org.apache.poi.util.BitField;
|
||||||
import org.apache.poi.util.BitFieldFactory;
|
import org.apache.poi.util.BitFieldFactory;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.StringUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conditional Formatting Rule Record.
|
* Conditional Formatting Rule Record.
|
||||||
@ -59,9 +54,6 @@ public final class CFRuleRecord extends Record
|
|||||||
|
|
||||||
private byte field_2_comparison_operator;
|
private byte field_2_comparison_operator;
|
||||||
|
|
||||||
private short field_3_formula1_len;
|
|
||||||
private short field_4_formula2_len;
|
|
||||||
|
|
||||||
private int field_5_options;
|
private int field_5_options;
|
||||||
|
|
||||||
private static final BitField modificationBits = bf(0x003FFFFF); // Bits: font,align,bord,patt,prot
|
private static final BitField modificationBits = bf(0x003FFFFF); // Bits: font,align,bord,patt,prot
|
||||||
@ -121,8 +113,6 @@ public final class CFRuleRecord extends Record
|
|||||||
{
|
{
|
||||||
field_1_condition_type=conditionType;
|
field_1_condition_type=conditionType;
|
||||||
field_2_comparison_operator=comparisonOperation;
|
field_2_comparison_operator=comparisonOperation;
|
||||||
field_3_formula1_len = (short)0;
|
|
||||||
field_4_formula2_len = (short)0;
|
|
||||||
|
|
||||||
// Set modification flags to 1: by default options are not modified
|
// Set modification flags to 1: by default options are not modified
|
||||||
field_5_options = modificationBits.setValue(field_5_options, -1);
|
field_5_options = modificationBits.setValue(field_5_options, -1);
|
||||||
@ -147,8 +137,8 @@ public final class CFRuleRecord extends Record
|
|||||||
this(conditionType, comparisonOperation);
|
this(conditionType, comparisonOperation);
|
||||||
field_1_condition_type = CONDITION_TYPE_CELL_VALUE_IS;
|
field_1_condition_type = CONDITION_TYPE_CELL_VALUE_IS;
|
||||||
field_2_comparison_operator = comparisonOperation;
|
field_2_comparison_operator = comparisonOperation;
|
||||||
setParsedExpression1(formula1);
|
field_17_formula1 = formula1;
|
||||||
setParsedExpression2(formula2);
|
field_18_formula2 = formula2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,63 +157,38 @@ public final class CFRuleRecord extends Record
|
|||||||
Ptg[] formula1 = parseFormula(formulaText1, workbook);
|
Ptg[] formula1 = parseFormula(formulaText1, workbook);
|
||||||
Ptg[] formula2 = parseFormula(formulaText2, workbook);
|
Ptg[] formula2 = parseFormula(formulaText2, workbook);
|
||||||
return new CFRuleRecord(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, formula1, formula2);
|
return new CFRuleRecord(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation, formula1, formula2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public CFRuleRecord(RecordInputStream in) {
|
||||||
* Constructs a Formula record and sets its fields appropriately.
|
|
||||||
* Note - id must be 0x06 (NOT 0x406 see MSKB #Q184647 for an
|
|
||||||
* "explanation of this bug in the documentation) or an exception
|
|
||||||
* will be throw upon validation
|
|
||||||
*
|
|
||||||
* @param in the RecordInputstream to read the record from
|
|
||||||
*/
|
|
||||||
|
|
||||||
public CFRuleRecord(RecordInputStream in)
|
|
||||||
{
|
|
||||||
super(in);
|
super(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected void fillFields(RecordInputStream in) {
|
protected void fillFields(RecordInputStream in) {
|
||||||
try {
|
field_1_condition_type = in.readByte();
|
||||||
field_1_condition_type = in.readByte();
|
field_2_comparison_operator = in.readByte();
|
||||||
field_2_comparison_operator = in.readByte();
|
int field_3_formula1_len = in.readUShort();
|
||||||
field_3_formula1_len = in.readShort();
|
int field_4_formula2_len = in.readUShort();
|
||||||
field_4_formula2_len = in.readShort();
|
field_5_options = in.readInt();
|
||||||
field_5_options = in.readInt();
|
field_6_not_used = in.readShort();
|
||||||
field_6_not_used = in.readShort();
|
|
||||||
|
|
||||||
if (containsFontFormattingBlock()) {
|
if (containsFontFormattingBlock()) {
|
||||||
fontFormatting = new FontFormatting(in);
|
fontFormatting = new FontFormatting(in);
|
||||||
}
|
|
||||||
|
|
||||||
if (containsBorderFormattingBlock()) {
|
|
||||||
borderFormatting = new BorderFormatting(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (containsPatternFormattingBlock()) {
|
|
||||||
patternFormatting = new PatternFormatting(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field_3_formula1_len > 0) {
|
|
||||||
Stack ptgs = Ptg.createParsedExpressionTokens(field_3_formula1_len, in);
|
|
||||||
// Now convert any fields as required
|
|
||||||
ptgs = SharedFormulaRecord.convertSharedFormulas(ptgs, 0, 0);
|
|
||||||
field_17_formula1 = toArray(ptgs);
|
|
||||||
}
|
|
||||||
if (field_4_formula2_len > 0) {
|
|
||||||
Stack ptgs = Ptg.createParsedExpressionTokens(field_4_formula2_len, in);
|
|
||||||
|
|
||||||
// Now convert any fields as required
|
|
||||||
ptgs = SharedFormulaRecord.convertSharedFormulas(ptgs, 0, 0);
|
|
||||||
field_18_formula2 = toArray(ptgs);
|
|
||||||
}
|
|
||||||
} catch (java.lang.UnsupportedOperationException uoe) {
|
|
||||||
throw new RecordFormatException(uoe);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (containsBorderFormattingBlock()) {
|
||||||
|
borderFormatting = new BorderFormatting(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containsPatternFormattingBlock()) {
|
||||||
|
patternFormatting = new PatternFormatting(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field_3_formula1_len > 0) {
|
||||||
|
field_17_formula1 = Ptg.readTokens(field_3_formula1_len, in);
|
||||||
|
}
|
||||||
|
if (field_4_formula2_len > 0) {
|
||||||
|
field_18_formula2 = Ptg.readTokens(field_4_formula2_len, in);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getConditionType()
|
public byte getConditionType()
|
||||||
@ -323,24 +288,6 @@ public final class CFRuleRecord extends Record
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the length (in number of tokens) of the expression 1
|
|
||||||
* @return expression length
|
|
||||||
*/
|
|
||||||
private short getExpression1Length()
|
|
||||||
{
|
|
||||||
return field_3_formula1_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the length (in number of tokens) of the expression 2
|
|
||||||
* @return expression length
|
|
||||||
*/
|
|
||||||
private short getExpression2Length()
|
|
||||||
{
|
|
||||||
return field_4_formula2_len;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* get the option flags
|
* get the option flags
|
||||||
*
|
*
|
||||||
@ -489,16 +436,6 @@ public final class CFRuleRecord extends Record
|
|||||||
return field_18_formula2;
|
return field_18_formula2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setParsedExpression1(Ptg[] ptgs) {
|
|
||||||
short len = getTotalPtgSize(field_17_formula1 = ptgs);
|
|
||||||
field_3_formula1_len = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setParsedExpression2(Ptg[] ptgs) {
|
|
||||||
short len = getTotalPtgSize(field_18_formula2 = ptgs);
|
|
||||||
field_4_formula2_len = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called by constructor, should throw runtime exception in the event of a
|
* called by constructor, should throw runtime exception in the event of a
|
||||||
* record passed with a differing ID.
|
* record passed with a differing ID.
|
||||||
@ -519,6 +456,17 @@ public final class CFRuleRecord extends Record
|
|||||||
return sid;
|
return sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ptgs may be <code>null</code>
|
||||||
|
* @return encoded size of the formula
|
||||||
|
*/
|
||||||
|
private static int getFormulaSize(Ptg[] ptgs) {
|
||||||
|
if (ptgs == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return Ptg.getEncodedSize(ptgs);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called by the class that is responsible for writing this sucker.
|
* called by the class that is responsible for writing this sucker.
|
||||||
* Subclasses should implement this so that their data is passed back in a
|
* Subclasses should implement this so that their data is passed back in a
|
||||||
@ -528,18 +476,20 @@ public final class CFRuleRecord extends Record
|
|||||||
* @param data byte array containing instance data
|
* @param data byte array containing instance data
|
||||||
* @return number of bytes written
|
* @return number of bytes written
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public int serialize(int pOffset, byte [] data)
|
public int serialize(int pOffset, byte [] data)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int formula1Len=getFormulaSize(field_17_formula1);
|
||||||
|
int formula2Len=getFormulaSize(field_18_formula2);
|
||||||
|
|
||||||
int offset = pOffset;
|
int offset = pOffset;
|
||||||
int recordsize = getRecordSize();
|
int recordsize = getRecordSize();
|
||||||
LittleEndian.putShort(data, 0 + offset, sid);
|
LittleEndian.putShort(data, 0 + offset, sid);
|
||||||
LittleEndian.putShort(data, 2 + offset, (short)(recordsize-4));
|
LittleEndian.putShort(data, 2 + offset, (short)(recordsize-4));
|
||||||
data[4 + offset] = field_1_condition_type;
|
data[4 + offset] = field_1_condition_type;
|
||||||
data[5 + offset] = field_2_comparison_operator;
|
data[5 + offset] = field_2_comparison_operator;
|
||||||
LittleEndian.putShort(data, 6 + offset, field_3_formula1_len);
|
LittleEndian.putUShort(data, 6 + offset, formula1Len);
|
||||||
LittleEndian.putShort(data, 8 + offset, field_4_formula2_len);
|
LittleEndian.putUShort(data, 8 + offset, formula2Len);
|
||||||
LittleEndian.putInt(data, 10 + offset, field_5_options);
|
LittleEndian.putInt(data, 10 + offset, field_5_options);
|
||||||
LittleEndian.putShort(data,14 + offset, field_6_not_used);
|
LittleEndian.putShort(data,14 + offset, field_6_not_used);
|
||||||
|
|
||||||
@ -562,16 +512,12 @@ public final class CFRuleRecord extends Record
|
|||||||
offset += patternFormatting.serialize(offset, data);
|
offset += patternFormatting.serialize(offset, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getExpression1Length()>0)
|
if (field_17_formula1 != null) {
|
||||||
{
|
offset += Ptg.serializePtgs(field_17_formula1, data, offset);
|
||||||
Ptg.serializePtgStack(convertToTokenStack(field_17_formula1), data, offset);
|
|
||||||
offset += getExpression1Length();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getExpression2Length()>0)
|
if (field_18_formula2 != null) {
|
||||||
{
|
offset += Ptg.serializePtgs(field_18_formula2, data, offset);
|
||||||
Ptg.serializePtgStack(convertToTokenStack(field_18_formula2), data, offset);
|
|
||||||
offset += getExpression2Length();
|
|
||||||
}
|
}
|
||||||
if(offset - pOffset != recordsize) {
|
if(offset - pOffset != recordsize) {
|
||||||
throw new IllegalStateException("write mismatch (" + (offset - pOffset) + "!=" + recordsize + ")");
|
throw new IllegalStateException("write mismatch (" + (offset - pOffset) + "!=" + recordsize + ")");
|
||||||
@ -586,24 +532,12 @@ public final class CFRuleRecord extends Record
|
|||||||
(containsFontFormattingBlock()?fontFormatting.getRawRecord().length:0)+
|
(containsFontFormattingBlock()?fontFormatting.getRawRecord().length:0)+
|
||||||
(containsBorderFormattingBlock()?8:0)+
|
(containsBorderFormattingBlock()?8:0)+
|
||||||
(containsPatternFormattingBlock()?4:0)+
|
(containsPatternFormattingBlock()?4:0)+
|
||||||
getExpression1Length()+
|
getFormulaSize(field_17_formula1)+
|
||||||
getExpression2Length()
|
getFormulaSize(field_18_formula2)
|
||||||
;
|
;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
private short getTotalPtgSize(Ptg[] ptgs)
|
|
||||||
{
|
|
||||||
if( ptgs == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
short retval = 0;
|
|
||||||
for (int i = 0; i < ptgs.length; i++)
|
|
||||||
{
|
|
||||||
retval += ptgs[i].getSize();
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
@ -629,8 +563,6 @@ public final class CFRuleRecord extends Record
|
|||||||
|
|
||||||
public Object clone() {
|
public Object clone() {
|
||||||
CFRuleRecord rec = new CFRuleRecord(field_1_condition_type, field_2_comparison_operator);
|
CFRuleRecord rec = new CFRuleRecord(field_1_condition_type, field_2_comparison_operator);
|
||||||
rec.field_3_formula1_len = field_3_formula1_len;
|
|
||||||
rec.field_4_formula2_len = field_4_formula2_len;
|
|
||||||
rec.field_5_options = field_5_options;
|
rec.field_5_options = field_5_options;
|
||||||
rec.field_6_not_used = field_6_not_used;
|
rec.field_6_not_used = field_6_not_used;
|
||||||
if (containsFontFormattingBlock()) {
|
if (containsFontFormattingBlock()) {
|
||||||
@ -642,10 +574,10 @@ public final class CFRuleRecord extends Record
|
|||||||
if (containsPatternFormattingBlock()) {
|
if (containsPatternFormattingBlock()) {
|
||||||
rec.patternFormatting = (PatternFormatting) patternFormatting.clone();
|
rec.patternFormatting = (PatternFormatting) patternFormatting.clone();
|
||||||
}
|
}
|
||||||
if (field_3_formula1_len > 0) {
|
if (field_17_formula1 != null) {
|
||||||
rec.field_17_formula1 = (Ptg[]) field_17_formula1.clone();
|
rec.field_17_formula1 = (Ptg[]) field_17_formula1.clone();
|
||||||
}
|
}
|
||||||
if (field_4_formula2_len > 0) {
|
if (field_18_formula2 != null) {
|
||||||
rec.field_18_formula2 = (Ptg[]) field_18_formula2.clone();
|
rec.field_18_formula2 = (Ptg[]) field_18_formula2.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,30 +585,17 @@ public final class CFRuleRecord extends Record
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO - parse conditional format formulas properly i.e. produce tRefN and tAreaN instead of tRef and tArea
|
||||||
|
* this call will produce the wrong results if the formula contains any cell references
|
||||||
|
* One approach might be to apply the inverse of SharedFormulaRecord.convertSharedFormulas(Stack, int, int)
|
||||||
|
* Note - two extra parameters (rowIx & colIx) will be required. They probably come from one of the Region objects.
|
||||||
|
*
|
||||||
* @return <code>null</code> if <tt>formula</tt> was null.
|
* @return <code>null</code> if <tt>formula</tt> was null.
|
||||||
*/
|
*/
|
||||||
private static Ptg[] parseFormula(String formula, HSSFWorkbook workbook)
|
private static Ptg[] parseFormula(String formula, HSSFWorkbook workbook) {
|
||||||
{
|
|
||||||
if(formula == null) {
|
if(formula == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return FormulaParser.parse(formula, workbook);
|
return FormulaParser.parse(formula, workbook);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - treat formulas as token arrays instead of Stacks throughout the rest of POI
|
|
||||||
private static Stack convertToTokenStack(Ptg[] ptgs)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
private static Ptg[] toArray(Stack ptgs) {
|
|
||||||
Ptg[] result = new Ptg[ptgs.size()];
|
|
||||||
ptgs.toArray(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
|
|
||||||
package org.apache.poi.hssf.record;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
@ -22,9 +21,8 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.model.FormulaParser;
|
||||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||||
import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.DeletedRef3DPtg;
|
|
||||||
import org.apache.poi.hssf.record.formula.Ptg;
|
import org.apache.poi.hssf.record.formula.Ptg;
|
||||||
import org.apache.poi.hssf.record.formula.Ref3DPtg;
|
import org.apache.poi.hssf.record.formula.Ref3DPtg;
|
||||||
import org.apache.poi.hssf.record.formula.UnionPtg;
|
import org.apache.poi.hssf.record.formula.UnionPtg;
|
||||||
@ -44,8 +42,7 @@ import org.apache.poi.util.StringUtil;
|
|||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
* @version 1.0-pre
|
* @version 1.0-pre
|
||||||
*/
|
*/
|
||||||
|
public final class NameRecord extends Record {
|
||||||
public class NameRecord extends Record {
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public final static short sid = 0x18; //Docs says that it is 0x218
|
public final static short sid = 0x18; //Docs says that it is 0x218
|
||||||
@ -650,50 +647,9 @@ public class NameRecord extends Record {
|
|||||||
/** gets the reference , the area only (range)
|
/** gets the reference , the area only (range)
|
||||||
* @return area reference
|
* @return area reference
|
||||||
*/
|
*/
|
||||||
public String getAreaReference(HSSFWorkbook book){
|
public String getAreaReference(HSSFWorkbook book){
|
||||||
if (field_13_name_definition == null || field_13_name_definition.isEmpty()) return "Error";
|
return FormulaParser.toFormulaString(book, field_13_name_definition);
|
||||||
Ptg ptg = (Ptg) field_13_name_definition.peek();
|
}
|
||||||
String result = "";
|
|
||||||
|
|
||||||
// If it's a union, descend in and process
|
|
||||||
if (ptg.getClass() == UnionPtg.class) {
|
|
||||||
Iterator it =field_13_name_definition.iterator();
|
|
||||||
while( it.hasNext() ) {
|
|
||||||
Ptg p = (Ptg)it.next();
|
|
||||||
|
|
||||||
String thisRes = getAreaRefString(p, book);
|
|
||||||
if(thisRes.length() > 0) {
|
|
||||||
// Add a comma to the end if needed
|
|
||||||
if(result.length() > 0 && !result.endsWith(",")) {
|
|
||||||
result += ",";
|
|
||||||
}
|
|
||||||
// And add the string it corresponds to
|
|
||||||
result += thisRes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Otherwise just get the string
|
|
||||||
result = getAreaRefString(ptg, book);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn the given ptg into a string, or
|
|
||||||
* return an empty string if nothing is possible
|
|
||||||
* for it.
|
|
||||||
*/
|
|
||||||
private String getAreaRefString(Ptg ptg,HSSFWorkbook book) {
|
|
||||||
if (ptg.getClass() == Area3DPtg.class){
|
|
||||||
return ptg.toFormulaString(book);
|
|
||||||
} else if (ptg.getClass() == Ref3DPtg.class){
|
|
||||||
return ptg.toFormulaString(book);
|
|
||||||
} else if (ptg.getClass() == DeletedArea3DPtg.class || ptg.getClass() == DeletedRef3DPtg.class) {
|
|
||||||
return "#REF!";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** sets the reference , the area only (range)
|
/** sets the reference , the area only (range)
|
||||||
* @param ref area reference
|
* @param ref area reference
|
||||||
|
@ -35,7 +35,7 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
* @author Jason Height (jheight at chariot dot net dot au)
|
* @author Jason Height (jheight at chariot dot net dot au)
|
||||||
* @version 1.0-pre
|
* @version 1.0-pre
|
||||||
*/
|
*/
|
||||||
public class Area3DPtg extends OperandPtg implements AreaI {
|
public final class Area3DPtg extends OperandPtg implements AreaI {
|
||||||
public final static byte sid = 0x3b;
|
public final static byte sid = 0x3b;
|
||||||
private final static int SIZE = 11; // 10 + 1 for Ptg
|
private final static int SIZE = 11; // 10 + 1 for Ptg
|
||||||
private short field_1_index_extern_sheet;
|
private short field_1_index_extern_sheet;
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
package org.apache.poi.hssf.record.formula;
|
package org.apache.poi.hssf.record.formula;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.RecordInputStream;
|
import org.apache.poi.hssf.record.RecordInputStream;
|
||||||
|
import org.apache.poi.ss.usermodel.ErrorConstants;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Title: Deleted Area 3D Ptg - 3D referecnce (Sheet + Area)<P>
|
* Title: Deleted Area 3D Ptg - 3D referecnce (Sheet + Area)<P>
|
||||||
@ -26,19 +29,30 @@ import org.apache.poi.hssf.record.RecordInputStream;
|
|||||||
* @author Patrick Luby
|
* @author Patrick Luby
|
||||||
* @version 1.0-pre
|
* @version 1.0-pre
|
||||||
*/
|
*/
|
||||||
|
public final class DeletedArea3DPtg extends OperandPtg {
|
||||||
public class DeletedArea3DPtg extends Area3DPtg
|
|
||||||
{
|
|
||||||
public final static byte sid = 0x3d;
|
public final static byte sid = 0x3d;
|
||||||
|
private final int field_1_index_extern_sheet;
|
||||||
|
private final int unused1;
|
||||||
|
private final int unused2;
|
||||||
|
|
||||||
/** Creates new DeletedArea3DPtg */
|
public DeletedArea3DPtg( RecordInputStream in) {
|
||||||
public DeletedArea3DPtg( String arearef, short externIdx )
|
field_1_index_extern_sheet = in.readUShort();
|
||||||
{
|
unused1 = in.readInt();
|
||||||
super(arearef, externIdx);
|
unused2 = in.readInt();
|
||||||
}
|
}
|
||||||
|
public String toFormulaString(Workbook book) {
|
||||||
public DeletedArea3DPtg( RecordInputStream in)
|
return ErrorConstants.getText(ErrorConstants.ERROR_REF);
|
||||||
{
|
}
|
||||||
super(in);
|
public byte getDefaultOperandClass() {
|
||||||
}
|
return Ptg.CLASS_REF;
|
||||||
|
}
|
||||||
|
public int getSize() {
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
public void writeBytes(byte[] data, int offset) {
|
||||||
|
LittleEndian.putByte(data, 0 + offset, sid + getPtgClass());
|
||||||
|
LittleEndian.putUShort(data, 1 + offset, field_1_index_extern_sheet);
|
||||||
|
LittleEndian.putInt(data, 3 + offset, unused1);
|
||||||
|
LittleEndian.putInt(data, 7 + offset, unused2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,13 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
|
|
||||||
package org.apache.poi.hssf.record.formula;
|
package org.apache.poi.hssf.record.formula;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.RecordInputStream;
|
import org.apache.poi.hssf.record.RecordInputStream;
|
||||||
|
import org.apache.poi.ss.usermodel.ErrorConstants;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Title: Deleted Reference 3D Ptg <P>
|
* Title: Deleted Reference 3D Ptg <P>
|
||||||
@ -28,16 +30,29 @@ import org.apache.poi.hssf.record.RecordInputStream;
|
|||||||
* @author Patrick Luby
|
* @author Patrick Luby
|
||||||
* @version 1.0-pre
|
* @version 1.0-pre
|
||||||
*/
|
*/
|
||||||
|
public final class DeletedRef3DPtg extends OperandPtg {
|
||||||
|
public final static byte sid = 0x3c;
|
||||||
|
private final int field_1_index_extern_sheet;
|
||||||
|
private final int unused1;
|
||||||
|
|
||||||
public class DeletedRef3DPtg extends Ref3DPtg {
|
/** Creates new DeletedRef3DPtg */
|
||||||
public final static byte sid = 0x3c;
|
public DeletedRef3DPtg(RecordInputStream in) {
|
||||||
|
field_1_index_extern_sheet = in.readUShort();
|
||||||
|
unused1 = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
/** Creates new DeletedRef3DPtg */
|
public String toFormulaString(Workbook book) {
|
||||||
public DeletedRef3DPtg(RecordInputStream in) {
|
return ErrorConstants.getText(ErrorConstants.ERROR_REF);
|
||||||
super(in);
|
}
|
||||||
}
|
public byte getDefaultOperandClass() {
|
||||||
|
return Ptg.CLASS_REF;
|
||||||
public DeletedRef3DPtg(String cellref, short externIdx ) {
|
}
|
||||||
super(cellref, externIdx);
|
public int getSize() {
|
||||||
}
|
return 7;
|
||||||
|
}
|
||||||
|
public void writeBytes(byte[] data, int offset) {
|
||||||
|
LittleEndian.putByte(data, 0 + offset, sid + getPtgClass());
|
||||||
|
LittleEndian.putUShort(data, 1 + offset, field_1_index_extern_sheet);
|
||||||
|
LittleEndian.putInt(data, 3 + offset, unused1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
* @author Jason Height (jheight at chariot dot net dot au)
|
* @author Jason Height (jheight at chariot dot net dot au)
|
||||||
* @version 1.0-pre
|
* @version 1.0-pre
|
||||||
*/
|
*/
|
||||||
public class Ref3DPtg extends OperandPtg {
|
public final class Ref3DPtg extends OperandPtg {
|
||||||
public final static byte sid = 0x3a;
|
public final static byte sid = 0x3a;
|
||||||
private final static int SIZE = 7; // 6 + 1 for Ptg
|
private final static int SIZE = 7; // 6 + 1 for Ptg
|
||||||
private short field_1_index_extern_sheet;
|
private short field_1_index_extern_sheet;
|
||||||
|
@ -16,67 +16,12 @@
|
|||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
import org.apache.poi.ss.usermodel.ErrorConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains raw Excel error codes (as defined in OOO's excelfileformat.pdf (2.5.6)
|
* Contains raw Excel error codes (as defined in OOO's excelfileformat.pdf (2.5.6)
|
||||||
*
|
*
|
||||||
* @author Michael Harhen
|
* @author Michael Harhen
|
||||||
*/
|
*/
|
||||||
public final class HSSFErrorConstants {
|
public final class HSSFErrorConstants extends ErrorConstants {
|
||||||
private HSSFErrorConstants() {
|
|
||||||
// no instances of this class
|
|
||||||
}
|
|
||||||
|
|
||||||
/** <b>#NULL!</b> - Intersection of two cell ranges is empty */
|
|
||||||
public static final int ERROR_NULL = 0x00;
|
|
||||||
/** <b>#DIV/0!</b> - Division by zero */
|
|
||||||
public static final int ERROR_DIV_0 = 0x07;
|
|
||||||
/** <b>#VALUE!</b> - Wrong type of operand */
|
|
||||||
public static final int ERROR_VALUE = 0x0F;
|
|
||||||
/** <b>#REF!</b> - Illegal or deleted cell reference */
|
|
||||||
public static final int ERROR_REF = 0x17;
|
|
||||||
/** <b>#NAME?</b> - Wrong function or range name */
|
|
||||||
public static final int ERROR_NAME = 0x1D;
|
|
||||||
/** <b>#NUM!</b> - Value range overflow */
|
|
||||||
public static final int ERROR_NUM = 0x24;
|
|
||||||
/** <b>#N/A</b> - Argument or function not available */
|
|
||||||
public static final int ERROR_NA = 0x2A;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Standard Excel error literal for the specified error code.
|
|
||||||
* @throws IllegalArgumentException if the specified error code is not one of the 7
|
|
||||||
* standard error codes
|
|
||||||
*/
|
|
||||||
public static final String getText(int errorCode) {
|
|
||||||
switch(errorCode) {
|
|
||||||
case ERROR_NULL: return "#NULL!";
|
|
||||||
case ERROR_DIV_0: return "#DIV/0!";
|
|
||||||
case ERROR_VALUE: return "#VALUE!";
|
|
||||||
case ERROR_REF: return "#REF!";
|
|
||||||
case ERROR_NAME: return "#NAME?";
|
|
||||||
case ERROR_NUM: return "#NUM!";
|
|
||||||
case ERROR_NA: return "#N/A";
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Bad error code (" + errorCode + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return <code>true</code> if the specified error code is a standard Excel error code.
|
|
||||||
*/
|
|
||||||
public static final boolean isValidCode(int errorCode) {
|
|
||||||
// This method exists because it would be bad to force clients to catch
|
|
||||||
// IllegalArgumentException if there were potential for passing an invalid error code.
|
|
||||||
switch(errorCode) {
|
|
||||||
case ERROR_NULL:
|
|
||||||
case ERROR_DIV_0:
|
|
||||||
case ERROR_VALUE:
|
|
||||||
case ERROR_REF:
|
|
||||||
case ERROR_NAME:
|
|
||||||
case ERROR_NUM:
|
|
||||||
case ERROR_NA:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,8 @@ public final class HSSFSheetConditionalFormatting {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory method allowing to create a conditional formatting rule
|
* A factory method allowing to create a conditional formatting rule
|
||||||
* with a cell comparison operator
|
* with a cell comparison operator<p/>
|
||||||
|
* TODO - formulas containing cell references are currently not parsed properly
|
||||||
*
|
*
|
||||||
* @param comparisonOperation - a constant value from
|
* @param comparisonOperation - a constant value from
|
||||||
* <tt>{@link HSSFConditionalFormattingRule.ComparisonOperator}</tt>: <p>
|
* <tt>{@link HSSFConditionalFormattingRule.ComparisonOperator}</tt>: <p>
|
||||||
@ -72,8 +73,8 @@ public final class HSSFSheetConditionalFormatting {
|
|||||||
/**
|
/**
|
||||||
* A factory method allowing to create a conditional formatting rule with a formula.<br>
|
* A factory method allowing to create a conditional formatting rule with a formula.<br>
|
||||||
*
|
*
|
||||||
* The formatting rules are applied by Excel when the value of the formula not equal to 0.
|
* The formatting rules are applied by Excel when the value of the formula not equal to 0.<p/>
|
||||||
*
|
* TODO - formulas containing cell references are currently not parsed properly
|
||||||
* @param formula - formula for the valued, compared with the cell
|
* @param formula - formula for the valued, compared with the cell
|
||||||
*/
|
*/
|
||||||
public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) {
|
public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) {
|
||||||
|
82
src/java/org/apache/poi/ss/usermodel/ErrorConstants.java
Normal file
82
src/java/org/apache/poi/ss/usermodel/ErrorConstants.java
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.ss.usermodel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains raw Excel error codes (as defined in OOO's excelfileformat.pdf (2.5.6)
|
||||||
|
*
|
||||||
|
* @author Michael Harhen
|
||||||
|
*/
|
||||||
|
public class ErrorConstants {
|
||||||
|
protected ErrorConstants() {
|
||||||
|
// no instances of this class
|
||||||
|
}
|
||||||
|
|
||||||
|
/** <b>#NULL!</b> - Intersection of two cell ranges is empty */
|
||||||
|
public static final int ERROR_NULL = 0x00;
|
||||||
|
/** <b>#DIV/0!</b> - Division by zero */
|
||||||
|
public static final int ERROR_DIV_0 = 0x07;
|
||||||
|
/** <b>#VALUE!</b> - Wrong type of operand */
|
||||||
|
public static final int ERROR_VALUE = 0x0F;
|
||||||
|
/** <b>#REF!</b> - Illegal or deleted cell reference */
|
||||||
|
public static final int ERROR_REF = 0x17;
|
||||||
|
/** <b>#NAME?</b> - Wrong function or range name */
|
||||||
|
public static final int ERROR_NAME = 0x1D;
|
||||||
|
/** <b>#NUM!</b> - Value range overflow */
|
||||||
|
public static final int ERROR_NUM = 0x24;
|
||||||
|
/** <b>#N/A</b> - Argument or function not available */
|
||||||
|
public static final int ERROR_NA = 0x2A;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Standard Excel error literal for the specified error code.
|
||||||
|
* @throws IllegalArgumentException if the specified error code is not one of the 7
|
||||||
|
* standard error codes
|
||||||
|
*/
|
||||||
|
public static final String getText(int errorCode) {
|
||||||
|
switch(errorCode) {
|
||||||
|
case ERROR_NULL: return "#NULL!";
|
||||||
|
case ERROR_DIV_0: return "#DIV/0!";
|
||||||
|
case ERROR_VALUE: return "#VALUE!";
|
||||||
|
case ERROR_REF: return "#REF!";
|
||||||
|
case ERROR_NAME: return "#NAME?";
|
||||||
|
case ERROR_NUM: return "#NUM!";
|
||||||
|
case ERROR_NA: return "#N/A";
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Bad error code (" + errorCode + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return <code>true</code> if the specified error code is a standard Excel error code.
|
||||||
|
*/
|
||||||
|
public static final boolean isValidCode(int errorCode) {
|
||||||
|
// This method exists because it would be bad to force clients to catch
|
||||||
|
// IllegalArgumentException if there were potential for passing an invalid error code.
|
||||||
|
switch(errorCode) {
|
||||||
|
case ERROR_NULL:
|
||||||
|
case ERROR_DIV_0:
|
||||||
|
case ERROR_VALUE:
|
||||||
|
case ERROR_REF:
|
||||||
|
case ERROR_NAME:
|
||||||
|
case ERROR_NUM:
|
||||||
|
case ERROR_NA:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -355,7 +355,7 @@ public abstract class TextShape extends SimpleShape {
|
|||||||
*/
|
*/
|
||||||
public float getMarginLeft(){
|
public float getMarginLeft(){
|
||||||
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
|
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTLEFT);
|
||||||
int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
|
int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
|
||||||
return (float)val/EMU_PER_POINT;
|
return (float)val/EMU_PER_POINT;
|
||||||
}
|
}
|
||||||
|
@ -635,27 +635,24 @@ public class Range
|
|||||||
/**
|
/**
|
||||||
* Replace (one instance of) a piece of text with another...
|
* Replace (one instance of) a piece of text with another...
|
||||||
*
|
*
|
||||||
* @param pPlaceHolder The text to be replaced (e.g., "${company}")
|
* @param pPlaceHolder The text to be replaced (e.g., "${organization}")
|
||||||
* @param pValue The replacement text (e.g., "Cognocys, Inc.")
|
* @param pValue The replacement text (e.g., "Apache Software Foundation")
|
||||||
* @param pDocument The <code>HWPFDocument</code> in which the placeholder was found
|
* @param pOffset The offset or index where the text to be replaced begins
|
||||||
* @param pStartOffset The offset or index where the <code>CharacterRun</code> begins
|
* (relative to/within this <code>Range</code>)
|
||||||
* @param pPlaceHolderIndex The offset or index of the placeholder,
|
|
||||||
* relative to the <code>CharacterRun</code> where
|
|
||||||
* <code>pPlaceHolder</code> was found
|
|
||||||
*/
|
*/
|
||||||
protected void replaceText(String pPlaceHolder, String pValue,
|
public void replaceText(String pPlaceHolder, String pValue, int pOffset)
|
||||||
int pStartOffset, int pPlaceHolderIndex, HWPFDocument pDocument) {
|
{
|
||||||
int absPlaceHolderIndex = pStartOffset + pPlaceHolderIndex;
|
int absPlaceHolderIndex = getStartOffset() + pOffset;
|
||||||
Range subRange = new Range(
|
Range subRange = new Range(
|
||||||
absPlaceHolderIndex,
|
absPlaceHolderIndex,
|
||||||
(absPlaceHolderIndex + pPlaceHolder.length()), pDocument
|
(absPlaceHolderIndex + pPlaceHolder.length()), getDocument()
|
||||||
);
|
);
|
||||||
if (subRange.usesUnicode()) {
|
if (subRange.usesUnicode()) {
|
||||||
absPlaceHolderIndex = pStartOffset + (pPlaceHolderIndex * 2);
|
absPlaceHolderIndex = getStartOffset() + (pOffset * 2);
|
||||||
subRange = new Range(
|
subRange = new Range(
|
||||||
absPlaceHolderIndex,
|
absPlaceHolderIndex,
|
||||||
(absPlaceHolderIndex + (pPlaceHolder.length() * 2)),
|
(absPlaceHolderIndex + (pPlaceHolder.length() * 2)),
|
||||||
pDocument
|
getDocument()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,13 +662,13 @@ public class Range
|
|||||||
subRange = new Range(
|
subRange = new Range(
|
||||||
(absPlaceHolderIndex + pValue.length()),
|
(absPlaceHolderIndex + pValue.length()),
|
||||||
(absPlaceHolderIndex + pPlaceHolder.length() + pValue.length()),
|
(absPlaceHolderIndex + pPlaceHolder.length() + pValue.length()),
|
||||||
pDocument
|
getDocument()
|
||||||
);
|
);
|
||||||
if (subRange.usesUnicode())
|
if (subRange.usesUnicode())
|
||||||
subRange = new Range(
|
subRange = new Range(
|
||||||
(absPlaceHolderIndex + (pValue.length() * 2)),
|
(absPlaceHolderIndex + (pValue.length() * 2)),
|
||||||
(absPlaceHolderIndex + (pPlaceHolder.length() * 2) +
|
(absPlaceHolderIndex + (pPlaceHolder.length() * 2) +
|
||||||
(pValue.length() * 2)), pDocument
|
(pValue.length() * 2)), getDocument()
|
||||||
);
|
);
|
||||||
|
|
||||||
subRange.delete();
|
subRange.delete();
|
||||||
@ -942,4 +939,9 @@ public class Range
|
|||||||
|
|
||||||
return _end;
|
return _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected HWPFDocument getDocument() {
|
||||||
|
|
||||||
|
return _doc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
BIN
src/scratchpad/testcases/org/apache/poi/hslf/data/text-margins.ppt
Executable file
BIN
src/scratchpad/testcases/org/apache/poi/hslf/data/text-margins.ppt
Executable file
Binary file not shown.
@ -23,6 +23,7 @@ import junit.framework.TestCase;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.apache.poi.hslf.usermodel.SlideShow;
|
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||||
import org.apache.poi.hslf.record.TextHeaderAtom;
|
import org.apache.poi.hslf.record.TextHeaderAtom;
|
||||||
@ -157,4 +158,46 @@ public class TestTextShape extends TestCase {
|
|||||||
assertEquals("Testing TextShape", shape1.getTextRun().getText());
|
assertEquals("Testing TextShape", shape1.getTextRun().getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testMargins() throws IOException {
|
||||||
|
FileInputStream is = new FileInputStream(new File(cwd, "text-margins.ppt"));
|
||||||
|
SlideShow ppt = new SlideShow(is);
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
Slide slide = ppt.getSlides()[0];
|
||||||
|
|
||||||
|
HashMap map = new HashMap();
|
||||||
|
Shape[] shape = slide.getShapes();
|
||||||
|
for (int i = 0; i < shape.length; i++) {
|
||||||
|
if(shape[i] instanceof TextShape){
|
||||||
|
TextShape tx = (TextShape)shape[i];
|
||||||
|
map.put(tx.getText(), tx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextShape tx;
|
||||||
|
|
||||||
|
tx = (TextShape)map.get("TEST1");
|
||||||
|
assertEquals(0.1, tx.getMarginLeft()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.1, tx.getMarginRight()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.39, tx.getMarginTop()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.05, tx.getMarginBottom()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
|
||||||
|
tx = (TextShape)map.get("TEST2");
|
||||||
|
assertEquals(0.1, tx.getMarginLeft()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.1, tx.getMarginRight()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.05, tx.getMarginTop()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.39, tx.getMarginBottom()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
|
||||||
|
tx = (TextShape)map.get("TEST3");
|
||||||
|
assertEquals(0.39, tx.getMarginLeft()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.1, tx.getMarginRight()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.05, tx.getMarginTop()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.05, tx.getMarginBottom()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
|
||||||
|
tx = (TextShape)map.get("TEST4");
|
||||||
|
assertEquals(0.1, tx.getMarginLeft()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.39, tx.getMarginRight()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.05, tx.getMarginTop()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
assertEquals(0.05, tx.getMarginBottom()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -0,0 +1,119 @@
|
|||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
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.hwpf.usermodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
|
import org.apache.poi.hwpf.model.PicturesTable;
|
||||||
|
import org.apache.poi.hwpf.usermodel.Picture;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test to see if Range.replaceText() works even if the Range contains a
|
||||||
|
* CharacterRun that uses Unicode characters.
|
||||||
|
*/
|
||||||
|
public class TestRangeReplacement extends TestCase {
|
||||||
|
|
||||||
|
// u201c and u201d are "smart-quotes"
|
||||||
|
private String originalText =
|
||||||
|
"It is used to confirm that text replacement works even if Unicode characters (such as \u201c\u2014\u201d (U+2014), \u201c\u2e8e\u201d (U+2E8E), or \u201c\u2714\u201d (U+2714)) are present. Everybody should be thankful to the ${organization} and all the POI contributors for their assistance in this matter.\r";
|
||||||
|
private String searchText = "${organization}";
|
||||||
|
private String replacementText = "Apache Software Foundation";
|
||||||
|
private String expectedText =
|
||||||
|
"It is used to confirm that text replacement works even if Unicode characters (such as \u201c\u2014\u201d (U+2014), \u201c\u2e8e\u201d (U+2E8E), or \u201c\u2714\u201d (U+2714)) are present. Everybody should be thankful to the Apache Software Foundation and all the POI contributors for their assistance in this matter.\r";
|
||||||
|
|
||||||
|
private String illustrativeDocFile;
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
|
||||||
|
String dirname = System.getProperty("HWPF.testdata.path");
|
||||||
|
|
||||||
|
illustrativeDocFile = dirname + "/testRangeReplacement.doc";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test just opening the files
|
||||||
|
*/
|
||||||
|
public void testOpen() throws Exception {
|
||||||
|
|
||||||
|
HWPFDocument docA = new HWPFDocument(new FileInputStream(illustrativeDocFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test (more "confirm" than test) that we have the general structure that we expect to have.
|
||||||
|
*/
|
||||||
|
public void testDocStructure() throws Exception {
|
||||||
|
|
||||||
|
HWPFDocument daDoc = new HWPFDocument(new FileInputStream(illustrativeDocFile));
|
||||||
|
|
||||||
|
Range range = daDoc.getRange();
|
||||||
|
|
||||||
|
assertEquals(1, range.numSections());
|
||||||
|
Section section = range.getSection(0);
|
||||||
|
|
||||||
|
assertEquals(5, section.numParagraphs());
|
||||||
|
Paragraph para = section.getParagraph(2);
|
||||||
|
|
||||||
|
assertEquals(5, para.numCharacterRuns());
|
||||||
|
String text = para.getCharacterRun(0).text() + para.getCharacterRun(1).text() +
|
||||||
|
para.getCharacterRun(2).text() + para.getCharacterRun(3).text() + para.getCharacterRun(4).text();
|
||||||
|
|
||||||
|
assertEquals(originalText, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that we can replace text in our Range with Unicode text.
|
||||||
|
*/
|
||||||
|
public void testRangeReplacement() throws Exception {
|
||||||
|
|
||||||
|
HWPFDocument daDoc = new HWPFDocument(new FileInputStream(illustrativeDocFile));
|
||||||
|
|
||||||
|
Range range = daDoc.getRange();
|
||||||
|
assertEquals(1, range.numSections());
|
||||||
|
|
||||||
|
Section section = range.getSection(0);
|
||||||
|
assertEquals(5, section.numParagraphs());
|
||||||
|
|
||||||
|
Paragraph para = section.getParagraph(2);
|
||||||
|
|
||||||
|
String text = para.text();
|
||||||
|
assertEquals(originalText, text);
|
||||||
|
|
||||||
|
int offset = text.indexOf(searchText);
|
||||||
|
assertEquals(181, offset);
|
||||||
|
|
||||||
|
para.replaceText(searchText, replacementText, offset);
|
||||||
|
|
||||||
|
// we need to let the model re-calculate the Range before we evaluate it
|
||||||
|
range = daDoc.getRange();
|
||||||
|
|
||||||
|
assertEquals(1, range.numSections());
|
||||||
|
section = range.getSection(0);
|
||||||
|
|
||||||
|
assertEquals(5, section.numParagraphs());
|
||||||
|
para = section.getParagraph(2);
|
||||||
|
|
||||||
|
text = para.text();
|
||||||
|
assertEquals(expectedText, text);
|
||||||
|
}
|
||||||
|
}
|
BIN
src/testcases/org/apache/poi/hssf/data/30978-alt.xls
Normal file
BIN
src/testcases/org/apache/poi/hssf/data/30978-alt.xls
Normal file
Binary file not shown.
@ -17,12 +17,16 @@
|
|||||||
|
|
||||||
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.CFRuleRecord.ComparisonOperator;
|
import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
|
||||||
import org.apache.poi.hssf.record.cf.BorderFormatting;
|
import org.apache.poi.hssf.record.cf.BorderFormatting;
|
||||||
import org.apache.poi.hssf.record.cf.FontFormatting;
|
import org.apache.poi.hssf.record.cf.FontFormatting;
|
||||||
import org.apache.poi.hssf.record.cf.PatternFormatting;
|
import org.apache.poi.hssf.record.cf.PatternFormatting;
|
||||||
|
import org.apache.poi.hssf.record.formula.Ptg;
|
||||||
|
import org.apache.poi.hssf.record.formula.RefNPtg;
|
||||||
|
import org.apache.poi.hssf.record.formula.RefPtg;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.hssf.util.HSSFColor;
|
import org.apache.poi.hssf.util.HSSFColor;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
@ -296,7 +300,57 @@ public final class TestCFRuleRecord extends TestCase
|
|||||||
// check all remaining flag bits (some are not well understood yet)
|
// check all remaining flag bits (some are not well understood yet)
|
||||||
assertEquals(0x203FFFFF, flags);
|
assertEquals(0x203FFFFF, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final byte[] DATA_REFN = {
|
||||||
|
// formula extracted from bugzilla 45234 att 22141
|
||||||
|
1, 3,
|
||||||
|
9, // formula 1 length
|
||||||
|
0, 0, 0, -1, -1, 63, 32, 2, -128, 0, 0, 0, 5,
|
||||||
|
// formula 1: "=B3=1" (formula is relative to B4)
|
||||||
|
76, -1, -1, 0, -64, // tRefN(B1)
|
||||||
|
30, 1, 0,
|
||||||
|
11,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tRefN and tAreaN tokens must be preserved when re-serializing conditional format formulas
|
||||||
|
*/
|
||||||
|
public void testReserializeRefNTokens() {
|
||||||
|
|
||||||
|
RecordInputStream is = new TestcaseRecordInputStream(CFRuleRecord.sid, DATA_REFN);
|
||||||
|
CFRuleRecord rr = new CFRuleRecord(is);
|
||||||
|
Ptg[] ptgs = rr.getParsedExpression1();
|
||||||
|
assertEquals(3, ptgs.length);
|
||||||
|
if (ptgs[0] instanceof RefPtg) {
|
||||||
|
throw new AssertionFailedError("Identified bug 45234");
|
||||||
|
}
|
||||||
|
assertEquals(RefNPtg.class, ptgs[0].getClass());
|
||||||
|
RefNPtg refNPtg = (RefNPtg) ptgs[0];
|
||||||
|
assertTrue(refNPtg.isColRelative());
|
||||||
|
assertTrue(refNPtg.isRowRelative());
|
||||||
|
|
||||||
|
byte[] data = rr.serialize();
|
||||||
|
|
||||||
|
if (!compareArrays(DATA_REFN, 0, data, 4, DATA_REFN.length)) {
|
||||||
|
fail("Did not re-serialize correctly");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean compareArrays(byte[] arrayA, int offsetA, byte[] arrayB, int offsetB, int length) {
|
||||||
|
|
||||||
|
if (offsetA + length > arrayA.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (offsetB + length > arrayB.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (arrayA[i+offsetA] != arrayB[i+offsetB]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] ignored_args)
|
public static void main(String[] ignored_args)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,10 @@ import junit.framework.TestCase;
|
|||||||
import org.apache.poi.ss.util.Region;
|
import org.apache.poi.ss.util.Region;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
|
import org.apache.poi.hssf.model.Workbook;
|
||||||
import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
|
import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
|
||||||
|
import org.apache.poi.hssf.record.NameRecord;
|
||||||
|
import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
|
||||||
import org.apache.poi.util.TempFile;
|
import org.apache.poi.util.TempFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -990,4 +993,63 @@ public final class TestBugs extends TestCase {
|
|||||||
fail();
|
fail();
|
||||||
} catch(FileNotFoundException e) {}
|
} catch(FileNotFoundException e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that we can delete sheets without
|
||||||
|
* breaking the build in named ranges
|
||||||
|
* used for printing stuff.
|
||||||
|
* Currently broken, as we change the Ptg
|
||||||
|
*/
|
||||||
|
public void test30978() throws Exception {
|
||||||
|
HSSFWorkbook wb = openSample("30978-alt.xls");
|
||||||
|
assertEquals(1, wb.getNumberOfNames());
|
||||||
|
assertEquals(3, wb.getNumberOfSheets());
|
||||||
|
|
||||||
|
// Check all names fit within range, and use
|
||||||
|
// DeletedArea3DPtg
|
||||||
|
Workbook w = wb.getWorkbook();
|
||||||
|
for(int i=0; i<w.getNumNames(); i++) {
|
||||||
|
NameRecord r = w.getNameRecord(i);
|
||||||
|
assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
|
||||||
|
|
||||||
|
List nd = r.getNameDefinition();
|
||||||
|
assertEquals(1, nd.size());
|
||||||
|
assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Delete the 2nd sheet
|
||||||
|
wb.removeSheetAt(1);
|
||||||
|
|
||||||
|
|
||||||
|
// Re-check
|
||||||
|
assertEquals(1, wb.getNumberOfNames());
|
||||||
|
assertEquals(2, wb.getNumberOfSheets());
|
||||||
|
|
||||||
|
for(int i=0; i<w.getNumNames(); i++) {
|
||||||
|
NameRecord r = w.getNameRecord(i);
|
||||||
|
assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
|
||||||
|
|
||||||
|
List nd = r.getNameDefinition();
|
||||||
|
assertEquals(1, nd.size());
|
||||||
|
assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Save and re-load
|
||||||
|
wb = writeOutAndReadBack(wb);
|
||||||
|
w = wb.getWorkbook();
|
||||||
|
|
||||||
|
assertEquals(1, wb.getNumberOfNames());
|
||||||
|
assertEquals(2, wb.getNumberOfSheets());
|
||||||
|
|
||||||
|
for(int i=0; i<w.getNumNames(); i++) {
|
||||||
|
NameRecord r = w.getNameRecord(i);
|
||||||
|
assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
|
||||||
|
|
||||||
|
List nd = r.getNameDefinition();
|
||||||
|
assertEquals(1, nd.size());
|
||||||
|
assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user