diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java index 580d48d025..3c3b91b148 100644 --- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java +++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java @@ -94,6 +94,7 @@ import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.ptg.Ref3DPtg; import org.apache.poi.ss.formula.udf.UDFFinder; import org.apache.poi.ss.usermodel.BuiltinFormats; +import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.util.Internal; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -1803,6 +1804,10 @@ public final class InternalWorkbook { } return linkTable; } + + public int linkExternalWorkbook(String name, Workbook externalWorkbook) { + return getOrCreateLinkTable().linkExternalWorkbook(name, externalWorkbook); + } /** * Finds the first sheet name by his extern sheet index diff --git a/src/java/org/apache/poi/hssf/model/LinkTable.java b/src/java/org/apache/poi/hssf/model/LinkTable.java index 7277da2e6c..cc228b3dfd 100644 --- a/src/java/org/apache/poi/hssf/model/LinkTable.java +++ b/src/java/org/apache/poi/hssf/model/LinkTable.java @@ -37,6 +37,7 @@ import org.apache.poi.ss.formula.ptg.ErrPtg; import org.apache.poi.ss.formula.ptg.NameXPtg; import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.ptg.Ref3DPtg; +import org.apache.poi.ss.usermodel.Workbook; /** * Link Table (OOO pdf reference: 4.10.3 )
@@ -110,31 +111,39 @@ final class LinkTable { _crnBlocks = new CRNBlock[temp.size()]; temp.toArray(_crnBlocks); } + + /** + * Create a new block for external references. + */ + public ExternalBookBlock(String url, String[] sheetNames) { + _externalBookRecord = SupBookRecord.createExternalReferences(url, sheetNames); + _crnBlocks = new CRNBlock[0]; + } - /** - * Create a new block for internal references. It is called when constructing a new LinkTable. - * - * @see org.apache.poi.hssf.model.LinkTable#LinkTable(int, WorkbookRecordList) - */ - public ExternalBookBlock(int numberOfSheets) { - _externalBookRecord = SupBookRecord.createInternalReferences((short)numberOfSheets); - _externalNameRecords = new ExternalNameRecord[0]; - _crnBlocks = new CRNBlock[0]; - } + /** + * Create a new block for internal references. It is called when constructing a new LinkTable. + * + * @see org.apache.poi.hssf.model.LinkTable#LinkTable(int, WorkbookRecordList) + */ + public ExternalBookBlock(int numberOfSheets) { + _externalBookRecord = SupBookRecord.createInternalReferences((short)numberOfSheets); + _externalNameRecords = new ExternalNameRecord[0]; + _crnBlocks = new CRNBlock[0]; + } - /** - * Create a new block for registering add-in functions - * - * @see org.apache.poi.hssf.model.LinkTable#addNameXPtg(String) - */ - public ExternalBookBlock() { - _externalBookRecord = SupBookRecord.createAddInFunctions(); - _externalNameRecords = new ExternalNameRecord[0]; - _crnBlocks = new CRNBlock[0]; - } + /** + * Create a new block for registering add-in functions + * + * @see org.apache.poi.hssf.model.LinkTable#addNameXPtg(String) + */ + public ExternalBookBlock() { + _externalBookRecord = SupBookRecord.createAddInFunctions(); + _externalNameRecords = new ExternalNameRecord[0]; + _crnBlocks = new CRNBlock[0]; + } public SupBookRecord getExternalBookRecord() { - return _externalBookRecord; + return _externalBookRecord; } public String getNameText(int definedNameIndex) { @@ -382,31 +391,68 @@ final class LinkTable { }; } } + + private int getExternalWorkbookIndex(String workbookName) { + for (int i=0; i<_externalBookBlocks.length; i++) { + SupBookRecord ebr = _externalBookBlocks[i].getExternalBookRecord(); + if (!ebr.isExternalReferences()) { + continue; + } + if (workbookName.equals(ebr.getURL())) { // not sure if 'equals()' works when url has a directory + return i; + } + } + return -1; + } + + public int linkExternalWorkbook(String name, Workbook externalWorkbook) { + int extBookIndex = getExternalWorkbookIndex(name); + if (extBookIndex != -1) { + // Already linked! + return extBookIndex; + } + + // Create a new SupBookRecord + String[] sheetNames = new String[externalWorkbook.getNumberOfSheets()]; + for (int sn=0; snThis linking only applies for writing formulas. To link things + * for evaluation, see {@link FormulaEvaluator#setupReferencedWorkbooks(java.util.Map)} + * + * @param name The name the workbook will be referenced as in formulas + * @param workbook The open workbook to fetch the link required information from + */ + int linkExternalWorkbook(String name, Workbook workbook); + /** * Sets the printarea for the sheet provided *
diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
index 112c1ff814..ce56b6a6d6 100644
--- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
+++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
@@ -1174,6 +1174,20 @@ public class SXSSFWorkbook implements Workbook
{
_wb.setSheetHidden(sheetIx,hidden);
}
+
+ /**
+ * Adds the LinkTable records required to allow formulas referencing
+ * the specified external workbook to be added to this one. Allows
+ * formulas such as "[MyOtherWorkbook]Sheet3!$A$5" to be added to the
+ * file, for workbooks not already referenced.
+ *
+ * @param name The name the workbook will be referenced as in formulas
+ * @param workbook The open workbook to fetch the link required information from
+ */
+ public int linkExternalWorkbook(String name, Workbook workbook) {
+ throw new RuntimeException("NotImplemented");
+ }
+
/**
* Register a new toolpack in this workbook.
*
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
index a51b40675f..7164534d3b 100644
--- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
+++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
@@ -1704,6 +1704,18 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable