Rename some of the internal HSSF sheet lookup methods which deal with external sheet indicies, to make it clear when they return the first sheet name/index, and add support for getting the last one too (will be the same as the first if not a range)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1613305 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-07-24 21:25:45 +00:00
parent 1fc5397a59
commit 7f6ba5513c
10 changed files with 113 additions and 34 deletions

View File

@ -85,6 +85,7 @@ import org.apache.poi.hssf.record.common.UnicodeString;
import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName; import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet; import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheetRange;
import org.apache.poi.ss.formula.FormulaShifter; import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.formula.ptg.Area3DPtg; import org.apache.poi.ss.formula.ptg.Area3DPtg;
import org.apache.poi.ss.formula.ptg.NameXPtg; import org.apache.poi.ss.formula.ptg.NameXPtg;
@ -1803,30 +1804,42 @@ public final class InternalWorkbook {
return linkTable; return linkTable;
} }
/** finds the sheet name by his extern sheet index /**
* Finds the first sheet name by his extern sheet index
* @param externSheetIndex extern sheet index * @param externSheetIndex extern sheet index
* @return sheet name. * @return first sheet name.
*/ */
public String findSheetNameFromExternSheet(int externSheetIndex){ public String findSheetFirstNameFromExternSheet(int externSheetIndex){
int indexToSheet = linkTable.getFirstInternalSheetIndexForExtIndex(externSheetIndex);
int indexToSheet = linkTable.getIndexToInternalSheet(externSheetIndex); return findSheetNameFromIndex(indexToSheet);
if (indexToSheet < 0) { }
public String findSheetLastNameFromExternSheet(int externSheetIndex){
int indexToSheet = linkTable.getLastInternalSheetIndexForExtIndex(externSheetIndex);
return findSheetNameFromIndex(indexToSheet);
}
private String findSheetNameFromIndex(int internalSheetIndex) {
if (internalSheetIndex < 0) {
// TODO - what does '-1' mean here? // TODO - what does '-1' mean here?
//error check, bail out gracefully! //error check, bail out gracefully!
return ""; return "";
} }
if (indexToSheet >= boundsheets.size()) { if (internalSheetIndex >= boundsheets.size()) {
// Not sure if this can ever happen (See bug 45798) // Not sure if this can ever happen (See bug 45798)
return ""; // Seems to be what excel would do in this case return ""; // Seems to be what excel would do in this case
} }
return getSheetName(indexToSheet); return getSheetName(internalSheetIndex);
} }
public ExternalSheet getExternalSheet(int externSheetIndex) { public ExternalSheet getExternalSheet(int externSheetIndex) {
String[] extNames = linkTable.getExternalBookAndSheetName(externSheetIndex); String[] extNames = linkTable.getExternalBookAndSheetName(externSheetIndex);
if (extNames == null) { if (extNames == null) {
return null; return null;
} }
return new ExternalSheet(extNames[0], extNames[1]); if (extNames.length == 2) {
return new ExternalSheet(extNames[0], extNames[1]);
} else {
return new ExternalSheetRange(extNames[0], extNames[1], extNames[2]);
}
} }
public ExternalName getExternalName(int externSheetIndex, int externNameIndex) { public ExternalName getExternalName(int externSheetIndex, int externNameIndex) {
String nameName = linkTable.resolveNameXText(externSheetIndex, externNameIndex, this); String nameName = linkTable.resolveNameXText(externSheetIndex, externNameIndex, this);

View File

@ -359,15 +359,28 @@ final class LinkTable {
return null; return null;
} }
// Sheet name only applies if not a global reference // Sheet name only applies if not a global reference
int shIx = _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex); int shIx1 = _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex);
String usSheetName = null; int shIx2 = _externSheetRecord.getLastSheetIndexFromRefIndex(extRefIndex);
if(shIx >= 0) { String firstSheetName = null;
usSheetName = ebr.getSheetNames()[shIx]; String lastSheetName = null;
if(shIx1 >= 0) {
firstSheetName = ebr.getSheetNames()[shIx1];
}
if (shIx2 >= 0) {
lastSheetName = ebr.getSheetNames()[shIx2];
}
if (shIx1 == shIx2) {
return new String[] {
ebr.getURL(),
firstSheetName
};
} else {
return new String[] {
ebr.getURL(),
firstSheetName,
lastSheetName
};
} }
return new String[] {
ebr.getURL(),
usSheetName,
};
} }
public int getExternalSheetIndex(String workbookName, String sheetName) { public int getExternalSheetIndex(String workbookName, String sheetName) {
@ -411,9 +424,16 @@ final class LinkTable {
* @param extRefIndex as from a {@link Ref3DPtg} or {@link Area3DPtg} * @param extRefIndex as from a {@link Ref3DPtg} or {@link Area3DPtg}
* @return -1 if the reference is to an external book * @return -1 if the reference is to an external book
*/ */
public int getIndexToInternalSheet(int extRefIndex) { public int getFirstInternalSheetIndexForExtIndex(int extRefIndex) {
return _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex); return _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex);
} }
/**
* @param extRefIndex as from a {@link Ref3DPtg} or {@link Area3DPtg}
* @return -1 if the reference is to an external book
*/
public int getLastInternalSheetIndexForExtIndex(int extRefIndex) {
return _externSheetRecord.getLastSheetIndexFromRefIndex(extRefIndex);
}
/** /**
* @deprecated Was prevously used for removing sheets, which we now do differently * @deprecated Was prevously used for removing sheets, which we now do differently

View File

@ -132,6 +132,10 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
// Not actually sheet based at all - is workbook scoped // Not actually sheet based at all - is workbook scoped
return null; return null;
} }
// Is it a single local sheet, or a range?
// TODO
// Look up the local sheet // Look up the local sheet
String sheetName = getSheetName(localSheetIndex); String sheetName = getSheetName(localSheetIndex);
sheet = new ExternalSheet(null, sheetName); sheet = new ExternalSheet(null, sheetName);
@ -154,8 +158,11 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex()); return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
} }
public String getSheetNameByExternSheet(int externSheetIndex) { public String getSheetFirstNameByExternSheet(int externSheetIndex) {
return _iBook.findSheetNameFromExternSheet(externSheetIndex); return _iBook.findSheetFirstNameFromExternSheet(externSheetIndex);
}
public String getSheetLastNameByExternSheet(int externSheetIndex) {
return _iBook.findSheetLastNameFromExternSheet(externSheetIndex);
} }
public String getNameText(NamePtg namePtg) { public String getNameText(NamePtg namePtg) {
return _iBook.getNameRecord(namePtg.getIndex()).getNameText(); return _iBook.getNameRecord(namePtg.getIndex()).getNameText();

View File

@ -21,8 +21,8 @@ import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.model.InternalWorkbook; import org.apache.poi.hssf.model.InternalWorkbook;
import org.apache.poi.hssf.record.NameCommentRecord; import org.apache.poi.hssf.record.NameCommentRecord;
import org.apache.poi.hssf.record.NameRecord; import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.FormulaType; import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.Name;
/** /**
@ -66,7 +66,7 @@ public final class HSSFName implements Name {
public String getSheetName() { public String getSheetName() {
int indexToExternSheet = _definedNameRec.getExternSheetNumber(); int indexToExternSheet = _definedNameRec.getExternSheetNumber();
return _book.getWorkbook().findSheetNameFromExternSheet(indexToExternSheet); return _book.getWorkbook().findSheetFirstNameFromExternSheet(indexToExternSheet);
} }
/** /**

View File

@ -675,7 +675,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
@Deprecated @Deprecated
public String findSheetNameFromExternSheet(int externSheetIndex){ public String findSheetNameFromExternSheet(int externSheetIndex){
// TODO - don't expose internal ugliness like externSheet indexes to the user model API // TODO - don't expose internal ugliness like externSheet indexes to the user model API
return workbook.findSheetNameFromExternSheet(externSheetIndex); return workbook.findSheetFirstNameFromExternSheet(externSheetIndex);
} }
/** /**
* @deprecated for POI internal use only (formula rendering). This method is likely to * @deprecated for POI internal use only (formula rendering). This method is likely to

View File

@ -89,6 +89,20 @@ public interface EvaluationWorkbook {
return _sheetName; return _sheetName;
} }
} }
class ExternalSheetRange extends ExternalSheet {
private final String _lastSheetName;
public ExternalSheetRange(String workbookName, String firstSheetName, String lastSheetName) {
super(workbookName, firstSheetName);
this._lastSheetName = lastSheetName;
}
public String getFirstSheetName() {
return getSheetName();
}
public String getLastSheetName() {
return _lastSheetName;
}
}
class ExternalName { class ExternalName {
private final String _nameName; private final String _nameName;
private final int _nameNumber; private final int _nameNumber;

View File

@ -17,9 +17,9 @@
package org.apache.poi.ss.formula; package org.apache.poi.ss.formula;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
import org.apache.poi.ss.formula.ptg.NamePtg; import org.apache.poi.ss.formula.ptg.NamePtg;
import org.apache.poi.ss.formula.ptg.NameXPtg; import org.apache.poi.ss.formula.ptg.NameXPtg;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
/** /**
* Abstracts a workbook for the purpose of converting formula to text.<br/> * Abstracts a workbook for the purpose of converting formula to text.<br/>
@ -29,12 +29,20 @@ import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
* @author Josh Micich * @author Josh Micich
*/ */
public interface FormulaRenderingWorkbook { public interface FormulaRenderingWorkbook {
/** /**
* @return <code>null</code> if externSheetIndex refers to a sheet inside the current workbook * @return <code>null</code> if externSheetIndex refers to a sheet inside the current workbook
*/ */
ExternalSheet getExternalSheet(int externSheetIndex); ExternalSheet getExternalSheet(int externSheetIndex);
String getSheetNameByExternSheet(int externSheetIndex);
/**
* @return the name of the (first) sheet referred to by the given external sheet index
*/
String getSheetFirstNameByExternSheet(int externSheetIndex);
/**
* @return the name of the (last) sheet referred to by the given external sheet index
*/
String getSheetLastNameByExternSheet(int externSheetIndex);
String resolveNameXText(NameXPtg nameXPtg); String resolveNameXText(NameXPtg nameXPtg);
String getNameText(NamePtg namePtg); String getNameText(NamePtg namePtg);
} }

View File

@ -18,6 +18,7 @@
package org.apache.poi.ss.formula.ptg; package org.apache.poi.ss.formula.ptg;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet; import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheetRange;
import org.apache.poi.ss.formula.FormulaRenderingWorkbook; import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
import org.apache.poi.ss.formula.SheetNameFormatter; import org.apache.poi.ss.formula.SheetNameFormatter;
@ -42,14 +43,26 @@ final class ExternSheetNameResolver {
sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4); sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4);
SheetNameFormatter.appendFormat(sb, sheetName); SheetNameFormatter.appendFormat(sb, sheetName);
} }
if (externalSheet instanceof ExternalSheetRange) {
ExternalSheetRange r = (ExternalSheetRange)externalSheet;
if (! r.getFirstSheetName().equals(r.getLastSheetName())) {
sb.append(':');
SheetNameFormatter.appendFormat(sb, r.getLastSheetName());
}
}
} else { } else {
String sheetName = book.getSheetNameByExternSheet(field_1_index_extern_sheet); String firstSheetName = book.getSheetFirstNameByExternSheet(field_1_index_extern_sheet);
sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4); String lastSheetName = book.getSheetLastNameByExternSheet(field_1_index_extern_sheet);
if (sheetName.length() < 1) { sb = new StringBuffer(firstSheetName.length() + cellRefText.length() + 4);
if (firstSheetName.length() < 1) {
// What excel does if sheet has been deleted // What excel does if sheet has been deleted
sb.append("#REF"); // note - '!' added just once below sb.append("#REF"); // note - '!' added just once below
} else { } else {
SheetNameFormatter.appendFormat(sb, sheetName); SheetNameFormatter.appendFormat(sb, firstSheetName);
if (! firstSheetName.equals(lastSheetName)) {
sb.append(':');
sb.append(lastSheetName);
}
} }
} }
sb.append('!'); sb.append('!');

View File

@ -256,10 +256,14 @@ public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
return _uBook.getSheetIndex(sheetName); return _uBook.getSheetIndex(sheetName);
} }
public String getSheetNameByExternSheet(int externSheetIndex) { public String getSheetFirstNameByExternSheet(int externSheetIndex) {
int sheetIndex = convertFromExternalSheetIndex(externSheetIndex); int sheetIndex = convertFromExternalSheetIndex(externSheetIndex);
return _uBook.getSheetName(sheetIndex); return _uBook.getSheetName(sheetIndex);
} }
public String getSheetLastNameByExternSheet(int externSheetIndex) {
// XSSF does multi-sheet references differently, so this is the same as the first
return getSheetFirstNameByExternSheet(externSheetIndex);
}
public String getNameText(NamePtg namePtg) { public String getNameText(NamePtg namePtg) {
return _uBook.getNameAt(namePtg.getIndex()).getNameName(); return _uBook.getNameAt(namePtg.getIndex()).getNameName();

View File

@ -78,9 +78,9 @@ public final class TestEventWorkbookBuilder extends TestCase {
assertEquals(3, listener.getStubWorkbook().getNumSheets()); assertEquals(3, listener.getStubWorkbook().getNumSheets());
InternalWorkbook ref = listener.getStubWorkbook(); InternalWorkbook ref = listener.getStubWorkbook();
assertEquals("Sh3", ref.findSheetNameFromExternSheet(0)); assertEquals("Sh3", ref.findSheetFirstNameFromExternSheet(0));
assertEquals("Sheet1", ref.findSheetNameFromExternSheet(1)); assertEquals("Sheet1", ref.findSheetFirstNameFromExternSheet(1));
assertEquals("S2", ref.findSheetNameFromExternSheet(2)); assertEquals("S2", ref.findSheetFirstNameFromExternSheet(2));
} }
public void testFormulas() { public void testFormulas() {