mirror of https://github.com/apache/poi.git
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
5449fca03a
commit
2643dfdef4
|
@ -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.util.POILogger;
|
||||||
import org.apache.poi.xssf.model.CalculationChain;
|
import org.apache.poi.xssf.model.CalculationChain;
|
||||||
import org.apache.poi.xssf.model.CommentsTable;
|
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.MapInfo;
|
||||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||||
import org.apache.poi.xssf.model.SingleXmlCells;
|
import org.apache.poi.xssf.model.SingleXmlCells;
|
||||||
|
@ -305,6 +306,13 @@ public final class XSSFRelation extends POIXMLRelation {
|
||||||
CalculationChain.class
|
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(
|
public static final XSSFRelation PRINTER_SETTINGS = new XSSFRelation(
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings",
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/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.POILogger;
|
||||||
import org.apache.poi.util.PackageHelper;
|
import org.apache.poi.util.PackageHelper;
|
||||||
import org.apache.poi.xssf.model.CalculationChain;
|
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.MapInfo;
|
||||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||||
import org.apache.poi.xssf.model.StylesTable;
|
import org.apache.poi.xssf.model.StylesTable;
|
||||||
|
@ -154,6 +155,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
private CalculationChain calcChain;
|
private CalculationChain calcChain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* External Links, for referencing names or cells in other workbooks
|
||||||
|
*/
|
||||||
|
private ExternalLinksTable externalLinks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of custom XML mappings
|
* 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 StylesTable) stylesSource = (StylesTable)p;
|
||||||
else if(p instanceof ThemesTable) theme = (ThemesTable)p;
|
else if(p instanceof ThemesTable) theme = (ThemesTable)p;
|
||||||
else if(p instanceof CalculationChain) calcChain = (CalculationChain)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 MapInfo) mapInfo = (MapInfo)p;
|
||||||
else if (p instanceof XSSFSheet) {
|
else if (p instanceof XSSFSheet) {
|
||||||
shIdMap.put(p.getPackageRelationship().getId(), (XSSFSheet)p);
|
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>
|
* <p>
|
||||||
* The calculation chain object specifies the order in which the cells in a workbook were last calculated
|
* The calculation chain object specifies the order in which the cells in a workbook were last calculated
|
||||||
* </p>
|
* </p>
|
||||||
|
@ -1599,9 +1606,23 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
||||||
* @return the <code>CalculationChain</code> object or <code>null</code> if not defined
|
* @return the <code>CalculationChain</code> object or <code>null</code> if not defined
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
public CalculationChain getCalculationChain(){
|
public CalculationChain getCalculationChain() {
|
||||||
return calcChain;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -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