Browse Source

Fix for bug 46174 - HSSFName now handles general formulas (not just area references)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@713909 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_5_BETA4
Josh Micich 15 years ago
parent
commit
dfa42cbf38

+ 1
- 0
src/documentation/content/xdocs/changes.xml View File

@@ -37,6 +37,7 @@

<!-- Don't forget to update status.xml too! -->
<release version="3.5-beta4" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">46174 - Fixed HSSFName to handle general formulas (not just area references)</header>
<action dev="POI-DEVELOPERS" type="add">46189 - added chart records: CHARTFRTINFO, STARTBLOCK, ENDBLOCK, STARTOBJECT, ENDOBJECT, and CATLAB</action>
<action dev="POI-DEVELOPERS" type="fix">46199 - More tweaks to EmbeddedObjectRefSubRecord</header>
<action dev="POI-DEVELOPERS" type="add">Changes to formula evaluation allowing for reduced memory usage</action>

+ 1
- 0
src/documentation/content/xdocs/status.xml View File

@@ -34,6 +34,7 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.5-beta4" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">46174 - Fixed HSSFName to handle general formulas (not just area references)</header>
<action dev="POI-DEVELOPERS" type="add">46189 - added chart records: CHARTFRTINFO, STARTBLOCK, ENDBLOCK, STARTOBJECT, ENDOBJECT, and CATLAB</action>
<action dev="POI-DEVELOPERS" type="fix">46199 - More tweaks to EmbeddedObjectRefSubRecord</header>
<action dev="POI-DEVELOPERS" type="add">Changes to formula evaluation allowing for reduced memory usage</action>

+ 0
- 89
src/java/org/apache/poi/hssf/record/NameRecord.java View File

@@ -17,18 +17,10 @@

package org.apache.poi.hssf.record;

import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.Ref3DPtg;
import org.apache.poi.hssf.record.formula.UnionPtg;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.RangeAddress;
import org.apache.poi.ss.formula.Formula;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
@@ -414,87 +406,6 @@ public final class NameRecord extends StandardRecord {
return 0;
}

/** sets the extern sheet number
* @param externSheetNumber extern sheet number
*/
public void setExternSheetNumber(short externSheetNumber){
Ptg[] ptgs = field_13_name_definition.getTokens();
Ptg ptg;

if (ptgs.length < 1){
ptg = createNewPtg();
ptgs = new Ptg[] { ptg, };
} else {
ptg = ptgs[0];
}

if (ptg.getClass() == Area3DPtg.class){
((Area3DPtg) ptg).setExternSheetIndex(externSheetNumber);

} else if (ptg.getClass() == Ref3DPtg.class){
((Ref3DPtg) ptg).setExternSheetIndex(externSheetNumber);
}
field_13_name_definition = Formula.create(ptgs);
}

private static Ptg createNewPtg(){
return new Area3DPtg("A1:A1", 0); // TODO - change to not be partially initialised
}

/** gets the reference , the area only (range)
* @return area reference
*/
public String getAreaReference(HSSFWorkbook book){
return HSSFFormulaParser.toFormulaString(book, field_13_name_definition.getTokens());
}

/** sets the reference , the area only (range)
* @param ref area reference
*/
public void setAreaReference(String ref){
//Trying to find if what ptg do we need
RangeAddress ra = new RangeAddress(ref);
Ptg oldPtg;

if (field_13_name_definition.getEncodedTokenSize() < 1){
oldPtg = createNewPtg();
} else {
//Trying to find extern sheet index
oldPtg = field_13_name_definition.getTokens()[0];
}
List temp = new ArrayList();
int externSheetIndex = 0;

if (oldPtg.getClass() == Area3DPtg.class){
externSheetIndex = ((Area3DPtg) oldPtg).getExternSheetIndex();

} else if (oldPtg.getClass() == Ref3DPtg.class){
externSheetIndex = ((Ref3DPtg) oldPtg).getExternSheetIndex();
}

if (ra.hasRange()) {
// Is it contiguous or not?
AreaReference[] refs = AreaReference.generateContiguous(ref);

// Add the area reference(s)
for(int i=0; i<refs.length; i++) {
Ptg ptg = new Area3DPtg(refs[i].formatAsString(), externSheetIndex);
temp.add(ptg);
}
// And then a union if we had more than one area
if(refs.length > 1) {
Ptg ptg = UnionPtg.instance;
temp.add(ptg);
}
} else {
Ref3DPtg ptg = new Ref3DPtg(ra.getFromCell(), externSheetIndex);
temp.add(ptg);
}
Ptg[] ptgs = new Ptg[temp.size()];
temp.toArray(ptgs);
field_13_name_definition = Formula.create(ptgs);
}

/**
* called by the constructor, should set class level fields. Should throw
* runtime exception for bad/icomplete data.

+ 17
- 26
src/java/org/apache/poi/hssf/usermodel/HSSFName.java View File

@@ -17,9 +17,10 @@

package org.apache.poi.hssf.usermodel;

import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.util.RangeAddress;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.ss.usermodel.Name;

/**
@@ -80,43 +81,33 @@ public final class HSSFName implements Name {
}

/**
* Note - this method only applies to named ranges
* @return the formula text defining the named range
* @deprecated (Nov 2008) Misleading name. Use {@link #getFormula()} instead.
*/
public String getReference() {
if (_definedNameRec.isFunctionName()) {
throw new IllegalStateException("Only applicable to named ranges");
}
return _definedNameRec.getAreaReference(_book);
return getFormula();
}

/**
* sets the sheet name which this named range referenced to
* @param sheetName the sheet name of the reference
* @deprecated (Nov 2008) Misleading name. Use {@link #setFormula(String)} instead.
*/
private void setSheetName(String sheetName){
int sheetNumber = _book.getSheetIndex(sheetName);
short externSheetNumber = _book.getWorkbook().checkExternSheet(sheetNumber);
_definedNameRec.setExternSheetNumber(externSheetNumber);
public void setReference(String ref){
setFormula(ref);
}

public void setFormula(String formulaText) {
Ptg[] ptgs = HSSFFormulaParser.parse(formulaText, _book);
_definedNameRec.setNameDefinition(ptgs);
}

/**
* sets the reference of this named range
* @param ref the reference to set
* Note - this method only applies to named ranges
* @return the formula text defining this name
*/
public void setReference(String ref){

RangeAddress ra = new RangeAddress(ref);

String sheetName = ra.getSheetName();

if (ra.hasSheetName()) {
setSheetName(sheetName);
public String getFormula() {
if (_definedNameRec.isFunctionName()) {
throw new IllegalStateException("Only applicable to named ranges");
}

//allow the poi utilities to parse it out
_definedNameRec.setAreaReference(ref);
return HSSFFormulaParser.toFormulaString(_book, _definedNameRec.getNameDefinition());
}

/**

+ 18
- 15
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java View File

@@ -33,6 +33,7 @@ import org.apache.poi.ddf.EscherBSERecord;
import org.apache.poi.ddf.EscherBitmapBlip;
import org.apache.poi.ddf.EscherBlipRecord;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
@@ -57,6 +58,7 @@ import org.apache.poi.hssf.record.formula.MemFuncPtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.Ref3DPtg;
import org.apache.poi.hssf.record.formula.SheetNameFormatter;
import org.apache.poi.hssf.record.formula.UnionPtg;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.poifs.filesystem.DirectoryNode;
@@ -1364,15 +1366,15 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);


if (name == null)
name = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
//adding one here because 0 indicates a global named region; doesnt make sense for print areas
short externSheetIndex = getWorkbook().checkExternSheet(sheetIndex);
name.setExternSheetNumber(externSheetIndex);
name.setAreaReference(reference);
if (name == null) {
name = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
// adding one here because 0 indicates a global named region; doesn't make sense for print areas
}
StringBuffer sb = new StringBuffer(32);
SheetNameFormatter.appendFormat(sb, getSheetName(sheetIndex));
sb.append("!");
sb.append(reference);
name.setNameDefinition(HSSFFormulaParser.parse(sb.toString(), this));
}

/**
@@ -1403,13 +1405,14 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
* @return String Null if no print area has been defined
*/
public String getPrintArea(int sheetIndex)
{
public String getPrintArea(int sheetIndex) {
NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
if (name == null) return null;
//adding one here because 0 indicates a global named region; doesnt make sense for print areas

return name.getAreaReference(this);
//adding one here because 0 indicates a global named region; doesn't make sense for print areas
if (name == null) {
return null;
}
return HSSFFormulaParser.toFormulaString(this, name.getNameDefinition());
}

/**

+ 0
- 367
src/java/org/apache/poi/hssf/util/RangeAddress.java View File

@@ -1,367 +0,0 @@
/* ====================================================================
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.util;



/**
* Title: Range Address <P>
* Description: provides connectivity utilities for ranges<P>
*
*
* REFERENCE: <P>
* @author IgOr KaTz && EuGeNe BuMaGiN (Tal Moshaiov) (VistaPortal LDT.)
@version 1.0
*/

public class RangeAddress {
final static int WRONG_POS = -1;
final static int MAX_HEIGHT = 66666;
final static char SO_FORMNAME_ENCLOSURE = '\'';
String m_sheetName;
String m_cellFrom;
String m_cellTo;

/**
* Accepts an external reference from excel.
* <p>
* i.e. Sheet1!$A$4:$B$9
* @param _url
*/
public RangeAddress (String _url) {
init (_url);
}
public RangeAddress (int _startCol, int _startRow, int _endCol, int _endRow) {
init (numTo26Sys (_startCol) + _startRow + ":"
+ numTo26Sys (_endCol) + _endRow);
}
/**
*
* @return String <b>note: </b> All absolute references are removed
*/
public String getAddress (){
String result = "";
if(m_sheetName != null)
result += m_sheetName+"!";
if(m_cellFrom != null){
result += m_cellFrom;
if(m_cellTo != null)
result += ":" + m_cellTo;
}
return result;
}
public String getSheetName (){
return m_sheetName;
}
public String getRange (){
String result = "";
if(m_cellFrom != null){
result += m_cellFrom;
if(m_cellTo != null)
result += ":" + m_cellTo;
}
return result;
}
public boolean isCellOk (String _cell){
if (_cell != null){
if ( (getYPosition (_cell) != WRONG_POS) &&
(getXPosition (_cell) != WRONG_POS) )
return true;
else
return false;
} else
return false;
}
public boolean isSheetNameOk (){
return isSheetNameOk (m_sheetName);
}
private static boolean intern_isSheetNameOk (String _sheetName, boolean _canBeWaitSpace){
for (int i = 0 ; i < _sheetName.length (); i++){
char ch = _sheetName.charAt (i);
if (! (Character.isLetterOrDigit (ch) || (ch == '_')||
_canBeWaitSpace&&(ch == ' '))){
return false;
}
}
return true;
}
public static boolean isSheetNameOk (String _sheetName){
boolean res = false;
if ( ( _sheetName != null) && !_sheetName.equals ("")){
res = intern_isSheetNameOk (_sheetName,true);
}else
res = true;
return res;
}
public String getFromCell (){
return m_cellFrom;
}
public String getToCell (){
return m_cellTo;
}
public int getWidth (){
if(m_cellFrom != null && m_cellTo != null){
int toX = getXPosition (m_cellTo);
int fromX = getXPosition (m_cellFrom);
if ((toX == WRONG_POS) || (fromX == WRONG_POS)){
return 0;
}else
return toX - fromX + 1;
}
return 0;
}
public int getHeight (){
if(m_cellFrom != null && m_cellTo != null){
int toY = getYPosition (m_cellTo);
int fromY = getYPosition (m_cellFrom);
if ((toY == WRONG_POS) || (fromY == WRONG_POS)){
return 0;
}else
return toY - fromY + 1;
}
return 0;
}
public void setSize (int _width, int _height){
if(m_cellFrom == null)
m_cellFrom = "a1";
int tlX, tlY, rbX, rbY;
tlX = getXPosition (m_cellFrom);
tlY = getYPosition (m_cellFrom);
m_cellTo = numTo26Sys (tlX + _width - 1);
m_cellTo += String.valueOf (tlY + _height - 1);
}
public boolean hasSheetName (){
if(m_sheetName == null)
return false;
return true;
}
public boolean hasRange (){
return (m_cellFrom != null && m_cellTo != null && !m_cellFrom.equals(m_cellTo));
}
public boolean hasCell (){
if(m_cellFrom == null)
return false;
return true;
}
private void init (String _url){

_url = removeString(_url, "$");
_url = removeString(_url, "'");
String[] urls = parseURL (_url);
m_sheetName = urls[0];
m_cellFrom = urls[1];
m_cellTo = urls[2];

//What if range is one celled ?
if (m_cellTo == null){
m_cellTo = m_cellFrom;
}
//Removing noneeds characters
m_cellTo = removeString(m_cellTo,".");
}
private String[] parseURL (String _url){
String[] result = new String[3];
int index = _url.indexOf(':');
if (index >= 0) {
String fromStr = _url.substring(0, index);
String toStr = _url.substring(index+1);
index = fromStr.indexOf('!');
if (index >= 0) {
result[0] = fromStr.substring(0, index);
result[1] = fromStr.substring(index+1);
} else {
result[1] = fromStr;
}
index = toStr.indexOf('!');
if (index >= 0) {
result[2] = toStr.substring(index+1);
} else {
result[2] = toStr;
}
} else {
index = _url.indexOf('!');
if (index >= 0) {
result[0] = _url.substring(0, index);
result[1] = _url.substring(index+1);
} else {
result[1] = _url;
}
}
return result;
}
public int getYPosition (String _subrange){
int result = WRONG_POS;
_subrange = _subrange.trim ();
if (_subrange.length () != 0){
String digitstr = getDigitPart (_subrange);
try {
result = Integer.parseInt (digitstr);
if (result > MAX_HEIGHT){
result = WRONG_POS;
}
}
catch (Exception ex) {
result = WRONG_POS;
}
}
return result;
}
private static boolean isLetter (String _str){
boolean res = true;
if ( !_str.equals ("") ){
for (int i = 0 ; i < _str.length (); i++){
char ch = _str.charAt (i);
if (! Character.isLetter (ch)){
res = false;
break;
}
}
}else
res = false;
return res;
}
public int getXPosition (String _subrange){
int result = WRONG_POS;
String tmp = filter$ (_subrange);
tmp = this.getCharPart (_subrange);
// we will process only 2 letters ranges
if (isLetter (tmp) && ((tmp.length () == 2)|| (tmp.length () == 1) )){
result = get26Sys (tmp);
}
return result;
}
public String getDigitPart (String _value){
String result = "";
int digitpos = getFirstDigitPosition (_value);
if(digitpos >= 0){
result = _value.substring (digitpos);
}
return result;
}
public String getCharPart (String _value){
String result = "";
int digitpos = getFirstDigitPosition (_value);
if(digitpos >= 0){
result = _value.substring (0, digitpos);
}
return result;
}
private String filter$ (String _range){
String res = "";
for (int i = 0 ; i < _range.length () ; i++){
char ch = _range.charAt (i);
if ( ch != '$' ){
res = res + ch;
}
}
return res;
}
private int getFirstDigitPosition (String _value){
int result = WRONG_POS;
if(_value != null && _value.trim ().length () == 0){
return result;
}
_value = _value.trim ();
int length = _value.length ();
for(int i = 0; i < length; i++){
if(Character.isDigit (_value.charAt (i))){
result = i;
break;
}
}
return result;
}
public int get26Sys (String _s){
int sum = 0;
int multiplier = 1;
if (_s != "") {
for (int i = _s.length ()-1 ; i >= 0 ; i--){
char ch = _s.charAt (i);
int val = Character.getNumericValue (ch) - Character.getNumericValue ('A')+1;
sum = sum + val * multiplier;
multiplier = multiplier * 26;
}
return sum;
}
return WRONG_POS;
}
public String numTo26Sys (int _num){
int sum = 0;
int reminder;
String s ="";
do{
_num --;
reminder = _num % 26;
int val = 65 + reminder;
_num = _num / 26;
s = (char)val + s; // reverce
}while(_num > 0);
return s;
}
public String replaceString(String _source , String _oldPattern,
String _newPattern){
StringBuffer res = new StringBuffer(_source);
int pos = -1;
while ((pos = res.toString().indexOf(_oldPattern, pos)) > -1){
res.replace(pos, pos + _oldPattern.length(), _newPattern);
}
return res.toString();
}
public String removeString(String _source, String _match){
return replaceString(_source, _match, "");
}
}

+ 14
- 11
src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java View File

@@ -41,7 +41,6 @@ public final class TestFormulaParserEval extends TestCase {

public void testWithNamedRange() {
HSSFWorkbook workbook = new HSSFWorkbook();
Ptg[] ptgs;

HSSFSheet s = workbook.createSheet("Foo");
s.createRow(0).createCell(0).setCellValue(1.1);
@@ -52,21 +51,25 @@ public final class TestFormulaParserEval extends TestCase {
name.setNameName("testName");
name.setReference("A1:A2");

ptgs = HSSFFormulaParser.parse("SUM(testName)", workbook);
assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2);
assertEquals(NamePtg.class, ptgs[0].getClass());
assertEquals(FuncVarPtg.class, ptgs[1].getClass());
confirmParseFormula(workbook);

// Now make it a single cell
name.setReference("C3");
ptgs = HSSFFormulaParser.parse("SUM(testName)", workbook);
assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2);
assertEquals(NamePtg.class, ptgs[0].getClass());
assertEquals(FuncVarPtg.class, ptgs[1].getClass());
confirmParseFormula(workbook);
// And make it non-contiguous
name.setReference("A1:A2,C3");
ptgs = HSSFFormulaParser.parse("SUM(testName)", workbook);
if (false) { // TODO (Nov 2008) - make the formula parser support area unions
name.setReference("A1:A2,C3");
}
confirmParseFormula(workbook);
}

/**
* Makes sure that a formula referring to the named range parses properly
*/
private static void confirmParseFormula(HSSFWorkbook workbook) {
Ptg[] ptgs = HSSFFormulaParser.parse("SUM(testName)", workbook);
assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2);
assertEquals(NamePtg.class, ptgs[0].getClass());
assertEquals(FuncVarPtg.class, ptgs[1].getClass());

+ 26
- 0
src/testcases/org/apache/poi/hssf/record/TestNameRecord.java View File

@@ -17,8 +17,11 @@

package org.apache.poi.hssf.record;

import org.apache.poi.hssf.usermodel.HSSFName;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.util.HexRead;

import junit.framework.AssertionFailedError;
import junit.framework.TestCase;

/**
@@ -55,4 +58,27 @@ public final class TestNameRecord extends TestCase {
byte[] data2 = nr.serialize();
TestcaseRecordInputStream.confirmRecordEncoding(NameRecord.sid, data, data2);
}
public void testFormulaRelAbs_bug46174() {
// perhaps this testcase belongs on TestHSSFName
HSSFWorkbook wb = new HSSFWorkbook();
HSSFName name = wb.createName();
wb.createSheet("Sheet1");
name.setNameName("test");
name.setReference("Sheet1!$B$3");
if (name.getReference().equals("Sheet1!B3")) {
throw new AssertionFailedError("Identified bug 46174");
}
assertEquals("Sheet1!$B$3", name.getReference());
}
public void testFormulaGeneral() {
// perhaps this testcase belongs on TestHSSFName
HSSFWorkbook wb = new HSSFWorkbook();
HSSFName name = wb.createName();
wb.createSheet("Sheet1");
name.setNameName("test");
name.setFormula("Sheet1!A1+Sheet1!A2");
assertEquals("Sheet1!A1+Sheet1!A2", name.getFormula());
name.setFormula("5*6");
assertEquals("5*6", name.getFormula());
}
}

+ 3
- 2
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java View File

@@ -26,6 +26,7 @@ import junit.framework.AssertionFailedError;
import junit.framework.TestCase;

import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.Record;
@@ -533,7 +534,7 @@ public final class TestHSSFWorkbook extends TestCase {
assertEquals(3, wb.getWorkbook().getNumNames());
nr = wb.getWorkbook().getNameRecord(2);
// TODO - render full row and full column refs properly
assertEquals("Sheet2!$A$1:$IV$1", nr.getAreaReference(wb)); // 1:1
assertEquals("Sheet2!$A$1:$IV$1", HSSFFormulaParser.toFormulaString(wb, nr.getNameDefinition())); // 1:1
try {
wb.setRepeatingRowsAndColumns(3, 4, 5, 8, 11);
@@ -547,6 +548,6 @@ public final class TestHSSFWorkbook extends TestCase {
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
assertEquals(3, wb.getWorkbook().getNumNames());
nr = wb.getWorkbook().getNameRecord(2);
assertEquals("Sheet2!E:F,Sheet2!$A$9:$IV$12", nr.getAreaReference(wb)); // E:F,9:12
assertEquals("Sheet2!E:F,Sheet2!$A$9:$IV$12", HSSFFormulaParser.toFormulaString(wb, nr.getNameDefinition())); // E:F,9:12
}
}

+ 72
- 80
src/testcases/org/apache/poi/hssf/usermodel/TestNamedRange.java View File

@@ -28,11 +28,11 @@ import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;

/**
*
*
* @author ROMANL
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Danny Mui (danny at muibros.com)
* @author Amol S. Deshmukh &lt; amol at ap ache dot org &gt;
* @author Amol S. Deshmukh &lt; amol at ap ache dot org &gt;
*/
public final class TestNamedRange extends TestCase {

@@ -59,8 +59,6 @@ public final class TestNamedRange extends TestCase {
HSSFName namedRange1 = wb.getNameAt(0);
//Getting it sheet name
sheetName = namedRange1.getSheetName();
//Getting its reference
String referece = namedRange1.getReference();

// sanity check
SanityChecker c = new SanityChecker();
@@ -71,12 +69,12 @@ public final class TestNamedRange extends TestCase {
assertTrue("Name is "+nm.getNameName(),"RangeTest".equals(nm.getNameName()));
assertEquals(wb.getSheetName(0)+"!$D$4:$E$8", nm.getReference());
}
/**
* Reads an excel file already containing a named range.
* <p>
* Addresses Bug <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=9632" target="_bug">#9632</a>
*/
*/
public void testNamedRead() {
HSSFWorkbook wb = openSample("namedinput.xls");

@@ -89,7 +87,7 @@ public final class TestNamedRange extends TestCase {

//Getting its reference
String reference = namedRange1.getReference();
assertEquals(sheetName+"!$A$1:$D$10", reference);

HSSFName namedRange2 = wb.getNameAt(1);
@@ -112,10 +110,10 @@ public final class TestNamedRange extends TestCase {
assertEquals(sheetName+"!$A$1:$D$10", name.getReference());

name = wb.getNameAt(1);
String newReference = sheetName +"!$A$1:$C$36";
String newReference = sheetName +"!$A$1:$C$36";
name.setReference(newReference);
assertEquals(newReference, name.getReference());
assertEquals(newReference, name.getReference());
}

/**
@@ -123,13 +121,13 @@ public final class TestNamedRange extends TestCase {
*/
public void testMultipleNamedWrite() {
HSSFWorkbook wb = new HSSFWorkbook();

wb.createSheet("testSheet1");
String sheetName = wb.getSheetName(0);

assertEquals("testSheet1", sheetName);
//Creating new Named Range
HSSFName newNamedRange = wb.createName();

@@ -142,15 +140,13 @@ public final class TestNamedRange extends TestCase {
newNamedRange2.setNameName("AnotherTest");
newNamedRange2.setReference(sheetName + "!$F$1:$G$6");


HSSFName namedRange1 = wb.getNameAt(0);
String referece = namedRange1.getReference();
wb.getNameAt(0);

wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
HSSFName nm =wb.getNameAt(wb.getNameIndex("RangeTest"));
assertTrue("Name is "+nm.getNameName(),"RangeTest".equals(nm.getNameName()));
assertTrue("Reference is "+nm.getReference(),(wb.getSheetName(0)+"!$D$4:$E$8").equals(nm.getReference()));
nm = wb.getNameAt(wb.getNameIndex("AnotherTest"));
assertTrue("Name is "+nm.getNameName(),"AnotherTest".equals(nm.getNameName()));
assertTrue("Reference is "+nm.getReference(),newNamedRange2.getReference().equals(nm.getReference()));
@@ -192,7 +188,7 @@ public final class TestNamedRange extends TestCase {

// Set the reference for the named range for worksheet 'sheet2'
namedRange2.setReference("sheet2" + "!$A$1:$O$21");
// Write the workbook to a file
// Read the Excel file and verify its content
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
@@ -203,7 +199,7 @@ public final class TestNamedRange extends TestCase {
HSSFName nm2 =wb.getNameAt(wb.getNameIndex("RangeTest2"));
assertTrue("Name is "+nm2.getNameName(),"RangeTest2".equals(nm2.getNameName()));
assertTrue("Reference is "+nm2.getReference(),(wb.getSheetName(1)+"!$A$1:$O$21").equals(nm2.getReference()));
}
}

public void testUnicodeNamedRange() {
HSSFWorkbook workBook = new HSSFWorkbook();
@@ -223,15 +219,14 @@ public final class TestNamedRange extends TestCase {
/**
* Test to see if the print areas can be retrieved/created in memory
*/
public void testSinglePrintArea()
{
public void testSinglePrintArea() {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Test Print Area");
workbook.createSheet("Test Print Area");
String sheetName = workbook.getSheetName(0);
String reference = sheetName+"!$A$1:$B$1";
String reference = "$A$1:$B$1";
workbook.setPrintArea(0, reference);
String retrievedPrintArea = workbook.getPrintArea(0);

assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);
@@ -239,17 +234,17 @@ public final class TestNamedRange extends TestCase {
}

/**
* For Convenience, dont force sheet names to be used
* For Convenience, don't force sheet names to be used
*/
public void testSinglePrintAreaWOSheet()
{
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Test Print Area");
workbook.createSheet("Test Print Area");
String sheetName = workbook.getSheetName(0);
String reference = "$A$1:$B$1";
workbook.setPrintArea(0, reference);
String retrievedPrintArea = workbook.getPrintArea(0);

assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);
@@ -275,14 +270,14 @@ public final class TestNamedRange extends TestCase {
HSSFWorkbook workbook = new HSSFWorkbook();
workbook.createSheet("Test Print Area");
String sheetName = workbook.getSheetName(0);
String reference = sheetName+"!$A$1:$B$1";
String reference = "$A$1:$B$1";
workbook.setPrintArea(0, reference);
workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook);
String retrievedPrintArea = workbook.getPrintArea(0);
String retrievedPrintArea = workbook.getPrintArea(0);
assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);
assertEquals("References Match", "'" + sheetName + "'!$A$1:$B$1", retrievedPrintArea);
}
@@ -296,43 +291,43 @@ public final class TestNamedRange extends TestCase {
workbook.createSheet("Sheet1");
workbook.createSheet("Sheet2");
workbook.createSheet("Sheet3");
String reference1 = "Sheet1!$A$1:$B$1";
String reference2 = "Sheet2!$B$2:$D$5";
String reference3 = "Sheet3!$D$2:$F$5";
workbook.setPrintArea(0, reference1);
String reference1 = "$A$1:$B$1";
String reference2 = "$B$2:$D$5";
String reference3 = "$D$2:$F$5";
workbook.setPrintArea(0, reference1);
workbook.setPrintArea(1, reference2);
workbook.setPrintArea(2, reference3);

//Check created print areas
String retrievedPrintArea;
retrievedPrintArea = workbook.getPrintArea(0);
assertNotNull("Print Area Not Found (Sheet 1)", retrievedPrintArea);
assertEquals(reference1, retrievedPrintArea);
assertEquals("Sheet1!" + reference1, retrievedPrintArea);

retrievedPrintArea = workbook.getPrintArea(1);
assertNotNull("Print Area Not Found (Sheet 2)", retrievedPrintArea);
assertEquals(reference2, retrievedPrintArea);
assertEquals("Sheet2!" + reference2, retrievedPrintArea);

retrievedPrintArea = workbook.getPrintArea(2);
assertNotNull("Print Area Not Found (Sheet 3)", retrievedPrintArea);
assertEquals(reference3, retrievedPrintArea);
assertEquals("Sheet3!" + reference3, retrievedPrintArea);

// Check print areas after re-reading workbook
workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook);

retrievedPrintArea = workbook.getPrintArea(0);
assertNotNull("Print Area Not Found (Sheet 1)", retrievedPrintArea);
assertEquals(reference1, retrievedPrintArea);
assertEquals("Sheet1!" + reference1, retrievedPrintArea);

retrievedPrintArea = workbook.getPrintArea(1);
assertNotNull("Print Area Not Found (Sheet 2)", retrievedPrintArea);
assertEquals(reference2, retrievedPrintArea);
assertEquals("Sheet2!" + reference2, retrievedPrintArea);

retrievedPrintArea = workbook.getPrintArea(2);
assertNotNull("Print Area Not Found (Sheet 3)", retrievedPrintArea);
assertEquals(reference3, retrievedPrintArea);
assertEquals("Sheet3!" + reference3, retrievedPrintArea);
}

/**
@@ -341,12 +336,11 @@ public final class TestNamedRange extends TestCase {
*/
public void testPrintAreaCoords(){
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Test Print Area");
workbook.createSheet("Test Print Area");
String sheetName = workbook.getSheetName(0);
String reference = sheetName+"!$A$1:$B$1";

workbook.setPrintArea(0, 0, 1, 0, 0);
String retrievedPrintArea = workbook.getPrintArea(0);

assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);
@@ -360,18 +354,17 @@ public final class TestNamedRange extends TestCase {
*/
public void testPrintAreaUnion(){
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Test Print Area");
workbook.createSheet("Test Print Area");
String sheetName = workbook.getSheetName(0);

String reference = sheetName + "!$A$1:$B$1, " + sheetName + "!$D$1:$F$2";
String expResult = "'" + sheetName + "'!$A$1:$B$1,'" + sheetName + "'!$D$1:$F$2";
workbook.setPrintArea(0, reference);
String retrievedPrintArea = workbook.getPrintArea(0);

assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);
assertEquals(expResult, retrievedPrintArea);
if (false) { // TODO - fix formula parser to support unions
String reference = "'" + sheetName + "'!$A$1:$B$1,'" + sheetName + "'!$D$1:$F$2";
workbook.setPrintArea(0, reference);
String retrievedPrintArea = workbook.getPrintArea(0);
assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);
assertEquals(reference, retrievedPrintArea);
}
}

/**
@@ -380,18 +373,17 @@ public final class TestNamedRange extends TestCase {
*/
public void testPrintAreaRemove() {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Test Print Area");
String sheetName = workbook.getSheetName(0);
String reference = sheetName+"!$A$1:$B$1";
workbook.createSheet("Test Print Area");
workbook.getSheetName(0);

workbook.setPrintArea(0, 0, 1, 0, 0);
String retrievedPrintArea = workbook.getPrintArea(0);

assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);

workbook.removePrintArea(0);
assertNull("PrintArea was not removed", workbook.getPrintArea(0));
assertNull("PrintArea was not removed", workbook.getPrintArea(0));
}

/**
@@ -406,11 +398,11 @@ public final class TestNamedRange extends TestCase {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(sheetName);
sheet.createRow(0).createCell(0).setCellValue(new HSSFRichTextString(cellValue));
// create named range for a single cell using areareference
HSSFName namedCell = wb.createName();
namedCell.setNameName(cellName);
String reference = sheetName+"!A1:A1";
String reference = "'" + sheetName + "'" + "!A1:A1";
namedCell.setReference(reference);

// retrieve the newly created named range
@@ -442,7 +434,7 @@ public final class TestNamedRange extends TestCase {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(sname);
sheet.createRow(0).createCell(0).setCellValue(new HSSFRichTextString(cvalue));
// create named range for a single cell using cellreference
HSSFName namedCell = wb.createName();
namedCell.setNameName(cname);
@@ -471,7 +463,7 @@ public final class TestNamedRange extends TestCase {
HSSFName name1 = wb.getNameAt(0);
assertEquals("a", name1.getNameName());
assertEquals("Sheet1!$A$1", name1.getReference());
AreaReference ref1 = new AreaReference(name1.getReference());
new AreaReference(name1.getReference());
assertTrue("Successfully constructed first reference", true);

HSSFName name2 = wb.getNameAt(1);
@@ -479,19 +471,19 @@ public final class TestNamedRange extends TestCase {
assertEquals("Sheet1!#REF!", name2.getReference());
assertTrue(name2.isDeleted());
try {
AreaReference ref2 = new AreaReference(name2.getReference());
new AreaReference(name2.getReference());
fail("attempt to supply an invalid reference to AreaReference constructor results in exception");
} catch (StringIndexOutOfBoundsException e) { // TODO - use a different exception for this condition
// expected during successful test
}
}
}
public void testRepeatingRowsAndColumsNames() {
// First test that setting RR&C for same sheet more than once only creates a
// First test that setting RR&C for same sheet more than once only creates a
// single Print_Titles built-in record
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("FirstSheet");
// set repeating rows and columns twice for the first sheet
for (int i = 0; i < 2; i++) {
wb.setRepeatingRowsAndColumns(0, 0, 0, 0, 3-1);
@@ -499,7 +491,7 @@ public final class TestNamedRange extends TestCase {
}
assertEquals(1, wb.getNumberOfNames());
HSSFName nr1 = wb.getNameAt(0);
assertEquals("Print_Titles", nr1.getNameName());
if (false) {
// TODO - full column references not rendering properly, absolute markers not present either
@@ -507,16 +499,16 @@ public final class TestNamedRange extends TestCase {
} else {
assertEquals("FirstSheet!A:A,FirstSheet!$A$1:$IV$3", nr1.getReference());
}
// Save and re-open
HSSFWorkbook nwb = HSSFTestDataSamples.writeOutAndReadBack(wb);

assertEquals(1, nwb.getNumberOfNames());
nr1 = nwb.getNameAt(0);
assertEquals("Print_Titles", nr1.getNameName());
assertEquals("FirstSheet!A:A,FirstSheet!$A$1:$IV$3", nr1.getReference());
// check that setting RR&C on a second sheet causes a new Print_Titles built-in
// name to be created
sheet = nwb.createSheet("SecondSheet");
@@ -524,10 +516,10 @@ public final class TestNamedRange extends TestCase {

assertEquals(2, nwb.getNumberOfNames());
HSSFName nr2 = nwb.getNameAt(1);
assertEquals("Print_Titles", nr2.getNameName());
assertEquals("SecondSheet!B:C,SecondSheet!$A$1:$IV$1", nr2.getReference());
if (false) {
// In case you fancy checking in excel, to ensure it
// won't complain about the file now

+ 0
- 1
src/testcases/org/apache/poi/hssf/util/AllHSSFUtilTests.java View File

@@ -32,7 +32,6 @@ public class AllHSSFUtilTests {
result.addTestSuite(TestAreaReference.class);
result.addTestSuite(TestCellReference.class);
result.addTestSuite(TestHSSFColor.class);
result.addTestSuite(TestRangeAddress.class);
result.addTestSuite(TestRKUtil.class);
return result;
}

+ 3
- 1
src/testcases/org/apache/poi/hssf/util/TestAreaReference.java View File

@@ -23,6 +23,7 @@ import java.io.InputStream;
import junit.framework.TestCase;

import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.formula.Area3DPtg;
@@ -107,6 +108,7 @@ public final class TestAreaReference extends TestCase {
TestCellReference.confirmCell(allCells[2], "Tabelle1", 6, 1, true, true, "Tabelle1!$B$7");
}

// TODO - remove this sub-class
private static final class HSSFWB extends HSSFWorkbook {
public HSSFWB(InputStream in) throws IOException {
super(in);
@@ -220,7 +222,7 @@ public final class TestAreaReference extends TestCase {
assertEquals(refB, ptgC.toFormulaString(eb));
assertEquals(",", ptgD.toFormulaString());

assertEquals(ref, nr.getAreaReference(wb));
assertEquals(ref, HSSFFormulaParser.toFormulaString(wb, nr.getNameDefinition()));

// Check the high level definition
int idx = wb.getNameIndex("test");

+ 0
- 46
src/testcases/org/apache/poi/hssf/util/TestRangeAddress.java View File

@@ -1,46 +0,0 @@

/* ====================================================================
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.util;

import junit.framework.TestCase;

/**
* Tests the Range Address Utility Functionality
* @author Danny Mui (danny at muibros.com)
*/
public class TestRangeAddress extends TestCase {
public TestRangeAddress(String s) {
super(s);
}
public static void main(java.lang.String[] args) {
junit.textui.TestRunner.run(TestRangeAddress.class);
}
public void testReferenceParse() {
String reference = "Sheet2!$A$1:$C$3";
RangeAddress ra = new RangeAddress(reference);
assertEquals("Sheet2!A1:C3", ra.getAddress());
}
}

Loading…
Cancel
Save