mirror of https://github.com/apache/poi.git
[bug-63189] support hyperlink relationships. Thanks to Ohyoung Kwon. This closes #617
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1917134 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d525d1a5b1
commit
eebb3717e0
|
@ -0,0 +1,44 @@
|
|||
/* ====================================================================
|
||||
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.ooxml;
|
||||
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Represents a hyperlink relationship.
|
||||
*
|
||||
* @since POI 5.2.6
|
||||
*/
|
||||
public class HyperlinkRelationship extends ReferenceRelationship {
|
||||
/**
|
||||
* Initializes a new instance of the HyperlinkRelationship.
|
||||
*
|
||||
* @param hyperlinkUri The target uri of the hyperlink relationship.
|
||||
* @param isExternal Is the URI external.
|
||||
* @param id The relationship ID.
|
||||
*/
|
||||
protected HyperlinkRelationship(POIXMLDocumentPart container, URI hyperlinkUri, boolean isExternal, String id) {
|
||||
super(container, hyperlinkUri, isExternal, PackageRelationshipTypes.HYPERLINK_PART, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRelationshipType() {
|
||||
return PackageRelationshipTypes.HYPERLINK_PART;
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import java.util.Collections;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
@ -38,7 +39,6 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
|||
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
|
||||
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
||||
import org.apache.poi.openxml4j.opc.TargetMode;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFChart;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRelation;
|
||||
|
@ -59,6 +59,7 @@ public class POIXMLDocumentPart {
|
|||
private PackagePart packagePart;
|
||||
private POIXMLDocumentPart parent;
|
||||
private final Map<String, RelationPart> relations = new LinkedHashMap<>();
|
||||
private final Map<String, ReferenceRelationship> referenceRelationships = new LinkedHashMap<>();
|
||||
private boolean isCommitted = false;
|
||||
|
||||
/**
|
||||
|
@ -640,38 +641,42 @@ public class POIXMLDocumentPart {
|
|||
|
||||
// scan breadth-first, so parent-relations are hopefully the shallowest element
|
||||
for (PackageRelationship rel : rels) {
|
||||
if (rel.getTargetMode() == TargetMode.INTERNAL) {
|
||||
URI uri = rel.getTargetURI();
|
||||
if (Objects.equals(rel.getRelationshipType(), HyperlinkRelationship.HYPERLINK_REL_TYPE)) {
|
||||
referenceRelationships.put(rel.getId(), new HyperlinkRelationship(this, rel.getTargetURI(), rel.getTargetMode() == TargetMode.EXTERNAL, rel.getId()));
|
||||
} else {
|
||||
if (rel.getTargetMode() == TargetMode.INTERNAL) {
|
||||
URI uri = rel.getTargetURI();
|
||||
|
||||
// check for internal references (e.g. '#Sheet1!A1')
|
||||
PackagePartName relName;
|
||||
if (uri.getRawFragment() != null) {
|
||||
relName = PackagingURIHelper.createPartName(uri.getPath());
|
||||
} else {
|
||||
relName = PackagingURIHelper.createPartName(uri);
|
||||
}
|
||||
|
||||
final PackagePart p = packagePart.getPackage().getPart(relName);
|
||||
if (p == null) {
|
||||
LOG.atError().log("Skipped invalid entry {}", rel.getTargetURI());
|
||||
continue;
|
||||
}
|
||||
|
||||
POIXMLDocumentPart childPart = context.get(p);
|
||||
if (childPart == null) {
|
||||
childPart = factory.createDocumentPart(this, p);
|
||||
//here we are checking if part if embedded and excel then set it to chart class
|
||||
//so that at the time to writing we can also write updated embedded part
|
||||
if (this instanceof XDDFChart && childPart instanceof XSSFWorkbook) {
|
||||
((XDDFChart) this).setWorkbook((XSSFWorkbook) childPart);
|
||||
// check for internal references (e.g. '#Sheet1!A1')
|
||||
PackagePartName relName;
|
||||
if (uri.getRawFragment() != null) {
|
||||
relName = PackagingURIHelper.createPartName(uri.getPath());
|
||||
} else {
|
||||
relName = PackagingURIHelper.createPartName(uri);
|
||||
}
|
||||
childPart.parent = this;
|
||||
// already add child to context, so other children can reference it
|
||||
context.put(p, childPart);
|
||||
readLater.add(childPart);
|
||||
}
|
||||
|
||||
addRelation(rel, childPart);
|
||||
final PackagePart p = packagePart.getPackage().getPart(relName);
|
||||
if (p == null) {
|
||||
LOG.atError().log("Skipped invalid entry {}", rel.getTargetURI());
|
||||
continue;
|
||||
}
|
||||
|
||||
POIXMLDocumentPart childPart = context.get(p);
|
||||
if (childPart == null) {
|
||||
childPart = factory.createDocumentPart(this, p);
|
||||
//here we are checking if part if embedded and excel then set it to chart class
|
||||
//so that at the time to writing we can also write updated embedded part
|
||||
if (this instanceof XDDFChart && childPart instanceof XSSFWorkbook) {
|
||||
((XDDFChart) this).setWorkbook((XSSFWorkbook) childPart);
|
||||
}
|
||||
childPart.parent = this;
|
||||
// already add child to context, so other children can reference it
|
||||
context.put(p, childPart);
|
||||
readLater.add(childPart);
|
||||
}
|
||||
|
||||
addRelation(rel, childPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -767,4 +772,31 @@ public class POIXMLDocumentPart {
|
|||
throw new POIXMLException("OOXML file structure broken/invalid", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeReferenceRelationship(String relId) {
|
||||
ReferenceRelationship existing = referenceRelationships.remove(relId);
|
||||
if (existing != null) {
|
||||
packagePart.removeRelationship(relId);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ReferenceRelationship getReferenceRelationship(String relId) {
|
||||
return referenceRelationships.get(relId);
|
||||
}
|
||||
|
||||
public HyperlinkRelationship createHyperlink(URI uri, boolean isExternal, String relId) {
|
||||
PackageRelationship pr = packagePart.addRelationship(uri, isExternal ? TargetMode.EXTERNAL : TargetMode.INTERNAL,
|
||||
HyperlinkRelationship.HYPERLINK_REL_TYPE, relId);
|
||||
HyperlinkRelationship hyperlink = new HyperlinkRelationship(this, uri, isExternal, relId);
|
||||
referenceRelationships.put(relId, hyperlink);
|
||||
return hyperlink;
|
||||
}
|
||||
|
||||
public List<ReferenceRelationship> getReferenceRelationships() {
|
||||
List<ReferenceRelationship> list = new ArrayList<>(referenceRelationships.values());
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/* ====================================================================
|
||||
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.ooxml;
|
||||
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.TargetMode;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Defines a reference relationship. A reference relationship can be internal or external.
|
||||
*
|
||||
* @since POI 5.2.6
|
||||
*/
|
||||
public abstract class ReferenceRelationship {
|
||||
private POIXMLDocumentPart container;
|
||||
private final String relationshipType;
|
||||
private final boolean external;
|
||||
private final String id;
|
||||
private final URI uri;
|
||||
|
||||
protected ReferenceRelationship(POIXMLDocumentPart container, PackageRelationship packageRelationship) {
|
||||
if (packageRelationship == null) {
|
||||
throw new IllegalArgumentException("packageRelationship");
|
||||
}
|
||||
|
||||
this.container = container;
|
||||
this.relationshipType = packageRelationship.getRelationshipType();
|
||||
this.uri = packageRelationship.getTargetURI();
|
||||
this.external = packageRelationship.getTargetMode() == TargetMode.EXTERNAL;
|
||||
this.id = packageRelationship.getId();
|
||||
}
|
||||
|
||||
protected ReferenceRelationship(POIXMLDocumentPart container, URI targetUri, boolean isExternal, String relationshipType, String id) {
|
||||
if (targetUri == null) {
|
||||
throw new IllegalArgumentException("targetUri");
|
||||
}
|
||||
|
||||
this.container = container;
|
||||
this.relationshipType = relationshipType;
|
||||
this.uri = targetUri;
|
||||
this.id = id;
|
||||
this.external = isExternal;
|
||||
}
|
||||
|
||||
public POIXMLDocumentPart getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
public String getRelationshipType() {
|
||||
return relationshipType;
|
||||
}
|
||||
|
||||
public boolean isExternal() {
|
||||
return external;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public URI getUri() {
|
||||
return uri;
|
||||
}
|
||||
}
|
|
@ -186,6 +186,12 @@ public final class PackageRelationship {
|
|||
return targetUri;
|
||||
}
|
||||
|
||||
// If it's an internal hyperlink target, we don't
|
||||
// need to apply our normal validation rules
|
||||
if (PackageRelationshipTypes.HYPERLINK_PART.equals(relationshipType)) {
|
||||
return targetUri;
|
||||
}
|
||||
|
||||
// Internal target
|
||||
// If it isn't absolute, resolve it relative
|
||||
// to ourselves
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||
|
@ -32,6 +33,7 @@ import org.apache.poi.openxml4j.opc.PackagePart;
|
|||
import org.apache.poi.openxml4j.opc.PackagePartName;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
|
||||
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
||||
import org.apache.poi.openxml4j.opc.StreamHelper;
|
||||
import org.apache.poi.openxml4j.opc.TargetMode;
|
||||
|
@ -154,7 +156,14 @@ public final class ZipPartMarshaller implements PartMarshaller {
|
|||
// the relationship Target
|
||||
String targetValue;
|
||||
URI uri = rel.getTargetURI();
|
||||
if (rel.getTargetMode() == TargetMode.EXTERNAL) {
|
||||
if (Objects.equals(rel.getRelationshipType(), PackageRelationshipTypes.HYPERLINK_PART)) {
|
||||
// Save the target as-is - we don't need to validate it,
|
||||
targetValue = uri.toString();
|
||||
if (rel.getTargetMode() == TargetMode.EXTERNAL) {
|
||||
// add TargetMode attribute (as it is external link external)
|
||||
relElem.setAttribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME, "External");
|
||||
}
|
||||
} else if (rel.getTargetMode() == TargetMode.EXTERNAL) {
|
||||
// Save the target as-is - we don't need to validate it,
|
||||
// alter it etc
|
||||
targetValue = uri.toString();
|
||||
|
|
|
@ -47,10 +47,12 @@ import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.poi.hpsf.ClassIDPredefined;
|
||||
import org.apache.poi.ooxml.HyperlinkRelationship;
|
||||
import org.apache.poi.ooxml.POIXMLDocument;
|
||||
import org.apache.poi.ooxml.POIXMLDocumentPart;
|
||||
import org.apache.poi.ooxml.POIXMLException;
|
||||
import org.apache.poi.ooxml.POIXMLProperties;
|
||||
import org.apache.poi.ooxml.ReferenceRelationship;
|
||||
import org.apache.poi.ooxml.util.PackageHelper;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
|
@ -683,6 +685,14 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Date1904Su
|
|||
addRelation(rp, clonedSheet);
|
||||
}
|
||||
|
||||
// copy sheet's reference relations;
|
||||
List<ReferenceRelationship> referenceRelationships = srcSheet.getReferenceRelationships();
|
||||
for (ReferenceRelationship ref : referenceRelationships) {
|
||||
if (ref instanceof HyperlinkRelationship) {
|
||||
createHyperlink(ref.getUri(), ref.isExternal(), ref.getId());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
for(PackageRelationship pr : srcSheet.getPackagePart().getRelationships()) {
|
||||
if (pr.getTargetMode() == TargetMode.EXTERNAL) {
|
||||
|
@ -742,6 +752,14 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Date1904Su
|
|||
addRelation(rp, clonedDg);
|
||||
}
|
||||
}
|
||||
|
||||
// copy sheet's reference relations;
|
||||
List<ReferenceRelationship> srcRefs = drawingPatriarch.getReferenceRelationships();
|
||||
for (ReferenceRelationship ref : srcRefs) {
|
||||
if (ref instanceof HyperlinkRelationship) {
|
||||
clonedDg.createHyperlink(ref.getUri(), ref.isExternal(), ref.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
XSSFSheet.cloneTables(clonedSheet);
|
||||
|
|
|
@ -284,7 +284,7 @@ public final class TestPackage {
|
|||
assertEquals(1, rels.size());
|
||||
PackageRelationship rel = rels.getRelationship(0);
|
||||
assertNotNull(rel);
|
||||
assertEquals("Sheet1!A1", rel.getTargetURI().getRawFragment());
|
||||
assertEquals("#Sheet1!A1", rel.getTargetURI().toString());
|
||||
|
||||
assertMSCompatibility(pkg);
|
||||
}
|
||||
|
|
|
@ -323,10 +323,11 @@ class TestRelationships {
|
|||
|
||||
PackageRelationship rId1 = drawingPart.getRelationship("rId1");
|
||||
URI parent = drawingPart.getPartName().getURI();
|
||||
URI rel1 = parent.relativize(rId1.getTargetURI());
|
||||
URI rel11 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId1.getTargetURI());
|
||||
assertEquals("'Another Sheet'!A1", rel1.getFragment());
|
||||
assertEquals("'Another Sheet'!A1", rel11.getFragment());
|
||||
// Hyperlink is not a target of relativize() because it is not resolved based on sourceURI in getTargetURI()
|
||||
// URI rel1 = parent.relativize(rId1.getTargetURI());
|
||||
// URI rel11 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId1.getTargetURI());
|
||||
// assertEquals("'Another Sheet'!A1", rel1.getFragment());
|
||||
// assertEquals("'Another Sheet'!A1", rel11.getFragment());
|
||||
|
||||
PackageRelationship rId2 = drawingPart.getRelationship("rId2");
|
||||
URI rel2 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId2.getTargetURI());
|
||||
|
|
|
@ -53,8 +53,10 @@ import org.apache.commons.io.output.NullPrintStream;
|
|||
import org.apache.poi.POIDataSamples;
|
||||
import org.apache.poi.common.usermodel.HyperlinkType;
|
||||
import org.apache.poi.extractor.ExtractorFactory;
|
||||
import org.apache.poi.ooxml.HyperlinkRelationship;
|
||||
import org.apache.poi.ooxml.POIXMLDocumentPart;
|
||||
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
|
||||
import org.apache.poi.ooxml.ReferenceRelationship;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||
import org.apache.poi.openxml4j.opc.PackagePartName;
|
||||
|
@ -384,23 +386,31 @@ class TestXSLFBugs {
|
|||
|
||||
// Check the relations from this
|
||||
Collection<RelationPart> rels = slide.getRelationParts();
|
||||
Collection<ReferenceRelationship> referenceRelationships = slide.getReferenceRelationships();
|
||||
|
||||
// Should have 6 relations:
|
||||
// 1 external hyperlink (skipped from list)
|
||||
// 4 internal hyperlinks
|
||||
// 1 slide layout
|
||||
assertEquals(5, rels.size());
|
||||
assertEquals(1, rels.size());
|
||||
assertEquals(5, referenceRelationships.size());
|
||||
int layouts = 0;
|
||||
int hyperlinks = 0;
|
||||
int extHyperLinks = 0;
|
||||
for (RelationPart p : rels) {
|
||||
if (p.getRelationship().getRelationshipType().equals(XSLFRelation.HYPERLINK.getRelation())) {
|
||||
hyperlinks++;
|
||||
} else if (p.getDocumentPart() instanceof XSLFSlideLayout) {
|
||||
if (p.getDocumentPart() instanceof XSLFSlideLayout) {
|
||||
layouts++;
|
||||
}
|
||||
}
|
||||
for (ReferenceRelationship ref : referenceRelationships) {
|
||||
if (ref instanceof HyperlinkRelationship) {
|
||||
if (ref.isExternal()) extHyperLinks++;
|
||||
else hyperlinks++;
|
||||
}
|
||||
}
|
||||
assertEquals(1, layouts);
|
||||
assertEquals(4, hyperlinks);
|
||||
assertEquals(1, extHyperLinks);
|
||||
|
||||
// Hyperlinks should all be to #_ftn1 or #ftnref1
|
||||
for (RelationPart p : rels) {
|
||||
|
|
|
@ -18,19 +18,31 @@
|
|||
package org.apache.poi.xssf;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.apache.poi.ooxml.ReferenceRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.ss.usermodel.BaseTestCloneSheet;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
|
||||
import org.apache.poi.xssf.usermodel.XSSFDrawing;
|
||||
import org.apache.poi.xssf.usermodel.XSSFPicture;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualPictureProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPictureNonVisual;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -127,4 +139,74 @@ class TestXSSFCloneSheet extends BaseTestCloneSheet {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBug63189() throws IOException {
|
||||
try (XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("bug63189.xlsx")) {
|
||||
// given
|
||||
String linkRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
|
||||
String linkTargetUrl = "#Sheet3!A1";
|
||||
String imageRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
||||
String imageTargetUrl = "/xl/media/image1.png";
|
||||
|
||||
XSSFSheet srcSheet = workbook.getSheetAt(0);
|
||||
assertEquals("CloneMe", srcSheet.getSheetName());
|
||||
XSSFDrawing drawing = srcSheet.getDrawingPatriarch();
|
||||
assertNotNull(drawing);
|
||||
assertEquals(1, drawing.getShapes().size());
|
||||
assertInstanceOf(XSSFPicture.class, drawing.getShapes().get(0));
|
||||
XSSFPicture lPic = (XSSFPicture)drawing.getShapes().get(0);
|
||||
CTPicture pic = lPic.getCTPicture();
|
||||
CTPictureNonVisual nvPicPr = pic.getNvPicPr();
|
||||
CTNonVisualDrawingProps cNvPr = nvPicPr.getCNvPr();
|
||||
assertTrue(cNvPr.isSetHlinkClick());
|
||||
CTHyperlink hlinkClick = cNvPr.getHlinkClick();
|
||||
String linkRelId = hlinkClick.getId();
|
||||
|
||||
ReferenceRelationship linkRel = drawing.getReferenceRelationship(linkRelId);
|
||||
assertEquals(linkRelationType, linkRel.getRelationshipType());
|
||||
assertEquals(linkTargetUrl, linkRel.getUri().toString());
|
||||
|
||||
CTNonVisualPictureProperties cNvPicPr = nvPicPr.getCNvPicPr();
|
||||
assertTrue(cNvPicPr.getPicLocks().getNoChangeAspect());
|
||||
|
||||
CTBlipFillProperties blipFill = pic.getBlipFill();
|
||||
CTBlip blip = blipFill.getBlip();
|
||||
String imageRelId = blip.getEmbed();
|
||||
|
||||
PackageRelationship imageRel = drawing.getRelationPartById(imageRelId).getRelationship();
|
||||
assertEquals(imageRelationType, imageRel.getRelationshipType());
|
||||
assertEquals(imageTargetUrl, imageRel.getTargetURI().toString());
|
||||
|
||||
// when
|
||||
XSSFSheet clonedSheet = workbook.cloneSheet(0);
|
||||
|
||||
// then
|
||||
XSSFDrawing drawing2 = clonedSheet.getDrawingPatriarch();
|
||||
assertNotNull(drawing2);
|
||||
assertEquals(1, drawing2.getShapes().size());
|
||||
assertInstanceOf(XSSFPicture.class, drawing2.getShapes().get(0));
|
||||
XSSFPicture lPic2 = (XSSFPicture)drawing2.getShapes().get(0);
|
||||
CTPicture pic2 = lPic2.getCTPicture();
|
||||
CTPictureNonVisual nvPicPr2 = pic2.getNvPicPr();
|
||||
CTNonVisualDrawingProps cNvPr2 = nvPicPr2.getCNvPr();
|
||||
assertTrue(cNvPr2.isSetHlinkClick());
|
||||
CTHyperlink hlinkClick2 = cNvPr2.getHlinkClick();
|
||||
String linkRelId2 = hlinkClick2.getId();
|
||||
|
||||
ReferenceRelationship linkRel2 = drawing2.getReferenceRelationship(linkRelId2);
|
||||
assertEquals(linkRelationType, linkRel2.getRelationshipType());
|
||||
assertEquals(linkTargetUrl, linkRel2.getUri().toString());
|
||||
|
||||
CTNonVisualPictureProperties cNvPicPr2 = nvPicPr2.getCNvPicPr();
|
||||
assertTrue(cNvPicPr2.getPicLocks().getNoChangeAspect());
|
||||
|
||||
CTBlipFillProperties blipFill2 = pic2.getBlipFill();
|
||||
CTBlip blip2 = blipFill2.getBlip();
|
||||
String imageRelId2 = blip2.getEmbed();
|
||||
|
||||
PackageRelationship imageRel2 = drawing2.getRelationPartById(imageRelId2).getRelationship();
|
||||
assertEquals(imageRelationType, imageRel2.getRelationshipType());
|
||||
assertEquals(imageTargetUrl, imageRel2.getTargetURI().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ import org.apache.poi.ooxml.POIXMLDocumentPart;
|
|||
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
|
||||
import org.apache.poi.ooxml.POIXMLException;
|
||||
import org.apache.poi.ooxml.POIXMLProperties;
|
||||
import org.apache.poi.ooxml.ReferenceRelationship;
|
||||
import org.apache.poi.ooxml.util.DocumentHelper;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
|
||||
|
@ -234,18 +235,18 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
|
|||
assertEquals(1, wb1.getNumberOfSheets());
|
||||
XSSFSheet sh = wb1.getSheetAt(0);
|
||||
XSSFDrawing drawing = sh.createDrawingPatriarch();
|
||||
List<RelationPart> rels = drawing.getRelationParts();
|
||||
assertEquals(1, rels.size());
|
||||
assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment());
|
||||
List<ReferenceRelationship> referenceRelationships = drawing.getReferenceRelationships();
|
||||
assertEquals(1, referenceRelationships.size());
|
||||
assertEquals("#Sheet1!A1", referenceRelationships.get(0).getUri().toString());
|
||||
|
||||
// And again, just to be sure
|
||||
try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
|
||||
assertEquals(1, wb2.getNumberOfSheets());
|
||||
sh = wb2.getSheetAt(0);
|
||||
drawing = sh.createDrawingPatriarch();
|
||||
rels = drawing.getRelationParts();
|
||||
assertEquals(1, rels.size());
|
||||
assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment());
|
||||
referenceRelationships = drawing.getReferenceRelationships();
|
||||
assertEquals(1, referenceRelationships.size());
|
||||
assertEquals("#Sheet1!A1", referenceRelationships.get(0).getUri().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue