Initial support for XSSF External Links tables, which hold references to other workbooks referenced by formulas and names. #56744
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1611828 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d0db408a2f
commit
611bcffb0c
165
src/ooxml/java/org/apache/poi/xssf/model/ExternalLinksTable.java
Normal file
165
src/ooxml/java/org/apache/poi/xssf/model/ExternalLinksTable.java
Normal file
@ -0,0 +1,165 @@
|
||||
/* ====================================================================
|
||||
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.xssf.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.ss.usermodel.Name;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalDefinedName;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalLink;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalSheetName;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.ExternalLinkDocument;
|
||||
|
||||
/**
|
||||
* Holds details of links to parts of other workbooks (eg named ranges),
|
||||
* along with the most recently seen values for what they point to.
|
||||
*/
|
||||
public class ExternalLinksTable extends POIXMLDocumentPart {
|
||||
private CTExternalLink link;
|
||||
|
||||
public ExternalLinksTable() {
|
||||
super();
|
||||
link = CTExternalLink.Factory.newInstance();
|
||||
}
|
||||
|
||||
public ExternalLinksTable(PackagePart part, PackageRelationship rel) throws IOException {
|
||||
super(part, rel);
|
||||
readFrom(part.getInputStream());
|
||||
}
|
||||
|
||||
public void readFrom(InputStream is) throws IOException {
|
||||
try {
|
||||
ExternalLinkDocument doc = ExternalLinkDocument.Factory.parse(is);
|
||||
link = doc.getExternalLink();
|
||||
} catch (XmlException e) {
|
||||
throw new IOException(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
ExternalLinkDocument doc = ExternalLinkDocument.Factory.newInstance();
|
||||
doc.setExternalLink(link);
|
||||
doc.save(out, DEFAULT_XML_OPTIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void commit() throws IOException {
|
||||
PackagePart part = getPackagePart();
|
||||
OutputStream out = part.getOutputStream();
|
||||
writeTo(out);
|
||||
out.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying xmlbeans object for the external
|
||||
* link table
|
||||
*/
|
||||
public CTExternalLink getCTExternalLink(){
|
||||
return link;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<String> getSheetNames() {
|
||||
CTExternalSheetName[] sheetNames =
|
||||
link.getExternalBook().getSheetNames().getSheetNameArray();
|
||||
List<String> names = new ArrayList<String>(sheetNames.length);
|
||||
for (CTExternalSheetName name : sheetNames) {
|
||||
names.add(name.getVal());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<Name> getDefinedNames() {
|
||||
CTExternalDefinedName[] extNames =
|
||||
link.getExternalBook().getDefinedNames().getDefinedNameArray();
|
||||
List<Name> names = new ArrayList<Name>(extNames.length);
|
||||
for (CTExternalDefinedName extName : extNames) {
|
||||
names.add(new ExternalName(extName));
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
// TODO Last seen data
|
||||
|
||||
|
||||
protected class ExternalName implements Name {
|
||||
private CTExternalDefinedName name;
|
||||
protected ExternalName(CTExternalDefinedName name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getNameName() {
|
||||
return name.getName();
|
||||
}
|
||||
public void setNameName(String name) {
|
||||
this.name.setName(name);
|
||||
}
|
||||
|
||||
public String getSheetName() {
|
||||
int sheetId = getSheetIndex();
|
||||
if (sheetId >= 0) {
|
||||
return getSheetNames().get(sheetId);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public int getSheetIndex() {
|
||||
if (name.isSetSheetId()) {
|
||||
return (int)name.getSheetId();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public void setSheetIndex(int sheetId) {
|
||||
name.setSheetId(sheetId);
|
||||
}
|
||||
|
||||
public String getRefersToFormula() {
|
||||
// Return, without the leading =
|
||||
return name.getRefersTo().substring(1);
|
||||
}
|
||||
public void setRefersToFormula(String formulaText) {
|
||||
// Save with leading =
|
||||
name.setRefersTo('=' + formulaText);
|
||||
}
|
||||
|
||||
public boolean isFunctionName() {
|
||||
return false;
|
||||
}
|
||||
public boolean isDeleted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return null;
|
||||
}
|
||||
public void setComment(String comment) {
|
||||
throw new IllegalStateException("Not Supported");
|
||||
}
|
||||
public void setFunction(boolean value) {
|
||||
throw new IllegalStateException("Not Supported");
|
||||
}
|
||||
}
|
||||
}
|
@ -36,6 +36,7 @@ import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.xssf.model.CalculationChain;
|
||||
import org.apache.poi.xssf.model.CommentsTable;
|
||||
import org.apache.poi.xssf.model.ExternalLinksTable;
|
||||
import org.apache.poi.xssf.model.MapInfo;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.model.SingleXmlCells;
|
||||
@ -305,6 +306,13 @@ public final class XSSFRelation extends POIXMLRelation {
|
||||
CalculationChain.class
|
||||
);
|
||||
|
||||
public static final XSSFRelation EXTERNAL_LINKS = new XSSFRelation(
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink",
|
||||
"/xl/externalLinks/externalLink#.xmll",
|
||||
ExternalLinksTable.class
|
||||
);
|
||||
|
||||
public static final XSSFRelation PRINTER_SETTINGS = new XSSFRelation(
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings",
|
||||
|
@ -63,6 +63,7 @@ import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.PackageHelper;
|
||||
import org.apache.poi.xssf.model.CalculationChain;
|
||||
import org.apache.poi.xssf.model.ExternalLinksTable;
|
||||
import org.apache.poi.xssf.model.MapInfo;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.model.StylesTable;
|
||||
@ -155,6 +156,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||
*/
|
||||
private CalculationChain calcChain;
|
||||
|
||||
/**
|
||||
* External Links, for referencing names or cells in other workbooks
|
||||
*/
|
||||
private ExternalLinksTable externalLinks;
|
||||
|
||||
/**
|
||||
* A collection of custom XML mappings
|
||||
*/
|
||||
@ -283,6 +289,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||
else if(p instanceof StylesTable) stylesSource = (StylesTable)p;
|
||||
else if(p instanceof ThemesTable) theme = (ThemesTable)p;
|
||||
else if(p instanceof CalculationChain) calcChain = (CalculationChain)p;
|
||||
else if(p instanceof ExternalLinksTable) externalLinks = (ExternalLinksTable)p;
|
||||
else if(p instanceof MapInfo) mapInfo = (MapInfo)p;
|
||||
else if (p instanceof XSSFSheet) {
|
||||
shIdMap.put(p.getPackageRelationship().getId(), (XSSFSheet)p);
|
||||
@ -1591,7 +1598,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CalculationChain object for this workbook
|
||||
* Return the {@link CalculationChain} object for this workbook
|
||||
* <p>
|
||||
* The calculation chain object specifies the order in which the cells in a workbook were last calculated
|
||||
* </p>
|
||||
@ -1599,10 +1606,24 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||
* @return the <code>CalculationChain</code> object or <code>null</code> if not defined
|
||||
*/
|
||||
@Internal
|
||||
public CalculationChain getCalculationChain(){
|
||||
public CalculationChain getCalculationChain() {
|
||||
return calcChain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ExternalLinksTable} object for this workbook.
|
||||
*
|
||||
* <p>The external links table specifies details of named ranges etc
|
||||
* that are referenced from other workbooks, along with the last seen
|
||||
* values of what they point to.</p>
|
||||
*
|
||||
* @return the <code>ExternalLinksTable</code> object or <code>null</code> if not defined
|
||||
*/
|
||||
@Internal
|
||||
public ExternalLinksTable getExternalLinksTable() {
|
||||
return externalLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return a collection of custom XML mappings defined in this workbook
|
||||
|
@ -0,0 +1,84 @@
|
||||
/* ====================================================================
|
||||
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.xssf.model;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Name;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.junit.Test;
|
||||
|
||||
public final class TestExternalLinksTable {
|
||||
@Test
|
||||
public void none() {
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("SampleSS.xlsx");
|
||||
assertEquals(null, wb.getExternalLinksTable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicRead() {
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("ref-56737.xlsx");
|
||||
assertNotNull(wb.getExternalLinksTable());
|
||||
Name name = null;
|
||||
|
||||
ExternalLinksTable links = wb.getExternalLinksTable();
|
||||
assertEquals(3, links.getSheetNames().size());
|
||||
assertEquals(2, links.getDefinedNames().size());
|
||||
|
||||
assertEquals("Uses", links.getSheetNames().get(0));
|
||||
assertEquals("Defines", links.getSheetNames().get(1));
|
||||
assertEquals("56737", links.getSheetNames().get(2));
|
||||
|
||||
name = links.getDefinedNames().get(0);
|
||||
assertEquals("NR_Global_B2", name.getNameName());
|
||||
assertEquals(-1, name.getSheetIndex());
|
||||
assertEquals(null, name.getSheetName());
|
||||
assertEquals("'Defines'!$B$2", name.getRefersToFormula());
|
||||
|
||||
name = links.getDefinedNames().get(1);
|
||||
assertEquals("NR_To_A1", name.getNameName());
|
||||
assertEquals(1, name.getSheetIndex());
|
||||
assertEquals("Defines", name.getSheetName());
|
||||
assertEquals("'Defines'!$A$1", name.getRefersToFormula());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicReadWriteRead() {
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("ref-56737.xlsx");
|
||||
Name name = wb.getExternalLinksTable().getDefinedNames().get(1);
|
||||
name.setNameName("Testing");
|
||||
name.setRefersToFormula("$A$1");
|
||||
|
||||
wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
ExternalLinksTable links = wb.getExternalLinksTable();
|
||||
|
||||
name = links.getDefinedNames().get(0);
|
||||
assertEquals("NR_Global_B2", name.getNameName());
|
||||
assertEquals(-1, name.getSheetIndex());
|
||||
assertEquals(null, name.getSheetName());
|
||||
assertEquals("'Defines'!$B$2", name.getRefersToFormula());
|
||||
|
||||
name = links.getDefinedNames().get(1);
|
||||
assertEquals("Testing", name.getNameName());
|
||||
assertEquals(1, name.getSheetIndex());
|
||||
assertEquals("Defines", name.getSheetName());
|
||||
assertEquals("$A$1", name.getRefersToFormula());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user