mirror of https://github.com/apache/poi.git
#61797 - Embed Excel / Ole objects into powerpoint
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1819710 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
cdab1a4511
commit
704b41ab9a
|
@ -21,8 +21,8 @@ import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.apache.poi.hslf.model.OLEShape;
|
|
||||||
import org.apache.poi.hslf.usermodel.HSLFObjectData;
|
import org.apache.poi.hslf.usermodel.HSLFObjectData;
|
||||||
|
import org.apache.poi.hslf.usermodel.HSLFObjectShape;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFPictureData;
|
import org.apache.poi.hslf.usermodel.HSLFPictureData;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFPictureShape;
|
import org.apache.poi.hslf.usermodel.HSLFPictureShape;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFShape;
|
import org.apache.poi.hslf.usermodel.HSLFShape;
|
||||||
|
@ -67,19 +67,19 @@ public final class DataExtraction {
|
||||||
for (HSLFSlide slide : ppt.getSlides()) {
|
for (HSLFSlide slide : ppt.getSlides()) {
|
||||||
//extract embedded OLE documents
|
//extract embedded OLE documents
|
||||||
for (HSLFShape shape : slide.getShapes()) {
|
for (HSLFShape shape : slide.getShapes()) {
|
||||||
if (shape instanceof OLEShape) {
|
if (shape instanceof HSLFObjectShape) {
|
||||||
oleIdx++;
|
oleIdx++;
|
||||||
OLEShape ole = (OLEShape) shape;
|
HSLFObjectShape ole = (HSLFObjectShape) shape;
|
||||||
HSLFObjectData data = ole.getObjectData();
|
HSLFObjectData data = ole.getObjectData();
|
||||||
String name = ole.getInstanceName();
|
String name = ole.getInstanceName();
|
||||||
if ("Worksheet".equals(name)) {
|
if ("Worksheet".equals(name)) {
|
||||||
|
|
||||||
//read xls
|
//read xls
|
||||||
@SuppressWarnings({ "unused", "resource" })
|
@SuppressWarnings({ "unused", "resource" })
|
||||||
HSSFWorkbook wb = new HSSFWorkbook(data.getData());
|
HSSFWorkbook wb = new HSSFWorkbook(data.getInputStream());
|
||||||
|
|
||||||
} else if ("Document".equals(name)) {
|
} else if ("Document".equals(name)) {
|
||||||
HWPFDocument doc = new HWPFDocument(data.getData());
|
HWPFDocument doc = new HWPFDocument(data.getInputStream());
|
||||||
//read the word document
|
//read the word document
|
||||||
Range r = doc.getRange();
|
Range r = doc.getRange();
|
||||||
for(int k = 0; k < r.numParagraphs(); k++) {
|
for(int k = 0; k < r.numParagraphs(); k++) {
|
||||||
|
@ -93,8 +93,8 @@ public final class DataExtraction {
|
||||||
out.close();
|
out.close();
|
||||||
doc.close();
|
doc.close();
|
||||||
} else {
|
} else {
|
||||||
FileOutputStream out = new FileOutputStream(ole.getProgID() + "-"+(oleIdx+1)+".dat");
|
FileOutputStream out = new FileOutputStream(ole.getProgId() + "-"+(oleIdx+1)+".dat");
|
||||||
InputStream dis = data.getData();
|
InputStream dis = data.getInputStream();
|
||||||
byte[] chunk = new byte[2048];
|
byte[] chunk = new byte[2048];
|
||||||
int count;
|
int count;
|
||||||
while ((count = dis.read(chunk)) >= 0) {
|
while ((count = dis.read(chunk)) >= 0) {
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/* ====================================================================
|
||||||
|
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.sl.usermodel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.poifs.filesystem.DirectoryEntry;
|
||||||
|
import org.apache.poi.poifs.filesystem.FileMagic;
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.util.IOUtils;
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common interface for OLE shapes, i.e. shapes linked to embedded documents
|
||||||
|
*
|
||||||
|
* @since POI 4.0.0
|
||||||
|
*/
|
||||||
|
public interface ObjectData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an input stream which returns the binary of the embedded data.
|
||||||
|
*
|
||||||
|
* @return the input stream which will contain the binary of the embedded data.
|
||||||
|
*/
|
||||||
|
InputStream getInputStream() throws IOException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the object data as stream (for writing)
|
||||||
|
*/
|
||||||
|
OutputStream getOutputStream() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method to get the embedded data as byte array.
|
||||||
|
*
|
||||||
|
* @return the embedded data.
|
||||||
|
*/
|
||||||
|
default byte[] getBytes() throws IOException {
|
||||||
|
try (InputStream is = getInputStream()) {
|
||||||
|
return IOUtils.toByteArray(is);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return does this ObjectData have an associated POIFS Directory Entry?
|
||||||
|
* (Not all do, those that don't have a data portion)
|
||||||
|
*/
|
||||||
|
default boolean hasDirectoryEntry() {
|
||||||
|
try (final InputStream is = FileMagic.prepareToCheckMagic(getInputStream())) {
|
||||||
|
FileMagic fm = FileMagic.valueOf(is);
|
||||||
|
return fm == FileMagic.OLE2;
|
||||||
|
} catch (IOException e) {
|
||||||
|
POILogger LOG = POILogFactory.getLogger(ObjectData.class);
|
||||||
|
LOG.log(POILogger.WARN, "Can't determine filemagic of ole stream", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the object data. Only call for ones that have
|
||||||
|
* data though. See {@link #hasDirectoryEntry()}.
|
||||||
|
* The caller has to close the corresponding POIFSFileSystem
|
||||||
|
*
|
||||||
|
* @return the object data as an OLE2 directory.
|
||||||
|
* @throws IOException if there was an error reading the data.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("resource")
|
||||||
|
default DirectoryEntry getDirectory() throws IOException {
|
||||||
|
try (final InputStream is = getInputStream()) {
|
||||||
|
return new POIFSFileSystem(is).getRoot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the OLE2 Class Name of the object
|
||||||
|
*/
|
||||||
|
String getOLE2ClassName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a filename suggestion - inspecting/interpreting the Directory object probably gives a better result
|
||||||
|
*/
|
||||||
|
String getFileName();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/* ====================================================================
|
||||||
|
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.sl.usermodel;
|
||||||
|
|
||||||
|
import org.apache.poi.hpsf.ClassID;
|
||||||
|
import org.apache.poi.hpsf.ClassIDPredefined;
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
|
@Beta
|
||||||
|
public interface ObjectMetaData {
|
||||||
|
enum Application {
|
||||||
|
EXCEL_V8("Worksheet", "Excel.Sheet.8", "Package", ClassIDPredefined.EXCEL_V8),
|
||||||
|
EXCEL_V12("Worksheet", "Excel.Sheet.12", "Package", ClassIDPredefined.EXCEL_V12),
|
||||||
|
WORD_V8("Document", "Word.Document.8", "Package", ClassIDPredefined.WORD_V8),
|
||||||
|
WORD_V12("Document", "Word.Document.12", "Package", ClassIDPredefined.WORD_V12),
|
||||||
|
PDF("PDF", "AcroExch.Document", "Contents", ClassIDPredefined.PDF),
|
||||||
|
CUSTOM(null, null, null, null);
|
||||||
|
|
||||||
|
String objectName;
|
||||||
|
String progId;
|
||||||
|
String oleEntry;
|
||||||
|
ClassID classId;
|
||||||
|
|
||||||
|
Application(String objectName, String progId, String oleEntry, ClassIDPredefined classId) {
|
||||||
|
this.objectName = objectName;
|
||||||
|
this.progId = progId;
|
||||||
|
this.classId = (classId == null) ? null : classId.getClassID();
|
||||||
|
this.oleEntry = oleEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Application lookup(String progId) {
|
||||||
|
for (Application a : values()) {
|
||||||
|
if (a.progId != null && a.progId.equals(progId)) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ObjectMetaData getMetaData() {
|
||||||
|
return new ObjectMetaData() {
|
||||||
|
public String getObjectName() {
|
||||||
|
return objectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProgId() {
|
||||||
|
return progId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOleEntry() {
|
||||||
|
return oleEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassID getClassID() {
|
||||||
|
return classId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name of the OLE shape
|
||||||
|
*/
|
||||||
|
String getObjectName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the program id assigned to the OLE container application
|
||||||
|
*/
|
||||||
|
String getProgId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the storage classid of the OLE entry
|
||||||
|
*/
|
||||||
|
ClassID getClassID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name of the OLE entry inside the oleObject#.bin
|
||||||
|
*/
|
||||||
|
String getOleEntry();
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
/* ====================================================================
|
||||||
|
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.sl.usermodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
|
import org.apache.poi.poifs.filesystem.FileMagic;
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.sl.usermodel.ObjectMetaData.Application;
|
||||||
|
import org.apache.poi.util.IOUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An shape which references an embedded OLE object
|
||||||
|
*
|
||||||
|
* @since POI 4.0.0
|
||||||
|
*/
|
||||||
|
public interface ObjectShape<
|
||||||
|
S extends Shape<S,P>,
|
||||||
|
P extends TextParagraph<S,P,? extends TextRun>
|
||||||
|
> extends Shape<S,P>, PlaceableShape<S,P> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the picture data for this picture.
|
||||||
|
*
|
||||||
|
* @return the picture data for this picture.
|
||||||
|
*/
|
||||||
|
PictureData getPictureData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ProgID that stores the OLE Programmatic Identifier.
|
||||||
|
* A ProgID is a string that uniquely identifies a given object, for example,
|
||||||
|
* "Word.Document.8" or "Excel.Sheet.8".
|
||||||
|
*
|
||||||
|
* @return the ProgID
|
||||||
|
*/
|
||||||
|
String getProgId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the full name of the embedded object,
|
||||||
|
* e.g. "Microsoft Word Document" or "Microsoft Office Excel Worksheet".
|
||||||
|
*
|
||||||
|
* @return the full name of the embedded object
|
||||||
|
*/
|
||||||
|
String getFullName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the ole data. If there wasn't an object registered before, a new
|
||||||
|
* ole embedding is registered in the parent slideshow.<p>
|
||||||
|
*
|
||||||
|
* For HSLF this needs to be a {@link POIFSFileSystem} stream.
|
||||||
|
*
|
||||||
|
* @param application a preset application enum
|
||||||
|
* @param metaData or a custom metaData object, can be {@code null} if the application has been set
|
||||||
|
*
|
||||||
|
* @return an {@link OutputStream} which receives the new data, the data will be persisted on {@code close()}
|
||||||
|
*
|
||||||
|
* @throws IOException if the linked object data couldn't be found or a new object data couldn't be initialized
|
||||||
|
*/
|
||||||
|
OutputStream updateObjectData(ObjectMetaData.Application application, ObjectMetaData metaData) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the ole data as stream - the application specific stream is served
|
||||||
|
* The {@link #readObjectDataRaw() raw data} serves the outer/wrapped object, which is usually a
|
||||||
|
* {@link POIFSFileSystem} stream, whereas this method return the unwrapped entry
|
||||||
|
*
|
||||||
|
* @return an {@link InputStream} which serves the object data
|
||||||
|
*
|
||||||
|
* @throws IOException if the linked object data couldn't be found
|
||||||
|
*/
|
||||||
|
default InputStream readObjectData() throws IOException {
|
||||||
|
final String progId = getProgId();
|
||||||
|
if (progId == null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Ole object hasn't been initialized or provided in the source xml. " +
|
||||||
|
"use updateObjectData() first or check the corresponding slideXXX.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Application app = Application.lookup(progId);
|
||||||
|
|
||||||
|
final ByteArrayOutputStream bos = new ByteArrayOutputStream(50000);
|
||||||
|
try (final InputStream is = FileMagic.prepareToCheckMagic(readObjectDataRaw())) {
|
||||||
|
final FileMagic fm = FileMagic.valueOf(is);
|
||||||
|
if (fm == FileMagic.OLE2) {
|
||||||
|
try (final POIFSFileSystem poifs = new POIFSFileSystem(is)) {
|
||||||
|
String[] names = {
|
||||||
|
(app == null) ? null : app.getMetaData().getOleEntry(),
|
||||||
|
// fallback to the usual suspects
|
||||||
|
"Package",
|
||||||
|
"Contents",
|
||||||
|
"CONTENTS",
|
||||||
|
"CONTENTSV30",
|
||||||
|
};
|
||||||
|
final DirectoryNode root = poifs.getRoot();
|
||||||
|
String entryName = null;
|
||||||
|
for (String n : names) {
|
||||||
|
if (root.hasEntry(n)) {
|
||||||
|
entryName = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entryName == null) {
|
||||||
|
poifs.writeFilesystem(bos);
|
||||||
|
} else {
|
||||||
|
try (final InputStream is2 = poifs.createDocumentInputStream(entryName)) {
|
||||||
|
IOUtils.copy(is2, bos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IOUtils.copy(is, bos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ByteArrayInputStream(bos.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method to return the raw data as {@code InputStream}
|
||||||
|
*
|
||||||
|
* @return the raw data stream
|
||||||
|
*
|
||||||
|
* @throws IOException if the data couldn't be retrieved
|
||||||
|
*/
|
||||||
|
default InputStream readObjectDataRaw() throws IOException {
|
||||||
|
return getObjectData().getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the data object
|
||||||
|
*/
|
||||||
|
ObjectData getObjectData();
|
||||||
|
}
|
|
@ -84,4 +84,11 @@ public interface ShapeContainer<
|
||||||
* @param numCols the number of columns
|
* @param numCols the number of columns
|
||||||
*/
|
*/
|
||||||
TableShape<S,P> createTable(int numRows, int numCols);
|
TableShape<S,P> createTable(int numRows, int numCols);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new OLE object shape with the given pictureData as preview image
|
||||||
|
*
|
||||||
|
* @param pictureData the preview image
|
||||||
|
*/
|
||||||
|
ObjectShape<?,?> createOleShape(PictureData pictureData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,20 +18,30 @@ package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.POIXMLDocumentPart.RelationPart;
|
||||||
|
import org.apache.poi.hpsf.ClassID;
|
||||||
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||||
|
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||||
|
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.PackagingURIHelper;
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
import org.apache.poi.util.Beta;
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.xmlbeans.XmlObject;
|
import org.apache.xmlbeans.XmlObject;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTOleObject;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Yegor Kozlov
|
|
||||||
*/
|
|
||||||
@Beta
|
@Beta
|
||||||
public class XSLFDrawing {
|
public class XSLFDrawing {
|
||||||
private XSLFSheet _sheet;
|
private XSLFSheet _sheet;
|
||||||
|
@ -110,4 +120,12 @@ public class XSLFDrawing {
|
||||||
shape.setAnchor(new Rectangle2D.Double());
|
shape.setAnchor(new Rectangle2D.Double());
|
||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public XSLFObjectShape createOleShape(String pictureRel) {
|
||||||
|
CTGraphicalObjectFrame obj = _spTree.addNewGraphicFrame();
|
||||||
|
obj.set(XSLFObjectShape.prototype(_shapeId++, pictureRel));
|
||||||
|
XSLFObjectShape shape = new XSLFObjectShape(obj, _sheet);
|
||||||
|
shape.setAnchor(new Rectangle2D.Double());
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.apache.poi.util.Units;
|
||||||
import org.apache.xmlbeans.XmlCursor;
|
import org.apache.xmlbeans.XmlCursor;
|
||||||
import org.apache.xmlbeans.XmlException;
|
import org.apache.xmlbeans.XmlException;
|
||||||
import org.apache.xmlbeans.XmlObject;
|
import org.apache.xmlbeans.XmlObject;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
||||||
|
@ -86,13 +87,24 @@ public class XSLFGraphicFrame extends XSLFShape implements GraphicalFrame<XSLFSh
|
||||||
|
|
||||||
|
|
||||||
static XSLFGraphicFrame create(CTGraphicalObjectFrame shape, XSLFSheet sheet){
|
static XSLFGraphicFrame create(CTGraphicalObjectFrame shape, XSLFSheet sheet){
|
||||||
String uri = shape.getGraphic().getGraphicData().getUri();
|
switch (getUri(shape)) {
|
||||||
if(XSLFTable.TABLE_URI.equals(uri)){
|
case XSLFTable.TABLE_URI:
|
||||||
return new XSLFTable(shape, sheet);
|
return new XSLFTable(shape, sheet);
|
||||||
} else {
|
case XSLFObjectShape.OLE_URI:
|
||||||
|
return new XSLFObjectShape(shape, sheet);
|
||||||
|
default:
|
||||||
return new XSLFGraphicFrame(shape, sheet);
|
return new XSLFGraphicFrame(shape, sheet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getUri(CTGraphicalObjectFrame shape) {
|
||||||
|
final CTGraphicalObject g = shape.getGraphic();
|
||||||
|
if (g == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
CTGraphicalObjectData gd = g.getGraphicData();
|
||||||
|
return (gd == null) ? null : gd.getUri();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotate this shape.
|
* Rotate this shape.
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.apache.poi.xslf.usermodel;
|
package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -44,6 +45,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTOleObject;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
|
||||||
|
|
||||||
|
@ -275,6 +277,29 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> {
|
||||||
return sh;
|
return sh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XSLFObjectShape createOleShape(PictureData pictureData) {
|
||||||
|
if (!(pictureData instanceof XSLFPictureData)) {
|
||||||
|
throw new IllegalArgumentException("pictureData needs to be of type XSLFPictureData");
|
||||||
|
}
|
||||||
|
XSLFPictureData xPictureData = (XSLFPictureData)pictureData;
|
||||||
|
PackagePart pic = xPictureData.getPackagePart();
|
||||||
|
|
||||||
|
PackageRelationship rel = getSheet().getPackagePart().addRelationship(
|
||||||
|
pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation());
|
||||||
|
|
||||||
|
XSLFObjectShape sh = getDrawing().createOleShape(rel.getId());
|
||||||
|
CTOleObject oleObj = sh.getCTOleObject();
|
||||||
|
Dimension dim = pictureData.getImageDimension();
|
||||||
|
oleObj.setImgW(Units.toEMU(dim.getWidth()));
|
||||||
|
oleObj.setImgH(Units.toEMU(dim.getHeight()));
|
||||||
|
|
||||||
|
|
||||||
|
getShapes().add(sh);
|
||||||
|
sh.setParent(this);
|
||||||
|
return sh;
|
||||||
|
}
|
||||||
|
|
||||||
public XSLFTable createTable(){
|
public XSLFTable createTable(){
|
||||||
XSLFTable sh = getDrawing().createTable();
|
XSLFTable sh = getDrawing().createTable();
|
||||||
_shapes.add(sh);
|
_shapes.add(sh);
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.xslf.usermodel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.POIXMLDocumentPart;
|
||||||
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
|
import org.apache.poi.poifs.filesystem.DirectoryEntry;
|
||||||
|
import org.apache.poi.sl.usermodel.ObjectData;
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An XSLFOleData instance holds the ole binary stream/object
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public final class XSLFObjectData extends POIXMLDocumentPart implements ObjectData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new XSLFOleData node
|
||||||
|
*/
|
||||||
|
protected XSLFObjectData() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct XSLFOleData from a package part
|
||||||
|
*
|
||||||
|
* @param part the package part holding the ole data
|
||||||
|
*
|
||||||
|
* @since POI 3.14-Beta1
|
||||||
|
*/
|
||||||
|
public XSLFObjectData(final PackagePart part) {
|
||||||
|
super(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return getPackagePart().getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream getOutputStream() throws IOException {
|
||||||
|
final PackagePart pp = getPackagePart();
|
||||||
|
pp.clear();
|
||||||
|
return pp.getOutputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *PictureData objects store the actual content in the part directly without keeping a
|
||||||
|
* copy like all others therefore we need to handle them differently.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void prepareForCommit() {
|
||||||
|
// do not clear the part here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setData(final byte[] data) throws IOException {
|
||||||
|
try (final OutputStream os = getPackagePart().getOutputStream()) {
|
||||||
|
os.write(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOLE2ClassName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFileName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,323 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.xslf.usermodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import javax.xml.namespace.QName;
|
||||||
|
|
||||||
|
import org.apache.poi.POIXMLDocumentPart.RelationPart;
|
||||||
|
import org.apache.poi.POIXMLException;
|
||||||
|
import org.apache.poi.hpsf.ClassID;
|
||||||
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||||
|
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||||
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
|
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||||
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
|
import org.apache.poi.poifs.filesystem.FileMagic;
|
||||||
|
import org.apache.poi.poifs.filesystem.Ole10Native;
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.sl.usermodel.ObjectMetaData;
|
||||||
|
import org.apache.poi.sl.usermodel.ObjectMetaData.Application;
|
||||||
|
import org.apache.poi.sl.usermodel.ObjectShape;
|
||||||
|
import org.apache.poi.util.IOUtils;
|
||||||
|
import org.apache.poi.util.Internal;
|
||||||
|
import org.apache.xmlbeans.XmlCursor;
|
||||||
|
import org.apache.xmlbeans.XmlException;
|
||||||
|
import org.apache.xmlbeans.XmlObject;
|
||||||
|
import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrameNonVisual;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTOleObject;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTPictureNonVisual;
|
||||||
|
|
||||||
|
public class XSLFObjectShape extends XSLFGraphicFrame implements ObjectShape<XSLFShape,XSLFTextParagraph> {
|
||||||
|
|
||||||
|
/* package */ static final String OLE_URI = "http://schemas.openxmlformats.org/presentationml/2006/ole";
|
||||||
|
|
||||||
|
private CTOleObject _oleObject;
|
||||||
|
private XSLFPictureData _data;
|
||||||
|
|
||||||
|
/*package*/ XSLFObjectShape(CTGraphicalObjectFrame shape, XSLFSheet sheet){
|
||||||
|
super(shape, sheet);
|
||||||
|
|
||||||
|
CTGraphicalObjectData god = shape.getGraphic().getGraphicData();
|
||||||
|
XmlCursor xc = god.newCursor();
|
||||||
|
// select oleObj potentially under AlternateContent
|
||||||
|
// usually the mc:Choice element will be selected first
|
||||||
|
xc.selectPath("declare namespace p='"+PML_NS+"' .//p:oleObj");
|
||||||
|
try {
|
||||||
|
if (!xc.toNextSelection()) {
|
||||||
|
throw new IllegalStateException("p:oleObj element was not found in\n " + god);
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlObject xo = xc.getObject();
|
||||||
|
// Pesky XmlBeans bug - see Bugzilla #49934
|
||||||
|
// it never happens when using the full ooxml-schemas jar but may happen with the abridged poi-ooxml-schemas
|
||||||
|
if (xo instanceof XmlAnyTypeImpl){
|
||||||
|
String errStr =
|
||||||
|
"Schemas (*.xsb) for CTOleObject can't be loaded - usually this happens when OSGI " +
|
||||||
|
"loading is used and the thread context classloader has no reference to " +
|
||||||
|
"the xmlbeans classes - use POIXMLTypeLoader.setClassLoader() to set the loader, " +
|
||||||
|
"e.g. with CTOleObject.class.getClassLoader()"
|
||||||
|
;
|
||||||
|
throw new IllegalStateException(errStr);
|
||||||
|
}
|
||||||
|
_oleObject = (CTOleObject)xo;
|
||||||
|
} finally {
|
||||||
|
xc.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Internal
|
||||||
|
public CTOleObject getCTOleObject(){
|
||||||
|
return _oleObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XSLFObjectData getObjectData() {
|
||||||
|
String oleRel = getCTOleObject().getId();
|
||||||
|
return getSheet().getRelationPartById(oleRel).getDocumentPart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProgId() {
|
||||||
|
return (_oleObject == null) ? null : _oleObject.getProgId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFullName() {
|
||||||
|
return (_oleObject == null) ? null : _oleObject.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the data on the (internal) picture.
|
||||||
|
* For an external linked picture, will return null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public XSLFPictureData getPictureData() {
|
||||||
|
if(_data == null){
|
||||||
|
String blipId = getBlipId();
|
||||||
|
if (blipId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackagePart p = getSheet().getPackagePart();
|
||||||
|
PackageRelationship rel = p.getRelationship(blipId);
|
||||||
|
if (rel != null) {
|
||||||
|
try {
|
||||||
|
PackagePart imgPart = p.getRelatedPart(rel);
|
||||||
|
_data = new XSLFPictureData(imgPart);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new POIXMLException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CTBlip getBlip(){
|
||||||
|
return getBlipFill().getBlip();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getBlipId(){
|
||||||
|
String id = getBlip().getEmbed();
|
||||||
|
if (id.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CTBlipFillProperties getBlipFill() {
|
||||||
|
String xquery =
|
||||||
|
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' "
|
||||||
|
+ ".//p:blipFill"
|
||||||
|
;
|
||||||
|
XmlObject xo = selectProperty(XmlObject.class, xquery);
|
||||||
|
try {
|
||||||
|
xo = CTPicture.Factory.parse(xo.getDomNode());
|
||||||
|
} catch (XmlException xe) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ((CTPicture)xo).getBlipFill();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream updateObjectData(final Application application, final ObjectMetaData metaData) throws IOException {
|
||||||
|
final ObjectMetaData md = (application != null) ? application.getMetaData() : metaData;
|
||||||
|
if (md == null || md.getClassID() == null) {
|
||||||
|
throw new IllegalArgumentException("either application and/or metaData needs to be set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final XSLFSheet sheet = getSheet();
|
||||||
|
|
||||||
|
final RelationPart rp;
|
||||||
|
if (_oleObject.isSetId()) {
|
||||||
|
// object data was already set
|
||||||
|
rp = sheet.getRelationPartById(_oleObject.getId());
|
||||||
|
} else {
|
||||||
|
// object data needs to be initialized
|
||||||
|
try {
|
||||||
|
final XSLFRelation descriptor = XSLFRelation.OLE_OBJECT;
|
||||||
|
final OPCPackage pack = sheet.getPackagePart().getPackage();
|
||||||
|
int nextIdx = pack.getUnusedPartIndex(descriptor.getDefaultFileName());
|
||||||
|
rp = sheet.createRelationship(descriptor, XSLFFactory.getInstance(), nextIdx, false);
|
||||||
|
_oleObject.setId(rp.getRelationship().getId());
|
||||||
|
} catch (InvalidFormatException e) {
|
||||||
|
throw new IOException("Unable to add new ole embedding", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// setting spid only works with a vml drawing object
|
||||||
|
// oleObj.setSpid("_x0000_s"+(1025+objectIdx));
|
||||||
|
}
|
||||||
|
|
||||||
|
_oleObject.setProgId(md.getProgId());
|
||||||
|
_oleObject.setName(md.getObjectName());
|
||||||
|
|
||||||
|
return new XSLFObjectOutputStream(rp.getDocumentPart().getPackagePart(),md);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class XSLFObjectOutputStream extends ByteArrayOutputStream {
|
||||||
|
final PackagePart objectPart;
|
||||||
|
final ObjectMetaData metaData;
|
||||||
|
private XSLFObjectOutputStream(final PackagePart objectPart, final ObjectMetaData metaData) {
|
||||||
|
super(100000);
|
||||||
|
this.objectPart = objectPart;
|
||||||
|
this.metaData = metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
objectPart.clear();
|
||||||
|
try (final OutputStream os = objectPart.getOutputStream()) {
|
||||||
|
final ByteArrayInputStream bis = new ByteArrayInputStream(this.buf, 0, size());
|
||||||
|
final FileMagic fm = FileMagic.valueOf(this.buf);
|
||||||
|
|
||||||
|
if (fm == FileMagic.OLE2) {
|
||||||
|
try (final POIFSFileSystem poifs = new POIFSFileSystem(bis)) {
|
||||||
|
poifs.getRoot().setStorageClsid(metaData.getClassID());
|
||||||
|
poifs.writeFilesystem(os);
|
||||||
|
}
|
||||||
|
} else if (metaData.getOleEntry() == null) {
|
||||||
|
// OLE Name hasn't been specified, pass the input through
|
||||||
|
os.write(this.buf, 0, size());
|
||||||
|
} else {
|
||||||
|
try (final POIFSFileSystem poifs = new POIFSFileSystem()) {
|
||||||
|
final ClassID clsId = metaData.getClassID();
|
||||||
|
if (clsId != null) {
|
||||||
|
poifs.getRoot().setStorageClsid(clsId);
|
||||||
|
}
|
||||||
|
poifs.createDocument(bis, metaData.getOleEntry());
|
||||||
|
|
||||||
|
Ole10Native.createOleMarkerEntry(poifs);
|
||||||
|
|
||||||
|
poifs.writeFilesystem(os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param shapeId 1-based shapeId
|
||||||
|
* @param picRel relationship to the picture data in the ooxml package
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static CTGraphicalObjectFrame prototype(int shapeId, String picRel){
|
||||||
|
CTGraphicalObjectFrame frame = CTGraphicalObjectFrame.Factory.newInstance();
|
||||||
|
CTGraphicalObjectFrameNonVisual nvGr = frame.addNewNvGraphicFramePr();
|
||||||
|
|
||||||
|
CTNonVisualDrawingProps cnv = nvGr.addNewCNvPr();
|
||||||
|
// usually the shape name has its index based on the n-th embeding, but having
|
||||||
|
// the prototype separate from the actual updating of the object, we use the shape id
|
||||||
|
cnv.setName("Object " + (shapeId + 1));
|
||||||
|
cnv.setId(shapeId + 1);
|
||||||
|
|
||||||
|
// add empty property elements otherwise Powerpoint doesn't load the file ...
|
||||||
|
nvGr.addNewCNvGraphicFramePr();
|
||||||
|
nvGr.addNewNvPr();
|
||||||
|
|
||||||
|
frame.addNewXfrm();
|
||||||
|
CTGraphicalObjectData gr = frame.addNewGraphic().addNewGraphicData();
|
||||||
|
gr.setUri(OLE_URI);
|
||||||
|
XmlCursor grCur = gr.newCursor();
|
||||||
|
grCur.toEndToken();
|
||||||
|
grCur.beginElement(new QName(PML_NS, "oleObj"));
|
||||||
|
grCur.insertElement(new QName(PML_NS, "embed"));
|
||||||
|
|
||||||
|
|
||||||
|
CTGroupShape grpShp = CTGroupShape.Factory.newInstance();
|
||||||
|
CTPicture pic = grpShp.addNewPic();
|
||||||
|
CTPictureNonVisual nvPicPr = pic.addNewNvPicPr();
|
||||||
|
CTNonVisualDrawingProps cNvPr = nvPicPr.addNewCNvPr();
|
||||||
|
cNvPr.setName("");
|
||||||
|
cNvPr.setId(0);
|
||||||
|
nvPicPr.addNewCNvPicPr();
|
||||||
|
nvPicPr.addNewNvPr();
|
||||||
|
|
||||||
|
|
||||||
|
CTBlipFillProperties blip = pic.addNewBlipFill();
|
||||||
|
blip.addNewBlip().setEmbed(picRel);
|
||||||
|
blip.addNewStretch().addNewFillRect();
|
||||||
|
|
||||||
|
CTShapeProperties spPr = pic.addNewSpPr();
|
||||||
|
CTTransform2D xfrm = spPr.addNewXfrm();
|
||||||
|
CTPoint2D off = xfrm.addNewOff();
|
||||||
|
off.setX(1270000);
|
||||||
|
off.setY(1270000);
|
||||||
|
CTPositiveSize2D xext = xfrm.addNewExt();
|
||||||
|
xext.setCx(1270000);
|
||||||
|
xext.setCy(1270000);
|
||||||
|
|
||||||
|
spPr.addNewPrstGeom().setPrst(STShapeType.RECT);
|
||||||
|
|
||||||
|
|
||||||
|
XmlCursor picCur = grpShp.newCursor();
|
||||||
|
picCur.toStartDoc();
|
||||||
|
picCur.moveXmlContents(grCur);
|
||||||
|
picCur.dispose();
|
||||||
|
|
||||||
|
grCur.dispose();
|
||||||
|
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
}
|
|
@ -231,6 +231,14 @@ public class XSLFRelation extends POIXMLRelation {
|
||||||
XSLFTableStyles.class
|
XSLFTableStyles.class
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static final XSLFRelation OLE_OBJECT = new XSLFRelation(
|
||||||
|
"application/vnd.openxmlformats-officedocument.oleObject",
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject",
|
||||||
|
"/ppt/embeddings/oleObject#.bin",
|
||||||
|
XSLFObjectData.class
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
private XSLFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
|
private XSLFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
|
||||||
super(type, rel, defaultName, cls);
|
super(type, rel, defaultName, cls);
|
||||||
_table.put(rel, this);
|
_table.put(rel, this);
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
|
import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -45,13 +46,23 @@ import org.apache.poi.sl.draw.Drawable;
|
||||||
import org.apache.poi.sl.usermodel.PictureData;
|
import org.apache.poi.sl.usermodel.PictureData;
|
||||||
import org.apache.poi.sl.usermodel.Placeholder;
|
import org.apache.poi.sl.usermodel.Placeholder;
|
||||||
import org.apache.poi.sl.usermodel.Sheet;
|
import org.apache.poi.sl.usermodel.Sheet;
|
||||||
import org.apache.poi.util.*;
|
import org.apache.poi.util.Beta;
|
||||||
|
import org.apache.poi.util.IOUtils;
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
import org.apache.poi.util.Units;
|
||||||
import org.apache.xmlbeans.XmlCursor;
|
import org.apache.xmlbeans.XmlCursor;
|
||||||
import org.apache.xmlbeans.XmlException;
|
import org.apache.xmlbeans.XmlException;
|
||||||
import org.apache.xmlbeans.XmlObject;
|
import org.apache.xmlbeans.XmlObject;
|
||||||
import org.apache.xmlbeans.XmlOptions;
|
import org.apache.xmlbeans.XmlOptions;
|
||||||
import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
|
import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.*;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTOleObject;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
|
||||||
|
|
||||||
@Beta
|
@Beta
|
||||||
public abstract class XSLFSheet extends POIXMLDocumentPart
|
public abstract class XSLFSheet extends POIXMLDocumentPart
|
||||||
|
@ -256,6 +267,28 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XSLFObjectShape createOleShape(PictureData pictureData) {
|
||||||
|
if (!(pictureData instanceof XSLFPictureData)) {
|
||||||
|
throw new IllegalArgumentException("pictureData needs to be of type XSLFPictureData");
|
||||||
|
}
|
||||||
|
XSLFPictureData xPictureData = (XSLFPictureData)pictureData;
|
||||||
|
PackagePart pic = xPictureData.getPackagePart();
|
||||||
|
|
||||||
|
RelationPart rp = addRelation(null, XSLFRelation.IMAGES, new XSLFPictureData(pic));
|
||||||
|
|
||||||
|
XSLFObjectShape sh = getDrawing().createOleShape(rp.getRelationship().getId());
|
||||||
|
CTOleObject oleObj = sh.getCTOleObject();
|
||||||
|
Dimension dim = pictureData.getImageDimension();
|
||||||
|
oleObj.setImgW(Units.toEMU(dim.getWidth()));
|
||||||
|
oleObj.setImgH(Units.toEMU(dim.getHeight()));
|
||||||
|
|
||||||
|
|
||||||
|
getShapes().add(sh);
|
||||||
|
sh.setParent(this);
|
||||||
|
return sh;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an iterator over the shapes in this sheet
|
* Returns an iterator over the shapes in this sheet
|
||||||
*
|
*
|
||||||
|
|
|
@ -59,25 +59,28 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
|
||||||
|
|
||||||
CTGraphicalObjectData god = shape.getGraphic().getGraphicData();
|
CTGraphicalObjectData god = shape.getGraphic().getGraphicData();
|
||||||
XmlCursor xc = god.newCursor();
|
XmlCursor xc = god.newCursor();
|
||||||
if (!xc.toChild(DRAWINGML_URI, "tbl")) {
|
try {
|
||||||
throw new IllegalStateException("a:tbl element was not found in\n " + god);
|
if (!xc.toChild(DRAWINGML_URI, "tbl")) {
|
||||||
|
throw new IllegalStateException("a:tbl element was not found in\n " + god);
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlObject xo = xc.getObject();
|
||||||
|
// Pesky XmlBeans bug - see Bugzilla #49934
|
||||||
|
// it never happens when using the full ooxml-schemas jar but may happen with the abridged poi-ooxml-schemas
|
||||||
|
if (xo instanceof XmlAnyTypeImpl){
|
||||||
|
String errStr =
|
||||||
|
"Schemas (*.xsb) for CTTable can't be loaded - usually this happens when OSGI " +
|
||||||
|
"loading is used and the thread context classloader has no reference to " +
|
||||||
|
"the xmlbeans classes - use POIXMLTypeLoader.setClassLoader() to set the loader, " +
|
||||||
|
"e.g. with CTTable.class.getClassLoader()"
|
||||||
|
;
|
||||||
|
throw new IllegalStateException(errStr);
|
||||||
|
}
|
||||||
|
_table = (CTTable)xo;
|
||||||
|
} finally {
|
||||||
|
xc.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlObject xo = xc.getObject();
|
|
||||||
// Pesky XmlBeans bug - see Bugzilla #49934
|
|
||||||
// it never happens when using the full ooxml-schemas jar but may happen with the abridged poi-ooxml-schemas
|
|
||||||
if (xo instanceof XmlAnyTypeImpl){
|
|
||||||
String errStr =
|
|
||||||
"Schemas (*.xsb) for CTTable can't be loaded - usually this happens when OSGI " +
|
|
||||||
"loading is used and the thread context classloader has no reference to " +
|
|
||||||
"the xmlbeans classes - use POIXMLTypeLoader.setClassLoader() to set the loader, " +
|
|
||||||
"e.g. with CTTable.class.getClassLoader()"
|
|
||||||
;
|
|
||||||
throw new IllegalStateException(errStr);
|
|
||||||
}
|
|
||||||
_table = (CTTable)xo;
|
|
||||||
xc.dispose();
|
|
||||||
|
|
||||||
_rows = new ArrayList<>(_table.sizeOfTrArray());
|
_rows = new ArrayList<>(_table.sizeOfTrArray());
|
||||||
for(CTTableRow row : _table.getTrArray()) {
|
for(CTTableRow row : _table.getTrArray()) {
|
||||||
_rows.add(new XSLFTableRow(row, this));
|
_rows.add(new XSLFTableRow(row, this));
|
||||||
|
|
|
@ -0,0 +1,220 @@
|
||||||
|
/* ====================================================================
|
||||||
|
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.sl;
|
||||||
|
|
||||||
|
import static org.apache.poi.sl.SLCommonUtils.xslfOnly;
|
||||||
|
import static org.apache.poi.sl.usermodel.ObjectMetaData.Application.EXCEL_V12;
|
||||||
|
import static org.apache.poi.sl.usermodel.ObjectMetaData.Application.EXCEL_V8;
|
||||||
|
import static org.apache.poi.sl.usermodel.ObjectMetaData.Application.PDF;
|
||||||
|
import static org.apache.poi.sl.usermodel.ObjectMetaData.Application.WORD_V12;
|
||||||
|
import static org.apache.poi.sl.usermodel.ObjectMetaData.Application.WORD_V8;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.junit.Assume.assumeFalse;
|
||||||
|
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.poi.POIDataSamples;
|
||||||
|
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||||
|
import org.apache.poi.poifs.storage.RawDataUtil;
|
||||||
|
import org.apache.poi.sl.usermodel.ObjectMetaData;
|
||||||
|
import org.apache.poi.sl.usermodel.ObjectShape;
|
||||||
|
import org.apache.poi.sl.usermodel.PictureData;
|
||||||
|
import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
||||||
|
import org.apache.poi.sl.usermodel.Slide;
|
||||||
|
import org.apache.poi.sl.usermodel.SlideShow;
|
||||||
|
import org.apache.poi.sl.usermodel.SlideShowFactory;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||||
|
import org.apache.poi.util.IOUtils;
|
||||||
|
import org.apache.poi.xslf.usermodel.XMLSlideShow;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.junit.runners.Parameterized.Parameter;
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
|
public class TestOleShape {
|
||||||
|
private static final String PDF_SAMPLE =
|
||||||
|
"H4sIAAAAAAAAAJWUezRUWxzHe+o2FXncVtxLpxi3FPOeKYspjMdM5J1S4TTOaDIzxzpzJo9CUrnrSiUxIeT" +
|
||||||
|
"9jB7yqInihrhepTwqt1AT5VZCC7XcY0LWcv+5Z521zz6fvX+/vb/7t9cX78CyMiQZ0XD4W4OFEzgKQATgg4" +
|
||||||
|
"dxJiYAwRYS+aCHACqGnHAAABCs+AIUQrCvAEQhFsSFvSEck4kTowgECnEBl6E4OxGesfLkl2Bc0g5V/MCHt" +
|
||||||
|
"duqroTFC27YIKGAp+OL5Ou1SsmebA1XvciLk+Ucg84aLclQZhRZmh0amrG9Ina4t7Lh+ZCAHyezsg/NXsZg" +
|
||||||
|
"vuPw8NIedsrI2sZlz2vfhLkZfIgfMr4zFvTrmfbRgMmPw1UTvWk+r4MCZfLtj2WPPStVJ0P2PiKkxo+YnJ5" +
|
||||||
|
"Ua7v5UnefkB9ev0vSR37a8NrsC2lApaLp7086wS3Lzi2LqB3TMW2POrdRRUYMFYWs8vBo/kSQ6dYXpR6rxM" +
|
||||||
|
"UXM0vqu4arpe5dha7XS5MYS5P1arVG653sb8pXqReVw/TfjK8R3q4Z7X7Uk9dZ2Bcl8Wpmsl80Xf1QTOxe3" +
|
||||||
|
"Nutwus0kYge1LoHvgKLbc/f6WvdcsBfS9ctU3vSaneHNm0w/uhrm0Zett5O83s2xh2Gm8WZfWJ+/CNWruZ2" +
|
||||||
|
"cap8tR2/U9bAfRBbYt3PL9jvb3+0usqSF6vfrFuEq8Hf6jgrx/fERpZJEjKbHtJ11jCdUwI7Oc8QrmZf2pr" +
|
||||||
|
"L43WJn1mlT1ydV+QbrndcdN3qSEnicVhmoJyfWyprUEsIZlPyvi0tiEy7FzkOnqlE/qC6xFSpyg0E8tODa7" +
|
||||||
|
"qiKX61hMxRkZt73ITLWIHwtZtj71NbS4/BgKHnssOMcXOp1aacX4A//V+VFN4TWl6QryxdkcAp79BZcipmP" +
|
||||||
|
"OWOWkS6KhqUWlG+yCCxVMMtfW+9e56++gKHYEs9PNJztTI6KtyfOCDPOBppt3udRs3NpGrKfrs3i3Nivtrs" +
|
||||||
|
"VTl5LFerXZlTbf5XumbeYsOfwnve5ksEjKy6s1Z78rpbeJq7biTdzWwU3vhZ1GqkYb9D+t6mYvWLhXn6FWi" +
|
||||||
|
"c60VWpbBtVYHLQkmbh6Txwm6Ul3LbNW/Hs5FtLnlNX3fsAX2jPdlOI5W3HDIcm2MyNiR39rdyHlpwusjoOj" +
|
||||||
|
"I3IKfgPMILSzHZInmQaWyUFXEi0bHsCLX8pm9Gzl2vou7E3rrkPYdt1EwW3R5Qcg8rwzk88c1p13l8v+WkY" +
|
||||||
|
"75FHeS7XrvRsHgLy+wfr2EBRfNJ/4UVhUrihRqDktXciPGxWv1eXs396/0lqWG3YtU/A+D90hrT46cumSUN" +
|
||||||
|
"rBdG0G2Knn3T9Kw0X96vbhxMyr92uqUNOa4aEnGqP8us6GULm7mIyFKuxnOW2MZEEuKXmOpxnnqlwiMn+ju" +
|
||||||
|
"Xu+inC5mpG9oesxKkhcJq9bra5vR3H7l10hGbAxqu6t0LvHzaDnPIp/zeu0iXj1NNtVc+cMyUsH18u7TGXJ" +
|
||||||
|
"XiL4W3tqaL2mq6zkgXWB6kOTB3RxW8PHAOvzfaufDptdg7qmZlEcrUzbd5jKtVb85Sr9jaMT8a3y2Q30+3/" +
|
||||||
|
"FrsfGZDblh/mYnHhCg3ekm2q1JIYEVCd9rv42PNb9RFpuSsa4MNE0GfdSYDv6lsudikg4NE3tNugfWmfIY6" +
|
||||||
|
"7TeYvZCItG0zmDxrQwrjsQxArZ1RzHSA72CKgURgyqQszAASQOCCWItZETaAtdg7nYc2x85cAv0ggOAA+kC" +
|
||||||
|
"KnA4gAolQLGzG3ewgbz5oDgcA+zBEBEhUkhGDQiZvpc3tHlBMtYBFKBYsBiiz0dYILPGbs73vqynoDHLGKA" +
|
||||||
|
"KKxH5TK3MDZzAbQBEJNPNngc1iQUf4XMjJ2nxazxR3gsSwBOFCYoCsWPOHRtJ/ahQronbyvcWYnqljcJrdu" +
|
||||||
|
"2RK9pwE9DkJLLDioDACbOSCfAQGSEYkqhGJCGw8hKJ+xgSCgvogoN8hPldsBCM+mzZ9P0wE9pZwof8V92MD" +
|
||||||
|
"jHkKLEAUFMA+04XC1EzX6UdMAALxcERgK444+wB0Go1CA3jANCNRGdj1UoyIZhlpPsMobf48GmkeI1Pp8xi" +
|
||||||
|
"Nsm0eo9O3/mAoAvIFEKIQ58wPgrAtK+oJwyjAmL0+bBEPBugzGsUoiKAKhSQGmYjD4y3trXD/AmBc9IeqBwAA";
|
||||||
|
|
||||||
|
enum Api { HSLF, XSLF };
|
||||||
|
|
||||||
|
|
||||||
|
@Parameter(value = 0)
|
||||||
|
public Api api;
|
||||||
|
@Parameter(value = 1)
|
||||||
|
public ObjectMetaData.Application app;
|
||||||
|
|
||||||
|
|
||||||
|
private static File pictureFile;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void initPicture() {
|
||||||
|
pictureFile = POIDataSamples.getSlideShowInstance().getFile("wrench.emf");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Parameters(name="{0} {1}")
|
||||||
|
public static Collection<Object[]> data() {
|
||||||
|
return Arrays.asList(new Object[][] {
|
||||||
|
{ Api.HSLF, EXCEL_V8 },
|
||||||
|
{ Api.HSLF, WORD_V8 },
|
||||||
|
{ Api.HSLF, PDF },
|
||||||
|
{ Api.XSLF, EXCEL_V12 },
|
||||||
|
{ Api.XSLF, WORD_V12 },
|
||||||
|
{ Api.XSLF, PDF },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void embedData() throws IOException, InvalidFormatException {
|
||||||
|
final ByteArrayInputStream pptBytes;
|
||||||
|
try (SlideShow<?,?> ppt = createSlideShow()) {
|
||||||
|
final PictureData picData = ppt.addPicture(pictureFile, PictureType.EMF);
|
||||||
|
final Slide<?,?> slide = ppt.createSlide();
|
||||||
|
final ObjectShape<?,?> oleShape = slide.createOleShape(picData);
|
||||||
|
oleShape.setAnchor(new Rectangle2D.Double(100,100,100,100));
|
||||||
|
try (OutputStream os = oleShape.updateObjectData(app, null)) {
|
||||||
|
fillOleData(os);
|
||||||
|
}
|
||||||
|
final ByteArrayOutputStream bos = new ByteArrayOutputStream(50000);
|
||||||
|
ppt.write(bos);
|
||||||
|
pptBytes = new ByteArrayInputStream(bos.toByteArray());
|
||||||
|
}
|
||||||
|
try (SlideShow<?,?> ppt = SlideShowFactory.create(pptBytes)) {
|
||||||
|
final ObjectShape<?,?> oleShape = (ObjectShape<?,?>)ppt.getSlides().get(0).getShapes().get(0);
|
||||||
|
try (InputStream bis = oleShape.readObjectData()) {
|
||||||
|
validateOleData(bis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SlideShow<?,?> createSlideShow() {
|
||||||
|
if (api == Api.XSLF) {
|
||||||
|
return new XMLSlideShow();
|
||||||
|
} else {
|
||||||
|
assumeFalse(xslfOnly());
|
||||||
|
return new HSLFSlideShow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void fillOleData(final OutputStream out) throws IOException {
|
||||||
|
switch (app) {
|
||||||
|
case EXCEL_V8:
|
||||||
|
case EXCEL_V12:
|
||||||
|
try (Workbook wb = (app == EXCEL_V12) ? new XSSFWorkbook() : new HSSFWorkbook()) {
|
||||||
|
wb.createSheet().createRow(0).createCell(0).setCellValue("test me");
|
||||||
|
wb.write(out);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WORD_V8:
|
||||||
|
try (InputStream is = POIDataSamples.getDocumentInstance().openResourceAsStream("simple.doc")) {
|
||||||
|
IOUtils.copy(is, out);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WORD_V12:
|
||||||
|
try (XWPFDocument doc = new XWPFDocument()) {
|
||||||
|
doc.createParagraph().createRun().setText("Test me");
|
||||||
|
doc.write(out);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PDF:
|
||||||
|
out.write(RawDataUtil.decompress(PDF_SAMPLE));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case CUSTOM:
|
||||||
|
fail("not implemented");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateOleData(final InputStream in) throws IOException, InvalidFormatException {
|
||||||
|
switch (app) {
|
||||||
|
case EXCEL_V8:
|
||||||
|
case EXCEL_V12:
|
||||||
|
try (Workbook wb = WorkbookFactory.create(in)) {
|
||||||
|
assertEquals("test me", wb.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WORD_V8:
|
||||||
|
try (HWPFDocument doc = new HWPFDocument(in)) {
|
||||||
|
assertEquals("This is a simple file created with Word 97-SR2.\r", doc.getDocumentText());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WORD_V12:
|
||||||
|
try (XWPFDocument doc = new XWPFDocument(in)) {
|
||||||
|
assertEquals("Test me", doc.getParagraphs().get(0).getText());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PDF:
|
||||||
|
final byte[] expected = RawDataUtil.decompress(PDF_SAMPLE);
|
||||||
|
final byte[] actual = IOUtils.toByteArray(in);
|
||||||
|
assertArrayEquals(expected, actual);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case CUSTOM:
|
||||||
|
fail("not implemented");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,7 +29,6 @@ import org.apache.poi.POIOLE2TextExtractor;
|
||||||
import org.apache.poi.hslf.model.Comment;
|
import org.apache.poi.hslf.model.Comment;
|
||||||
import org.apache.poi.hslf.model.HSLFMetroShape;
|
import org.apache.poi.hslf.model.HSLFMetroShape;
|
||||||
import org.apache.poi.hslf.model.HeadersFooters;
|
import org.apache.poi.hslf.model.HeadersFooters;
|
||||||
import org.apache.poi.hslf.model.OLEShape;
|
|
||||||
import org.apache.poi.hslf.usermodel.HSLFMasterSheet;
|
import org.apache.poi.hslf.usermodel.HSLFMasterSheet;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFNotes;
|
import org.apache.poi.hslf.usermodel.HSLFNotes;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFShape;
|
import org.apache.poi.hslf.usermodel.HSLFShape;
|
||||||
|
@ -41,6 +40,7 @@ import org.apache.poi.hslf.usermodel.HSLFTable;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFTableCell;
|
import org.apache.poi.hslf.usermodel.HSLFTableCell;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
|
import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFTextShape;
|
import org.apache.poi.hslf.usermodel.HSLFTextShape;
|
||||||
|
import org.apache.poi.hslf.usermodel.HSLFObjectShape;
|
||||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
@ -194,13 +194,13 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor {
|
||||||
return getText(false, true);
|
return getText(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<OLEShape> getOLEShapes() {
|
public List<HSLFObjectShape> getOLEShapes() {
|
||||||
List<OLEShape> list = new ArrayList<>();
|
List<HSLFObjectShape> list = new ArrayList<>();
|
||||||
|
|
||||||
for (HSLFSlide slide : _slides) {
|
for (HSLFSlide slide : _slides) {
|
||||||
for (HSLFShape shape : slide.getShapes()) {
|
for (HSLFShape shape : slide.getShapes()) {
|
||||||
if (shape instanceof OLEShape) {
|
if (shape instanceof HSLFObjectShape) {
|
||||||
list.add((OLEShape) shape);
|
list.add((HSLFObjectShape) shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
package org.apache.poi.hslf.record;
|
package org.apache.poi.hslf.record;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
|
@ -31,7 +31,7 @@ public class ExEmbed extends RecordContainer {
|
||||||
/**
|
/**
|
||||||
* Record header data.
|
* Record header data.
|
||||||
*/
|
*/
|
||||||
private byte[] _header;
|
private final byte[] _header;
|
||||||
|
|
||||||
// Links to our more interesting children
|
// Links to our more interesting children
|
||||||
private RecordAtom embedAtom;
|
private RecordAtom embedAtom;
|
||||||
|
@ -47,7 +47,7 @@ public class ExEmbed extends RecordContainer {
|
||||||
* @param start the start offset into the byte array.
|
* @param start the start offset into the byte array.
|
||||||
* @param len the length of the slice in the byte array.
|
* @param len the length of the slice in the byte array.
|
||||||
*/
|
*/
|
||||||
protected ExEmbed(byte[] source, int start, int len) {
|
protected ExEmbed(final byte[] source, final int start, final int len) {
|
||||||
// Grab the header
|
// Grab the header
|
||||||
_header = new byte[8];
|
_header = new byte[8];
|
||||||
System.arraycopy(source,start,_header,0,8);
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
@ -62,7 +62,7 @@ public class ExEmbed extends RecordContainer {
|
||||||
*
|
*
|
||||||
* @param embedAtom the new embedAtom
|
* @param embedAtom the new embedAtom
|
||||||
*/
|
*/
|
||||||
protected ExEmbed(RecordAtom embedAtom) {
|
protected ExEmbed(final RecordAtom embedAtom) {
|
||||||
this();
|
this();
|
||||||
_children[0] = this.embedAtom = embedAtom;
|
_children[0] = this.embedAtom = embedAtom;
|
||||||
}
|
}
|
||||||
|
@ -81,11 +81,11 @@ public class ExEmbed extends RecordContainer {
|
||||||
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
|
||||||
// Setup our child records
|
// Setup our child records
|
||||||
CString cs1 = new CString();
|
final CString cs1 = new CString();
|
||||||
cs1.setOptions(0x1 << 4);
|
cs1.setOptions(0x1 << 4);
|
||||||
CString cs2 = new CString();
|
final CString cs2 = new CString();
|
||||||
cs2.setOptions(0x2 << 4);
|
cs2.setOptions(0x2 << 4);
|
||||||
CString cs3 = new CString();
|
final CString cs3 = new CString();
|
||||||
cs3.setOptions(0x3 << 4);
|
cs3.setOptions(0x3 << 4);
|
||||||
_children[0] = new ExEmbedAtom();
|
_children[0] = new ExEmbedAtom();
|
||||||
_children[1] = new ExOleObjAtom();
|
_children[1] = new ExOleObjAtom();
|
||||||
|
@ -117,8 +117,8 @@ public class ExEmbed extends RecordContainer {
|
||||||
|
|
||||||
for (int i = 2; i < _children.length; i++) {
|
for (int i = 2; i < _children.length; i++) {
|
||||||
if (_children[i] instanceof CString){
|
if (_children[i] instanceof CString){
|
||||||
CString cs = (CString)_children[i];
|
final CString cs = (CString)_children[i];
|
||||||
int opts = cs.getOptions() >> 4;
|
final int opts = cs.getOptions() >> 4;
|
||||||
switch(opts){
|
switch(opts){
|
||||||
case 0x1: menuName = cs; break;
|
case 0x1: menuName = cs; break;
|
||||||
case 0x2: progId = cs; break;
|
case 0x2: progId = cs; break;
|
||||||
|
@ -134,8 +134,7 @@ public class ExEmbed extends RecordContainer {
|
||||||
*
|
*
|
||||||
* @return the {@link ExEmbedAtom}.
|
* @return the {@link ExEmbedAtom}.
|
||||||
*/
|
*/
|
||||||
public ExEmbedAtom getExEmbedAtom()
|
public ExEmbedAtom getExEmbedAtom() {
|
||||||
{
|
|
||||||
return (ExEmbedAtom)embedAtom;
|
return (ExEmbedAtom)embedAtom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,8 +143,7 @@ public class ExEmbed extends RecordContainer {
|
||||||
*
|
*
|
||||||
* @return the {@link ExOleObjAtom}.
|
* @return the {@link ExOleObjAtom}.
|
||||||
*/
|
*/
|
||||||
public ExOleObjAtom getExOleObjAtom()
|
public ExOleObjAtom getExOleObjAtom() {
|
||||||
{
|
|
||||||
return oleObjAtom;
|
return oleObjAtom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,14 +152,13 @@ public class ExEmbed extends RecordContainer {
|
||||||
*
|
*
|
||||||
* @return the name used for menus and the Links dialog box.
|
* @return the name used for menus and the Links dialog box.
|
||||||
*/
|
*/
|
||||||
public String getMenuName()
|
public String getMenuName() {
|
||||||
{
|
|
||||||
return menuName == null ? null : menuName.getText();
|
return menuName == null ? null : menuName.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMenuName(String s)
|
public void setMenuName(final String menuName) {
|
||||||
{
|
this.menuName = safeCString(this.menuName, 0x1);
|
||||||
if(menuName != null) menuName.setText(s);
|
this.menuName.setText(menuName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -169,28 +166,29 @@ public class ExEmbed extends RecordContainer {
|
||||||
*
|
*
|
||||||
* @return the OLE Programmatic Identifier.
|
* @return the OLE Programmatic Identifier.
|
||||||
*/
|
*/
|
||||||
public String getProgId()
|
public String getProgId() {
|
||||||
{
|
|
||||||
return progId == null ? null : progId.getText();
|
return progId == null ? null : progId.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProgId(String s)
|
public void setProgId(final String progId) {
|
||||||
{
|
this.progId = safeCString(this.progId, 0x2);
|
||||||
if(progId != null) progId.setText(s);
|
this.progId.setText(progId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name that appears in the paste special dialog.
|
* Gets the name that appears in the paste special dialog.
|
||||||
*
|
*
|
||||||
* @return the name that appears in the paste special dialog.
|
* @return the name that appears in the paste special dialog.
|
||||||
*/
|
*/
|
||||||
public String getClipboardName()
|
public String getClipboardName() {
|
||||||
{
|
|
||||||
return clipboardName == null ? null : clipboardName.getText();
|
return clipboardName == null ? null : clipboardName.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClipboardName(String s)
|
public void setClipboardName(final String clipboardName) {
|
||||||
{
|
this.clipboardName = safeCString(this.clipboardName, 0x3);
|
||||||
if(clipboardName != null) clipboardName.setText(s);
|
this.clipboardName.setText(clipboardName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -199,6 +197,7 @@ public class ExEmbed extends RecordContainer {
|
||||||
*
|
*
|
||||||
* @return the record type.
|
* @return the record type.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public long getRecordType() {
|
public long getRecordType() {
|
||||||
return RecordTypes.ExEmbed.typeID;
|
return RecordTypes.ExEmbed.typeID;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +209,31 @@ public class ExEmbed extends RecordContainer {
|
||||||
* @param out the output stream.
|
* @param out the output stream.
|
||||||
* @throws IOException if there was an error writing to the stream.
|
* @throws IOException if there was an error writing to the stream.
|
||||||
*/
|
*/
|
||||||
public void writeOut(OutputStream out) throws IOException {
|
@Override
|
||||||
|
public void writeOut(final OutputStream out) throws IOException {
|
||||||
writeOut(_header[0],_header[1],getRecordType(),_children,out);
|
writeOut(_header[0],_header[1],getRecordType(),_children,out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CString safeCString(CString oldStr, int optionsId) {
|
||||||
|
CString newStr = oldStr;
|
||||||
|
if (newStr == null) {
|
||||||
|
newStr = new CString();
|
||||||
|
newStr.setOptions(optionsId << 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
|
for (final Record r : _children) {
|
||||||
|
// for simplicity just check for object identity
|
||||||
|
if (r == newStr) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
appendChildRecord(newStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newStr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,6 @@ import org.apache.poi.util.Units;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a group of shapes.
|
* Represents a group of shapes.
|
||||||
*
|
|
||||||
* @author Yegor Kozlov
|
|
||||||
*/
|
*/
|
||||||
public class HSLFGroupShape extends HSLFShape
|
public class HSLFGroupShape extends HSLFShape
|
||||||
implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
|
implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
|
||||||
|
@ -362,4 +360,15 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> {
|
||||||
addShape(s);
|
addShape(s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HSLFObjectShape createOleShape(PictureData pictureData) {
|
||||||
|
if (!(pictureData instanceof HSLFPictureData)) {
|
||||||
|
throw new IllegalArgumentException("pictureData needs to be of type HSLFPictureData");
|
||||||
|
}
|
||||||
|
HSLFObjectShape s = new HSLFObjectShape((HSLFPictureData)pictureData, this);
|
||||||
|
s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
|
||||||
|
addShape(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,17 +16,25 @@
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.hslf.usermodel;
|
package org.apache.poi.hslf.usermodel;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.apache.poi.hslf.record.ExOleObjStg;
|
import org.apache.poi.hslf.record.ExOleObjStg;
|
||||||
|
import org.apache.poi.poifs.filesystem.DirectoryEntry;
|
||||||
|
import org.apache.poi.poifs.filesystem.FileMagic;
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.sl.usermodel.ObjectData;
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that represents object data embedded in a slide show.
|
* A class that represents object data embedded in a slide show.
|
||||||
*
|
|
||||||
* @author Daniel Noll
|
|
||||||
*/
|
*/
|
||||||
public class HSLFObjectData {
|
public class HSLFObjectData implements ObjectData {
|
||||||
|
private static final POILogger LOG = POILogFactory.getLogger(HSLFObjectData.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The record that contains the object data.
|
* The record that contains the object data.
|
||||||
*/
|
*/
|
||||||
|
@ -41,14 +49,19 @@ public class HSLFObjectData {
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Gets an input stream which returns the binary of the embedded data.
|
public InputStream getInputStream() {
|
||||||
*
|
|
||||||
* @return the input stream which will contain the binary of the embedded data.
|
|
||||||
*/
|
|
||||||
public InputStream getData() {
|
|
||||||
return storage.getData();
|
return storage.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream getOutputStream() throws IOException {
|
||||||
|
return new ByteArrayOutputStream(100000) {
|
||||||
|
public void close() throws IOException {
|
||||||
|
setData(getBytes());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the embedded data.
|
* Sets the embedded data.
|
||||||
|
@ -67,4 +80,15 @@ public class HSLFObjectData {
|
||||||
public ExOleObjStg getExOleObjStg() {
|
public ExOleObjStg getExOleObjStg() {
|
||||||
return storage;
|
return storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOLE2ClassName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFileName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,12 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
package org.apache.poi.hslf.model;
|
package org.apache.poi.hslf.usermodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.apache.poi.ddf.EscherContainerRecord;
|
import org.apache.poi.ddf.EscherContainerRecord;
|
||||||
import org.apache.poi.ddf.EscherProperties;
|
import org.apache.poi.ddf.EscherProperties;
|
||||||
|
@ -26,22 +31,22 @@ import org.apache.poi.hslf.record.ExObjRefAtom;
|
||||||
import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
|
import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
|
||||||
import org.apache.poi.hslf.record.Record;
|
import org.apache.poi.hslf.record.Record;
|
||||||
import org.apache.poi.hslf.record.RecordTypes;
|
import org.apache.poi.hslf.record.RecordTypes;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFObjectData;
|
import org.apache.poi.poifs.filesystem.FileMagic;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFPictureData;
|
import org.apache.poi.poifs.filesystem.Ole10Native;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFPictureShape;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFShape;
|
import org.apache.poi.sl.usermodel.ObjectMetaData;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
import org.apache.poi.sl.usermodel.ObjectMetaData.Application;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
|
import org.apache.poi.sl.usermodel.ObjectShape;
|
||||||
import org.apache.poi.sl.usermodel.ShapeContainer;
|
import org.apache.poi.sl.usermodel.ShapeContainer;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A shape representing embedded OLE obejct.
|
* A shape representing embedded OLE object.
|
||||||
*/
|
*/
|
||||||
public final class OLEShape extends HSLFPictureShape {
|
public final class HSLFObjectShape extends HSLFPictureShape implements ObjectShape<HSLFShape,HSLFTextParagraph> {
|
||||||
private static final POILogger LOG = POILogFactory.getLogger(OLEShape.class);
|
private static final POILogger LOG = POILogFactory.getLogger(HSLFObjectShape.class);
|
||||||
|
|
||||||
private ExEmbed _exEmbed;
|
private ExEmbed _exEmbed;
|
||||||
|
|
||||||
|
@ -50,7 +55,7 @@ public final class OLEShape extends HSLFPictureShape {
|
||||||
*
|
*
|
||||||
* @param data the picture data
|
* @param data the picture data
|
||||||
*/
|
*/
|
||||||
public OLEShape(HSLFPictureData data){
|
public HSLFObjectShape(HSLFPictureData data){
|
||||||
super(data);
|
super(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +65,7 @@ public final class OLEShape extends HSLFPictureShape {
|
||||||
* @param data the picture data
|
* @param data the picture data
|
||||||
* @param parent the parent shape
|
* @param parent the parent shape
|
||||||
*/
|
*/
|
||||||
public OLEShape(HSLFPictureData data, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
|
public HSLFObjectShape(HSLFPictureData data, ShapeContainer<HSLFShape,HSLFTextParagraph> parent) {
|
||||||
super(data, parent);
|
super(data, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +76,7 @@ public final class OLEShape extends HSLFPictureShape {
|
||||||
* this picture in the <code>Slide</code>
|
* this picture in the <code>Slide</code>
|
||||||
* @param parent the parent shape of this picture
|
* @param parent the parent shape of this picture
|
||||||
*/
|
*/
|
||||||
public OLEShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
|
public HSLFObjectShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
|
||||||
super(escherRecord, parent);
|
super(escherRecord, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,12 +92,12 @@ public final class OLEShape extends HSLFPictureShape {
|
||||||
/**
|
/**
|
||||||
* Set the unique identifier for the OLE object and
|
* Set the unique identifier for the OLE object and
|
||||||
* register it in the necessary structures
|
* register it in the necessary structures
|
||||||
*
|
*
|
||||||
* @param objectId the unique identifier for the OLE object
|
* @param objectId the unique identifier for the OLE object
|
||||||
*/
|
*/
|
||||||
public void setObjectID(int objectId){
|
public void setObjectID(int objectId){
|
||||||
setEscherProperty(EscherProperties.BLIP__PICTUREID, objectId);
|
setEscherProperty(EscherProperties.BLIP__PICTUREID, objectId);
|
||||||
|
|
||||||
EscherContainerRecord ecr = getSpContainer();
|
EscherContainerRecord ecr = getSpContainer();
|
||||||
EscherSpRecord spRecord = ecr.getChildById(EscherSpRecord.RECORD_ID);
|
EscherSpRecord spRecord = ecr.getChildById(EscherSpRecord.RECORD_ID);
|
||||||
spRecord.setFlags(spRecord.getFlags()|EscherSpRecord.FLAG_OLESHAPE);
|
spRecord.setFlags(spRecord.getFlags()|EscherSpRecord.FLAG_OLESHAPE);
|
||||||
|
@ -111,14 +116,13 @@ public final class OLEShape extends HSLFPictureShape {
|
||||||
}
|
}
|
||||||
uer.setExObjIdRef(objectId);
|
uer.setExObjIdRef(objectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns unique identifier for the OLE object.
|
* Returns unique identifier for the OLE object.
|
||||||
*
|
*
|
||||||
* @return the unique identifier for the OLE object
|
* @return the unique identifier for the OLE object
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("resource")
|
|
||||||
public HSLFObjectData getObjectData(){
|
public HSLFObjectData getObjectData(){
|
||||||
HSLFSlideShow ppt = getSheet().getSlideShow();
|
HSLFSlideShow ppt = getSheet().getSlideShow();
|
||||||
HSLFObjectData[] ole = ppt.getEmbeddedObjects();
|
HSLFObjectData[] ole = ppt.getEmbeddedObjects();
|
||||||
|
@ -129,9 +133,10 @@ public final class OLEShape extends HSLFPictureShape {
|
||||||
if(exEmbed != null) {
|
if(exEmbed != null) {
|
||||||
int ref = exEmbed.getExOleObjAtom().getObjStgDataRef();
|
int ref = exEmbed.getExOleObjAtom().getObjStgDataRef();
|
||||||
|
|
||||||
for (int i = 0; i < ole.length; i++) {
|
for (HSLFObjectData hod : ole) {
|
||||||
if(ole[i].getExOleObjStg().getPersistId() == ref) {
|
if(hod.getExOleObjStg().getPersistId() == ref) {
|
||||||
data=ole[i];
|
data=hod;
|
||||||
|
// keep searching to return the last persistent object with that refId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,29 +161,40 @@ public final class OLEShape extends HSLFPictureShape {
|
||||||
* 6. MetaFile( 4033), optional
|
* 6. MetaFile( 4033), optional
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("resource")
|
|
||||||
public ExEmbed getExEmbed(){
|
public ExEmbed getExEmbed(){
|
||||||
if(_exEmbed == null){
|
return getExEmbed(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExEmbed getExEmbed(boolean create) {
|
||||||
|
if (_exEmbed == null) {
|
||||||
HSLFSlideShow ppt = getSheet().getSlideShow();
|
HSLFSlideShow ppt = getSheet().getSlideShow();
|
||||||
|
|
||||||
ExObjList lst = ppt.getDocumentRecord().getExObjList(false);
|
ExObjList lst = ppt.getDocumentRecord().getExObjList(create);
|
||||||
if(lst == null){
|
if(lst == null){
|
||||||
LOG.log(POILogger.WARN, "ExObjList not found");
|
LOG.log(POILogger.WARN, "ExObjList not found");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = getObjectID();
|
int id = getObjectID();
|
||||||
Record[] ch = lst.getChildRecords();
|
for (Record ch : lst.getChildRecords()) {
|
||||||
for (int i = 0; i < ch.length; i++) {
|
if(ch instanceof ExEmbed){
|
||||||
if(ch[i] instanceof ExEmbed){
|
ExEmbed embd = (ExEmbed)ch;
|
||||||
ExEmbed embd = (ExEmbed)ch[i];
|
if( embd.getExOleObjAtom().getObjID() == id) {
|
||||||
if( embd.getExOleObjAtom().getObjID() == id) _exEmbed = embd;
|
_exEmbed = embd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_exEmbed == null && create) {
|
||||||
|
_exEmbed = new ExEmbed();
|
||||||
|
_exEmbed.getExOleObjAtom().setObjID(id);
|
||||||
|
lst.appendChildRecord(_exEmbed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return _exEmbed;
|
return _exEmbed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the instance name of the embedded object, e.g. "Document" or "Workbook".
|
* Returns the instance name of the embedded object, e.g. "Document" or "Workbook".
|
||||||
*
|
*
|
||||||
|
@ -189,26 +205,63 @@ public final class OLEShape extends HSLFPictureShape {
|
||||||
return (ee == null) ? null : ee.getMenuName();
|
return (ee == null) ? null : ee.getMenuName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Returns the full name of the embedded object,
|
|
||||||
* e.g. "Microsoft Word Document" or "Microsoft Office Excel Worksheet".
|
|
||||||
*
|
|
||||||
* @return the full name of the embedded object
|
|
||||||
*/
|
|
||||||
public String getFullName(){
|
public String getFullName(){
|
||||||
ExEmbed ee = getExEmbed();
|
ExEmbed ee = getExEmbed();
|
||||||
return (ee == null) ? null : ee.getClipboardName();
|
return (ee == null) ? null : ee.getClipboardName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setFullName(final String fullName) {
|
||||||
* Returns the ProgID that stores the OLE Programmatic Identifier.
|
getExEmbed(true).setClipboardName(fullName);
|
||||||
* A ProgID is a string that uniquely identifies a given object, for example,
|
}
|
||||||
* "Word.Document.8" or "Excel.Sheet.8".
|
|
||||||
*
|
@Override
|
||||||
* @return the ProgID
|
public String getProgId(){
|
||||||
*/
|
|
||||||
public String getProgID(){
|
|
||||||
ExEmbed ee = getExEmbed();
|
ExEmbed ee = getExEmbed();
|
||||||
return (ee == null) ? null : ee.getProgId();
|
return (ee == null) ? null : ee.getProgId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProgId(final String progId) {
|
||||||
|
getExEmbed(true).setProgId(progId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OutputStream updateObjectData(final Application application, final ObjectMetaData metaData) throws IOException {
|
||||||
|
final ObjectMetaData md = (application != null) ? application.getMetaData() : metaData;
|
||||||
|
if (md == null) {
|
||||||
|
throw new RuntimeException("either application or metaData needs to be set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ByteArrayOutputStream(100000) {
|
||||||
|
public void close() throws IOException {
|
||||||
|
final FileMagic fm = FileMagic.valueOf(this.buf);
|
||||||
|
final ByteArrayInputStream bis = new ByteArrayInputStream(this.buf, 0, this.count);
|
||||||
|
final HSLFSlideShow ppt = getSheet().getSlideShow();
|
||||||
|
|
||||||
|
try (POIFSFileSystem poifs = (fm == FileMagic.OLE2) ? new POIFSFileSystem(bis) : new POIFSFileSystem()) {
|
||||||
|
if (fm != FileMagic.OLE2) {
|
||||||
|
poifs.createDocument(bis, md.getOleEntry());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ole10Native.createOleMarkerEntry(poifs);
|
||||||
|
|
||||||
|
poifs.getRoot().setStorageClsid(md.getClassID());
|
||||||
|
|
||||||
|
|
||||||
|
int oid = getObjectID();
|
||||||
|
if (oid == 0) {
|
||||||
|
// assign new embedding
|
||||||
|
oid = ppt.addEmbed(poifs);
|
||||||
|
setObjectID(oid);
|
||||||
|
} else {
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream(this.size()+1000);
|
||||||
|
poifs.writeFilesystem(bos);
|
||||||
|
getObjectData().setData(bos.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
setProgId(md.getProgId());
|
||||||
|
setFullName(md.getObjectName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -45,5 +45,6 @@ public interface HSLFShapeContainer extends ShapeContainer<HSLFShape,HSLFTextPar
|
||||||
@Override
|
@Override
|
||||||
HSLFPictureShape createPicture(PictureData pictureData);
|
HSLFPictureShape createPicture(PictureData pictureData);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
HSLFObjectShape createOleShape(PictureData pictureData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.apache.poi.ddf.EscherSimpleProperty;
|
||||||
import org.apache.poi.ddf.EscherSpRecord;
|
import org.apache.poi.ddf.EscherSpRecord;
|
||||||
import org.apache.poi.ddf.EscherTextboxRecord;
|
import org.apache.poi.ddf.EscherTextboxRecord;
|
||||||
import org.apache.poi.hslf.model.MovieShape;
|
import org.apache.poi.hslf.model.MovieShape;
|
||||||
import org.apache.poi.hslf.model.OLEShape;
|
|
||||||
import org.apache.poi.hslf.record.ExObjRefAtom;
|
import org.apache.poi.hslf.record.ExObjRefAtom;
|
||||||
import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
|
import org.apache.poi.hslf.record.HSLFEscherClientDataRecord;
|
||||||
import org.apache.poi.hslf.record.InteractiveInfo;
|
import org.apache.poi.hslf.record.InteractiveInfo;
|
||||||
|
@ -134,7 +133,7 @@ public final class HSLFShapeFactory {
|
||||||
if(info != null && info.getInteractiveInfoAtom() != null){
|
if(info != null && info.getInteractiveInfoAtom() != null){
|
||||||
switch(info.getInteractiveInfoAtom().getAction()){
|
switch(info.getInteractiveInfoAtom().getAction()){
|
||||||
case InteractiveInfoAtom.ACTION_OLE:
|
case InteractiveInfoAtom.ACTION_OLE:
|
||||||
return new OLEShape(spContainer, parent);
|
return new HSLFObjectShape(spContainer, parent);
|
||||||
case InteractiveInfoAtom.ACTION_MEDIA:
|
case InteractiveInfoAtom.ACTION_MEDIA:
|
||||||
return new MovieShape(spContainer, parent);
|
return new MovieShape(spContainer, parent);
|
||||||
default:
|
default:
|
||||||
|
@ -144,7 +143,7 @@ public final class HSLFShapeFactory {
|
||||||
|
|
||||||
ExObjRefAtom oes = getClientDataRecord(spContainer, RecordTypes.ExObjRefAtom.typeID);
|
ExObjRefAtom oes = getClientDataRecord(spContainer, RecordTypes.ExObjRefAtom.typeID);
|
||||||
return (oes != null)
|
return (oes != null)
|
||||||
? new OLEShape(spContainer, parent)
|
? new HSLFObjectShape(spContainer, parent)
|
||||||
: new HSLFPictureShape(spContainer, parent);
|
: new HSLFPictureShape(spContainer, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -442,4 +442,15 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
|
||||||
addShape(s);
|
addShape(s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HSLFObjectShape createOleShape(PictureData pictureData) {
|
||||||
|
if (!(pictureData instanceof HSLFPictureData)) {
|
||||||
|
throw new IllegalArgumentException("pictureData needs to be of type HSLFPictureData");
|
||||||
|
}
|
||||||
|
HSLFObjectShape s = new HSLFObjectShape((HSLFPictureData)pictureData);
|
||||||
|
s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
|
||||||
|
addShape(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,9 @@ import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.POIDataSamples;
|
import org.apache.poi.POIDataSamples;
|
||||||
import org.apache.poi.hslf.model.OLEShape;
|
|
||||||
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
|
import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
|
||||||
|
import org.apache.poi.hslf.usermodel.HSLFObjectShape;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.hwpf.HWPFDocument;
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
|
@ -206,12 +206,12 @@ public final class TestExtractor {
|
||||||
@Test
|
@Test
|
||||||
public void testExtractFromOwnEmbeded() throws IOException {
|
public void testExtractFromOwnEmbeded() throws IOException {
|
||||||
PowerPointExtractor ppe = openExtractor("ppt_with_embeded.ppt");
|
PowerPointExtractor ppe = openExtractor("ppt_with_embeded.ppt");
|
||||||
List<OLEShape> shapes = ppe.getOLEShapes();
|
List<HSLFObjectShape> shapes = ppe.getOLEShapes();
|
||||||
assertEquals("Expected 6 ole shapes", 6, shapes.size());
|
assertEquals("Expected 6 ole shapes", 6, shapes.size());
|
||||||
int num_ppt = 0, num_doc = 0, num_xls = 0;
|
int num_ppt = 0, num_doc = 0, num_xls = 0;
|
||||||
for (OLEShape ole : shapes) {
|
for (HSLFObjectShape ole : shapes) {
|
||||||
String name = ole.getInstanceName();
|
String name = ole.getInstanceName();
|
||||||
InputStream data = ole.getObjectData().getData();
|
InputStream data = ole.getObjectData().getInputStream();
|
||||||
if ("Worksheet".equals(name)) {
|
if ("Worksheet".equals(name)) {
|
||||||
HSSFWorkbook wb = new HSSFWorkbook(data);
|
HSSFWorkbook wb = new HSSFWorkbook(data);
|
||||||
num_xls++;
|
num_xls++;
|
||||||
|
@ -239,8 +239,8 @@ public final class TestExtractor {
|
||||||
@Test
|
@Test
|
||||||
public void test52991() throws IOException {
|
public void test52991() throws IOException {
|
||||||
PowerPointExtractor ppe = openExtractor("badzip.ppt");
|
PowerPointExtractor ppe = openExtractor("badzip.ppt");
|
||||||
for (OLEShape shape : ppe.getOLEShapes()) {
|
for (HSLFObjectShape shape : ppe.getOLEShapes()) {
|
||||||
IOUtils.copy(shape.getObjectData().getData(), new ByteArrayOutputStream());
|
IOUtils.copy(shape.getObjectData().getInputStream(), new ByteArrayOutputStream());
|
||||||
}
|
}
|
||||||
ppe.close();
|
ppe.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.poi.hslf.usermodel.HSLFShape;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFSlide;
|
import org.apache.poi.hslf.usermodel.HSLFSlide;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
||||||
import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
|
import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
|
||||||
|
import org.apache.poi.hslf.usermodel.HSLFObjectShape;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.hwpf.HWPFDocument;
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
|
@ -70,7 +71,7 @@ public final class TestOleEmbedding {
|
||||||
HSLFObjectData[] objects = slideShow.getEmbeddedObjects();
|
HSLFObjectData[] objects = slideShow.getEmbeddedObjects();
|
||||||
assertEquals("Should be two objects", 2, objects.length);
|
assertEquals("Should be two objects", 2, objects.length);
|
||||||
for (HSLFObjectData od : objects) {
|
for (HSLFObjectData od : objects) {
|
||||||
long checkEMF = IOUtils.calculateChecksum(od.getData());
|
long checkEMF = IOUtils.calculateChecksum(od.getInputStream());
|
||||||
assertEquals(checkSums[checkId++], checkEMF);
|
assertEquals(checkSums[checkId++], checkEMF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,13 +87,13 @@ public final class TestOleEmbedding {
|
||||||
HSLFSlide slide = ppt.getSlides().get(0);
|
HSLFSlide slide = ppt.getSlides().get(0);
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (HSLFShape sh : slide.getShapes()) {
|
for (HSLFShape sh : slide.getShapes()) {
|
||||||
if(sh instanceof OLEShape){
|
if(sh instanceof HSLFObjectShape){
|
||||||
cnt++;
|
cnt++;
|
||||||
OLEShape ole = (OLEShape)sh;
|
HSLFObjectShape ole = (HSLFObjectShape)sh;
|
||||||
HSLFObjectData data = ole.getObjectData();
|
HSLFObjectData data = ole.getObjectData();
|
||||||
if("Worksheet".equals(ole.getInstanceName())){
|
if("Worksheet".equals(ole.getInstanceName())){
|
||||||
//Voila! we created a workbook from the embedded OLE data
|
//Voila! we created a workbook from the embedded OLE data
|
||||||
HSSFWorkbook wb = new HSSFWorkbook(data.getData());
|
HSSFWorkbook wb = new HSSFWorkbook(data.getInputStream());
|
||||||
HSSFSheet sheet = wb.getSheetAt(0);
|
HSSFSheet sheet = wb.getSheetAt(0);
|
||||||
//verify we can access the xls data
|
//verify we can access the xls data
|
||||||
assertEquals(1, sheet.getRow(0).getCell(0).getNumericCellValue(), 0);
|
assertEquals(1, sheet.getRow(0).getCell(0).getNumericCellValue(), 0);
|
||||||
|
@ -103,7 +104,7 @@ public final class TestOleEmbedding {
|
||||||
wb.close();
|
wb.close();
|
||||||
} else if ("Document".equals(ole.getInstanceName())){
|
} else if ("Document".equals(ole.getInstanceName())){
|
||||||
//creating a HWPF document
|
//creating a HWPF document
|
||||||
HWPFDocument doc = new HWPFDocument(data.getData());
|
HWPFDocument doc = new HWPFDocument(data.getInputStream());
|
||||||
String txt = doc.getRange().getParagraph(0).text();
|
String txt = doc.getRange().getParagraph(0).text();
|
||||||
assertEquals("OLE embedding is thoroughly unremarkable.\r", txt);
|
assertEquals("OLE embedding is thoroughly unremarkable.\r", txt);
|
||||||
doc.close();
|
doc.close();
|
||||||
|
@ -129,14 +130,14 @@ public final class TestOleEmbedding {
|
||||||
int oleObjectId1 = ppt.addEmbed(poiData1);
|
int oleObjectId1 = ppt.addEmbed(poiData1);
|
||||||
|
|
||||||
HSLFSlide slide1 = ppt.createSlide();
|
HSLFSlide slide1 = ppt.createSlide();
|
||||||
OLEShape oleShape1 = new OLEShape(pictData);
|
HSLFObjectShape oleShape1 = new HSLFObjectShape(pictData);
|
||||||
oleShape1.setObjectID(oleObjectId1);
|
oleShape1.setObjectID(oleObjectId1);
|
||||||
slide1.addShape(oleShape1);
|
slide1.addShape(oleShape1);
|
||||||
oleShape1.setAnchor(new Rectangle2D.Double(100,100,100,100));
|
oleShape1.setAnchor(new Rectangle2D.Double(100,100,100,100));
|
||||||
|
|
||||||
// add second slide with different order in object creation
|
// add second slide with different order in object creation
|
||||||
HSLFSlide slide2 = ppt.createSlide();
|
HSLFSlide slide2 = ppt.createSlide();
|
||||||
OLEShape oleShape2 = new OLEShape(pictData);
|
HSLFObjectShape oleShape2 = new HSLFObjectShape(pictData);
|
||||||
|
|
||||||
is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleWithImages.xls");
|
is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleWithImages.xls");
|
||||||
POIFSFileSystem poiData2 = new POIFSFileSystem(is);
|
POIFSFileSystem poiData2 = new POIFSFileSystem(is);
|
||||||
|
@ -152,8 +153,8 @@ public final class TestOleEmbedding {
|
||||||
ppt.write(bos);
|
ppt.write(bos);
|
||||||
|
|
||||||
ppt = new HSLFSlideShow(new ByteArrayInputStream(bos.toByteArray()));
|
ppt = new HSLFSlideShow(new ByteArrayInputStream(bos.toByteArray()));
|
||||||
OLEShape comp = (OLEShape)ppt.getSlides().get(0).getShapes().get(0);
|
HSLFObjectShape comp = (HSLFObjectShape)ppt.getSlides().get(0).getShapes().get(0);
|
||||||
byte compData[] = IOUtils.toByteArray(comp.getObjectData().getData());
|
byte compData[] = IOUtils.toByteArray(comp.getObjectData().getInputStream());
|
||||||
|
|
||||||
bos.reset();
|
bos.reset();
|
||||||
poiData1.writeFilesystem(bos);
|
poiData1.writeFilesystem(bos);
|
||||||
|
|
|
@ -1010,7 +1010,7 @@ public final class TestBugs {
|
||||||
long persistId = vbaAtom.getPersistIdRef();
|
long persistId = vbaAtom.getPersistIdRef();
|
||||||
for (HSLFObjectData objData : ppt.getEmbeddedObjects()) {
|
for (HSLFObjectData objData : ppt.getEmbeddedObjects()) {
|
||||||
if (objData.getExOleObjStg().getPersistId() == persistId) {
|
if (objData.getExOleObjStg().getPersistId() == persistId) {
|
||||||
VBAMacroReader mr = new VBAMacroReader(objData.getData());
|
VBAMacroReader mr = new VBAMacroReader(objData.getInputStream());
|
||||||
try {
|
try {
|
||||||
return mr.readMacros();
|
return mr.readMacros();
|
||||||
} finally {
|
} finally {
|
||||||
|
|
Loading…
Reference in New Issue