You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2017/01/15 02:04:58 UTC

svn commit: r1778869 - in /poi: site/src/documentation/content/xdocs/ trunk/src/java/org/apache/poi/hssf/usermodel/ trunk/src/java/org/apache/poi/ss/usermodel/ trunk/src/ooxml/java/org/apache/poi/xssf/streaming/ trunk/src/ooxml/java/org/apache/poi/xssf...

Author: kiwiwings
Date: Sun Jan 15 02:04:57 2017
New Revision: 1778869

URL: http://svn.apache.org/viewvc?rev=1778869&view=rev
Log:
#60586 - Support embedding OLE1.0 package in XSSF / SS Common

Added:
    poi/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java   (with props)
Modified:
    poi/site/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
    poi/trunk/src/java/org/apache/poi/ss/usermodel/Drawing.java
    poi/trunk/src/java/org/apache/poi/ss/usermodel/Workbook.java
    poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java
    poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
    poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java
    poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFObjectData.java
    poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java

Modified: poi/site/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/status.xml?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/site/src/documentation/content/xdocs/status.xml (original)
+++ poi/site/src/documentation/content/xdocs/status.xml Sun Jan 15 02:04:57 2017
@@ -61,6 +61,7 @@
         <summary-item>The third-party jar for commons-collections4 is now required for handling of OLE2 properties</summary-item>
       </summary>
       <actions>
+        <action dev="PD" type="add" fixes-bug="60586" module="SS Common,XSSF">Support embedding OLE1.0 package in XSSF / SS Common</action>
         <action dev="PD" type="add" fixes-bug="60260" module="SS Common">Partial support for unicode sheet names</action>
         <action dev="PD" type="add" fixes-bug="60550" module="HSMF">Parse Content-ID for inline images in MAPIMessages</action>
         <action dev="PD" type="fix" fixes-bug="60498" module="XSSF">Fix performance problem with XPath parsing in XSSF import from XML</action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java Sun Jan 15 02:04:57 2017
@@ -48,6 +48,7 @@ import org.apache.poi.poifs.filesystem.D
 import org.apache.poi.ss.usermodel.Chart;
 import org.apache.poi.ss.usermodel.ClientAnchor;
 import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.NotImplemented;
@@ -137,6 +138,7 @@ public final class HSSFPatriarch impleme
      * @param shape to be removed
      * @return true of shape is removed
      */
+    @Override
     public boolean removeShape(HSSFShape shape) {
         boolean  isRemoved = _mainSpgrContainer.removeChildRecord(shape.getEscherContainer());
         if (isRemoved){
@@ -214,22 +216,13 @@ public final class HSSFPatriarch impleme
      *
      * @return newly created shape
      */
+    @Override
     public HSSFPicture createPicture(ClientAnchor anchor, int pictureIndex) {
         return createPicture((HSSFClientAnchor) anchor, pictureIndex);
     }
 
-    /**
-     * Adds a new OLE Package Shape 
-     * 
-     * @param anchor       the client anchor describes how this picture is
-     *                     attached to the sheet.
-     * @param storageId    the storageId returned by {@link HSSFWorkbook#addOlePackage(POIFSFileSystem,String,String,String)}
-     * @param pictureIndex the index of the picture (used as preview image) in the
-     *                     workbook collection of pictures.
-     *
-     * @return newly created shape
-     */
-    public HSSFObjectData createObjectData(HSSFClientAnchor anchor, int storageId, int pictureIndex) {
+    @Override
+    public HSSFObjectData createObjectData(ClientAnchor anchor, int storageId, int pictureIndex) {
         ObjRecord obj = new ObjRecord();
 
         CommonObjectDataSubRecord ftCmo = new CommonObjectDataSubRecord();
@@ -248,15 +241,15 @@ public final class HSSFPatriarch impleme
         FtCfSubRecord ftCf = new FtCfSubRecord();
         HSSFPictureData pictData = getSheet().getWorkbook().getAllPictures().get(pictureIndex-1);
         switch (pictData.getFormat()) {
-	        case HSSFWorkbook.PICTURE_TYPE_WMF:
-	        case HSSFWorkbook.PICTURE_TYPE_EMF:
+	        case Workbook.PICTURE_TYPE_WMF:
+	        case Workbook.PICTURE_TYPE_EMF:
 	        	// this needs patch #49658 to be applied to actually work 
 	            ftCf.setFlags(FtCfSubRecord.METAFILE_BIT);
 	            break;
-	        case HSSFWorkbook.PICTURE_TYPE_DIB:
-	        case HSSFWorkbook.PICTURE_TYPE_PNG:
-	        case HSSFWorkbook.PICTURE_TYPE_JPEG:
-	        case HSSFWorkbook.PICTURE_TYPE_PICT:
+	        case Workbook.PICTURE_TYPE_DIB:
+	        case Workbook.PICTURE_TYPE_PNG:
+	        case Workbook.PICTURE_TYPE_JPEG:
+	        case Workbook.PICTURE_TYPE_PICT:
 	            ftCf.setFlags(FtCfSubRecord.BITMAP_BIT);
 	            break;
 	        default:
@@ -280,14 +273,16 @@ public final class HSSFPatriarch impleme
         DirectoryEntry oleRoot;
         try {
             DirectoryNode dn = _sheet.getWorkbook().getDirectory();
-        	if (dn == null) throw new FileNotFoundException();
+        	if (dn == null) {
+                throw new FileNotFoundException();
+            }
         	oleRoot = (DirectoryEntry)dn.getEntry(entryName);
         } catch (FileNotFoundException e) {
         	throw new IllegalStateException("trying to add ole shape without actually adding data first - use HSSFWorkbook.addOlePackage first", e);
         }
         
         // create picture shape, which need to be minimal modified for oleshapes
-        HSSFPicture shape = new HSSFPicture(null, anchor);
+        HSSFPicture shape = new HSSFPicture(null, (HSSFClientAnchor)anchor);
         shape.setPictureIndex(pictureIndex);
         EscherContainerRecord spContainer = shape.getEscherContainer();
         EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
@@ -355,6 +350,7 @@ public final class HSSFPatriarch impleme
         return shape;
     }
 
+    @Override
     public HSSFComment createCellComment(ClientAnchor anchor) {
         return createComment((HSSFAnchor) anchor);
     }
@@ -362,6 +358,7 @@ public final class HSSFPatriarch impleme
     /**
      * Returns a unmodifiable list of all shapes contained by the patriarch.
      */
+    @Override
     public List<HSSFShape> getChildren() {
         return Collections.unmodifiableList(_shapes);
     }
@@ -369,6 +366,7 @@ public final class HSSFPatriarch impleme
     /**
      * add a shape to this drawing
      */
+    @Override
     @Internal
     public void addShape(HSSFShape shape) {
         shape.setPatriarch(this);
@@ -405,6 +403,7 @@ public final class HSSFPatriarch impleme
      * Sets the coordinate space of this group.  All children are constrained
      * to these coordinates.
      */
+    @Override
     public void setCoordinates(int x1, int y1, int x2, int y2) {
         _spgrRecord.setRectY1(y1);
         _spgrRecord.setRectY2(y2);
@@ -415,6 +414,7 @@ public final class HSSFPatriarch impleme
     /**
      * remove all shapes inside patriarch
      */
+    @Override
     public void clear() {
         ArrayList <HSSFShape> copy = new ArrayList<HSSFShape>(_shapes);
         for (HSSFShape shape: copy){
@@ -469,6 +469,7 @@ public final class HSSFPatriarch impleme
     /**
      * @return x coordinate of the left up corner
      */
+    @Override
     public int getX1() {
         return _spgrRecord.getRectX1();
     }
@@ -476,6 +477,7 @@ public final class HSSFPatriarch impleme
     /**
      * @return y coordinate of the left up corner
      */
+    @Override
     public int getY1() {
         return _spgrRecord.getRectY1();
     }
@@ -483,6 +485,7 @@ public final class HSSFPatriarch impleme
     /**
      * @return x coordinate of the right down corner
      */
+    @Override
     public int getX2() {
         return _spgrRecord.getRectX2();
     }
@@ -490,6 +493,7 @@ public final class HSSFPatriarch impleme
     /**
      * @return y coordinate of the right down corner
      */
+    @Override
     public int getY2() {
         return _spgrRecord.getRectY2();
     }
@@ -517,10 +521,12 @@ public final class HSSFPatriarch impleme
      * @param row2 the row (0 based) of the second cell.
      * @return the newly created client anchor
      */
+    @Override
     public HSSFClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) {
         return new HSSFClientAnchor(dx1, dy1, dx2, dy2, (short) col1, row1, (short) col2, row2);
     }
 
+    @Override
     @NotImplemented
     public Chart createChart(ClientAnchor anchor) {
         throw new RuntimeException("NotImplemented");

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Sun Jan 15 02:04:57 2017
@@ -2048,6 +2048,16 @@ public final class HSSFWorkbook extends
     	return olemap;
     }
 
+    /**
+     * Adds an OLE package manager object with the given POIFS to the sheet
+     *
+     * @param poiData an POIFS containing the embedded document, to be added
+     * @param label the label of the payload
+     * @param fileName the original filename
+     * @param command the command to open the payload
+     * @return the index of the added ole object
+     * @throws IOException if the object can't be embedded
+     */
     public int addOlePackage(POIFSFileSystem poiData, String label, String fileName, String command)
     throws IOException {
     	DirectoryNode root = poiData.getRoot();
@@ -2064,6 +2074,7 @@ public final class HSSFWorkbook extends
         return addOlePackage(bos.toByteArray(), label, fileName, command);
     }
 
+    @Override
     public int addOlePackage(byte[] oleData, String label, String fileName, String command)
     throws IOException {
     	// check if we were created by POIFS otherwise create a new dummy POIFS for storing the package data

Modified: poi/trunk/src/java/org/apache/poi/ss/usermodel/Drawing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/usermodel/Drawing.java?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/usermodel/Drawing.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/usermodel/Drawing.java Sun Jan 15 02:04:57 2017
@@ -62,4 +62,17 @@ public interface Drawing<T extends Shape
 	 * @return the newly created client anchor
 	 */
 	ClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2);
+	
+    /**
+     * Adds a new OLE Package Shape 
+     * 
+     * @param anchor       the client anchor describes how this picture is
+     *                     attached to the sheet.
+     * @param storageId    the storageId returned by {@link Workbook#addOlePackage(byte[], String, String, String)}
+     * @param pictureIndex the index of the picture (used as preview image) in the
+     *                     workbook collection of pictures.
+     *
+     * @return newly created shape
+     */
+    ObjectData createObjectData(ClientAnchor anchor, int storageId, int pictureIndex);
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/usermodel/Workbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/usermodel/Workbook.java?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/usermodel/Workbook.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/usermodel/Workbook.java Sun Jan 15 02:04:57 2017
@@ -286,6 +286,7 @@ public interface Workbook extends Closea
      * @return the font with the matched attributes or <code>null</code>
      * @deprecated POI 3.15 beta 2. Use {@link #findFont(boolean, short, short, String, boolean, boolean, short, byte)} instead.
      */
+    @Deprecated
     Font findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline);
     
     /**
@@ -635,4 +636,18 @@ public interface Workbook extends Closea
      * @since 3.14 beta 2
      */
     SpreadsheetVersion getSpreadsheetVersion();
+
+    /**
+     * Adds an OLE package manager object with the given content to the sheet
+     *
+     * @param oleData the payload
+     * @param label the label of the payload
+     * @param fileName the original filename
+     * @param command the command to open the payload
+     * 
+     * @return the index of the added ole object, i.e. the storage id
+     * 
+     * @throws IOException if the object can't be embedded
+     */
+    int addOlePackage(byte[] oleData, String label, String fileName, String command) throws IOException;
 }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFDrawing.java Sun Jan 15 02:04:57 2017
@@ -23,6 +23,7 @@ import org.apache.poi.ss.usermodel.Chart
 import org.apache.poi.ss.usermodel.ClientAnchor;
 import org.apache.poi.ss.usermodel.Comment;
 import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.ObjectData;
 import org.apache.poi.xssf.usermodel.XSSFDrawing;
 import org.apache.poi.xssf.usermodel.XSSFPicture;
 import org.apache.poi.xssf.usermodel.XSSFShape;
@@ -63,8 +64,14 @@ public class SXSSFDrawing implements Dra
     }
 
     @Override
+    public ObjectData createObjectData(ClientAnchor anchor, int storageId, int pictureIndex) {
+        return _drawing.createObjectData(anchor, storageId, pictureIndex);
+    }
+
+    @Override
     public Iterator<XSSFShape> iterator() {
         return _drawing.getShapes().iterator();
     }
+    
 }
 

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java Sun Jan 15 02:04:57 2017
@@ -1391,5 +1391,10 @@ public class SXSSFWorkbook implements Wo
         return SpreadsheetVersion.EXCEL2007;
     }
 
+    @Override
+    public int addOlePackage(byte[] oleData, String label, String fileName, String command) throws IOException {
+        return _wb.addOlePackage(oleData, label, fileName, command);
+    }
+    
 //end of interface implementation
 }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java Sun Jan 15 02:04:57 2017
@@ -28,9 +28,16 @@ import java.util.List;
 
 import javax.xml.namespace.QName;
 
+import org.apache.poi.POIXMLDocument;
 import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 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.PackageRelationshipTypes;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.ss.usermodel.ClientAnchor;
 import org.apache.poi.ss.usermodel.Drawing;
 import org.apache.poi.ss.util.CellAddress;
@@ -45,7 +52,9 @@ import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
 import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
+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.CTTransform2D;
@@ -59,19 +68,22 @@ import org.openxmlformats.schemas.drawin
 import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
 import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
 import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOleObject;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOleObjects;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
 
 /**
  * Represents a SpreadsheetML drawing
  */
 public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing<XSSFShape> {
     private static final POILogger LOG = POILogFactory.getLogger(XSSFDrawing.class);
-    
+
     /**
      * Root element of the SpreadsheetML Drawing part
      */
     private CTDrawing drawing;
     private long numOfGraphicFrames = 0L;
-    
+
     protected static final String NAMESPACE_A = XSSFRelation.NS_DRAWINGML;
     protected static final String NAMESPACE_C = XSSFRelation.NS_CHART;
 
@@ -90,7 +102,7 @@ public final class XSSFDrawing extends P
      *
      * @param part the package part holding the drawing data,
      * the content type must be <code>application/vnd.openxmlformats-officedocument.drawing+xml</code>
-     * 
+     *
      * @since POI 3.14-Beta1
      */
     public XSSFDrawing(PackagePart part) throws IOException, XmlException {
@@ -105,7 +117,7 @@ public final class XSSFDrawing extends P
             is.close();
         }
     }
-    
+
     /**
      * Construct a new CTDrawing bean. By default, it's just an empty placeholder for drawing objects
      *
@@ -194,7 +206,7 @@ public final class XSSFDrawing extends P
         shape.anchor = anchor;
         shape.setPictureReference(rel);
         ctShape.getSpPr().setXfrm(createXfrm(anchor));
-        
+
         return shape;
     }
 
@@ -319,7 +331,7 @@ public final class XSSFDrawing extends P
     @Override
     public XSSFComment createCellComment(ClientAnchor anchor) {
         XSSFClientAnchor ca = (XSSFClientAnchor)anchor;
-        XSSFSheet sheet = (XSSFSheet)getParent();
+        XSSFSheet sheet = getSheet();
 
         //create comments and vmlDrawing parts if they don't exist
         CommentsTable comments = sheet.getCommentsTable(true);
@@ -344,7 +356,7 @@ public final class XSSFDrawing extends P
         if(comments.findCellComment(ref) != null) {
             throw new IllegalArgumentException("Multiple cell comments in one cell are not allowed, cell: " + ref);
         }
-        
+
         return new XSSFComment(comments, comments.newComment(ref), vmlShape);
     }
 
@@ -368,7 +380,85 @@ public final class XSSFDrawing extends P
         graphicFrame.setName("Diagramm" + frameId);
         return graphicFrame;
     }
-    
+
+    @Override
+    public XSSFObjectData createObjectData(ClientAnchor anchor, int storageId, int pictureIndex) {
+        XSSFSheet sh = getSheet();
+        PackagePart sheetPart = sh.getPackagePart();
+        long shapeId = newShapeId();
+
+        // add reference to OLE part
+        PackagePartName olePN;
+        try {
+            olePN = PackagingURIHelper.createPartName( "/xl/embeddings/oleObject"+storageId+".bin" );
+        } catch (InvalidFormatException e) {
+            throw new POIXMLException(e);
+        }
+        PackageRelationship olePR = sheetPart.addRelationship( olePN, TargetMode.INTERNAL, POIXMLDocument.OLE_OBJECT_REL_TYPE );
+
+        // add reference to image part
+        XSSFPictureData imgPD = sh.getWorkbook().getAllPictures().get(pictureIndex);
+        PackagePartName imgPN = imgPD.getPackagePart().getPartName();
+        PackageRelationship imgSheetPR = sheetPart.addRelationship( imgPN, TargetMode.INTERNAL, PackageRelationshipTypes.IMAGE_PART );
+        PackageRelationship imgDrawPR = getPackagePart().addRelationship( imgPN, TargetMode.INTERNAL, PackageRelationshipTypes.IMAGE_PART );
+
+
+        // add OLE part metadata to sheet
+        CTWorksheet cwb = sh.getCTWorksheet();
+        CTOleObjects oo = cwb.isSetOleObjects() ? cwb.getOleObjects() : cwb.addNewOleObjects();
+
+        CTOleObject ole1 = oo.addNewOleObject();
+        ole1.setProgId("Package");
+        ole1.setShapeId(shapeId);
+        ole1.setId(olePR.getId());
+
+        XmlCursor cur1 = ole1.newCursor();
+        cur1.toEndToken();
+        cur1.beginElement("objectPr", XSSFRelation.NS_SPREADSHEETML);
+        cur1.insertAttributeWithValue("id", PackageRelationshipTypes.CORE_PROPERTIES_ECMA376_NS, imgSheetPR.getId());
+        cur1.insertAttributeWithValue("defaultSize", "0");
+        cur1.beginElement("anchor", XSSFRelation.NS_SPREADSHEETML);
+        cur1.insertAttributeWithValue("moveWithCells", "1");
+
+        CTTwoCellAnchor ctAnchor = createTwoCellAnchor((XSSFClientAnchor)anchor);
+        
+        XmlCursor cur2 = ctAnchor.newCursor();
+        cur2.copyXmlContents(cur1);
+        cur2.dispose();
+
+        cur1.toParent();
+        cur1.toFirstChild();
+        cur1.setName(new QName(XSSFRelation.NS_SPREADSHEETML, "from"));
+        cur1.toNextSibling();
+        cur1.setName(new QName(XSSFRelation.NS_SPREADSHEETML, "to"));
+
+        cur1.dispose();
+
+        // add a new shape and link OLE & image part
+        CTShape ctShape = ctAnchor.addNewSp();
+        ctShape.set(XSSFObjectData.prototype());
+        ctShape.getSpPr().setXfrm(createXfrm((XSSFClientAnchor)anchor));
+        
+        // workaround for not having the vmlDrawing filled
+        CTBlipFillProperties blipFill = ctShape.getSpPr().addNewBlipFill();
+        blipFill.addNewBlip().setEmbed(imgDrawPR.getId());
+        blipFill.addNewStretch().addNewFillRect();
+        
+        CTNonVisualDrawingProps cNvPr = ctShape.getNvSpPr().getCNvPr();
+        cNvPr.setId(shapeId);
+
+        XmlCursor extCur = cNvPr.getExtLst().getExtArray(0).newCursor();
+        extCur.toFirstChild();
+        extCur.setAttributeText(new QName("spid"), "_x0000_s"+shapeId);
+        extCur.dispose();
+
+        XSSFObjectData shape = new XSSFObjectData(this, ctShape);
+        shape.anchor = (XSSFClientAnchor)anchor;
+
+        return shape;
+    }
+
+
     /**
      * Returns all charts in this drawing.
      */
@@ -410,7 +500,7 @@ public final class XSSFDrawing extends P
         CTPoint2D off = xfrm.addNewOff();
         off.setX(anchor.getDx1());
         off.setY(anchor.getDy1());
-        XSSFSheet sheet = (XSSFSheet)getParent();
+        XSSFSheet sheet = getSheet();
         double widthPx = 0;
         for (int col=anchor.getCol1(); col<anchor.getCol2(); col++) {
             widthPx += sheet.getColumnWidthInPixels(col);
@@ -424,11 +514,11 @@ public final class XSSFDrawing extends P
         CTPositiveSize2D ext = xfrm.addNewExt();
         ext.setCx(width - anchor.getDx1() + anchor.getDx2());
         ext.setCy(height - anchor.getDy1() + anchor.getDy2());
-        
+
         // TODO: handle vflip/hflip
         return xfrm;
     }
-    
+
     private long newShapeId(){
         return drawing.sizeOfTwoCellAnchorArray() + 1;
     }
@@ -462,7 +552,7 @@ public final class XSSFDrawing extends P
         }
         return lst;
     }
-    
+
     private void addShapes(XmlCursor cur, List<XSSFShape> lst) {
         try {
             do {
@@ -470,7 +560,7 @@ public final class XSSFDrawing extends P
                 if (cur.toFirstChild()) {
                     do {
                         XmlObject obj = cur.getObject();
-    
+
                         XSSFShape shape;
                         if (obj instanceof CTMarker) {
                             // ignore anchor elements
@@ -480,7 +570,7 @@ public final class XSSFDrawing extends P
                         } else if(obj instanceof CTConnector) {
                             shape = new XSSFConnector(this, (CTConnector)obj) ;
                         } else if(obj instanceof CTShape) {
-                            shape = hasOleLink(obj) 
+                            shape = hasOleLink(obj)
                                 ? new XSSFObjectData(this, (CTShape)obj)
                                 : new XSSFSimpleShape(this, (CTShape)obj) ;
                         } else if(obj instanceof CTGraphicalObjectFrame) {
@@ -492,7 +582,7 @@ public final class XSSFDrawing extends P
                                     + "this unlinks the returned Shapes from the underlying xml content, "
                                     + "so those shapes can't be used to modify the drawing, "
                                     + "i.e. modifications will be ignored!");
-                            
+
                             // XmlAnyTypeImpl is returned for AlternateContent parts, which might contain a CTDrawing
                             cur.push();
                             cur.toFirstChild();
@@ -522,7 +612,7 @@ public final class XSSFDrawing extends P
                         assert(shape != null);
                         shape.anchor = getAnchorFromParent(obj);
                         lst.add(shape);
-                        
+
                     } while (cur.toNextSibling());
                 }
                 cur.pop();
@@ -575,4 +665,12 @@ public final class XSSFDrawing extends P
     public Iterator<XSSFShape> iterator() {
         return getShapes().iterator();
     }
+
+    /**
+     * @return the sheet associated with the drawing
+     */
+    public XSSFSheet getSheet() {
+        return (XSSFSheet)getParent();
+    }
+
 }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFObjectData.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFObjectData.java?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFObjectData.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFObjectData.java Sun Jan 15 02:04:57 2017
@@ -36,7 +36,17 @@ import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.xmlbeans.XmlCursor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeArtExtension;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeArtExtensionList;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
+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.drawingml.x2006.spreadsheetDrawing.CTShape;
+import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOleObject;
 
 /**
@@ -59,13 +69,54 @@ public class XSSFObjectData extends XSSF
     /**
      * Prototype with the default structure of a new auto-shape.
      */
+    /**
+     * Prototype with the default structure of a new auto-shape.
+     */
     protected static CTShape prototype() {
+        final String drawNS = "http://schemas.microsoft.com/office/drawing/2010/main";
+
         if(prototype == null) {
-            prototype = XSSFSimpleShape.prototype();
+            CTShape shape = CTShape.Factory.newInstance();
+
+            CTShapeNonVisual nv = shape.addNewNvSpPr();
+            CTNonVisualDrawingProps nvp = nv.addNewCNvPr();
+            nvp.setId(1);
+            nvp.setName("Shape 1");
+//            nvp.setHidden(true);
+            CTOfficeArtExtensionList extLst = nvp.addNewExtLst();
+            // https://msdn.microsoft.com/en-us/library/dd911027(v=office.12).aspx
+            CTOfficeArtExtension ext = extLst.addNewExt();
+            ext.setUri("{63B3BB69-23CF-44E3-9099-C40C66FF867C}");
+            XmlCursor cur = ext.newCursor();
+            cur.toEndToken();
+            cur.beginElement(new QName(drawNS, "compatExt", "a14"));
+            cur.insertNamespace("a14", drawNS);
+            cur.insertAttributeWithValue("spid", "_x0000_s1");
+            cur.dispose();
+            
+            nv.addNewCNvSpPr();
+
+            CTShapeProperties sp = shape.addNewSpPr();
+            CTTransform2D t2d = sp.addNewXfrm();
+            CTPositiveSize2D p1 = t2d.addNewExt();
+            p1.setCx(0);
+            p1.setCy(0);
+            CTPoint2D p2 = t2d.addNewOff();
+            p2.setX(0);
+            p2.setY(0);
+
+            CTPresetGeometry2D geom = sp.addNewPrstGeom();
+            geom.setPrst(STShapeType.RECT);
+            geom.addNewAvLst();
+
+            prototype = shape;
         }
         return prototype;
     }
 
+    
+    
+    
     @Override
     public String getOLE2ClassName() {
         return getOleObject().getProgId();

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java?rev=1778869&r1=1778868&r2=1778869&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java Sun Jan 15 02:04:57 2017
@@ -47,6 +47,7 @@ import org.apache.poi.POIXMLDocument;
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.POIXMLException;
 import org.apache.poi.POIXMLProperties;
+import org.apache.poi.hpsf.ClassID;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
 import org.apache.poi.openxml4j.opc.OPCPackage;
@@ -58,6 +59,9 @@ import org.apache.poi.openxml4j.opc.Pack
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.poifs.crypt.HashAlgorithm;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.Ole10Native;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.formula.SheetNameFormatter;
 import org.apache.poi.ss.formula.udf.AggregatingUDFFinder;
@@ -2437,4 +2441,41 @@ public class XSSFWorkbook extends POIXML
         }
         return null;
     }
+
+    @Override
+    public int addOlePackage(byte[] oleData, String label, String fileName, String command)
+    throws IOException {
+        // find an unused part name
+        OPCPackage opc = getPackage();
+        PackagePartName pnOLE;
+        int oleId=0;
+        do {
+            try {
+                pnOLE = PackagingURIHelper.createPartName( "/xl/embeddings/oleObject"+(++oleId)+".bin" );
+            } catch (InvalidFormatException e) {
+                throw new IOException("ole object name not recognized", e);
+            }
+        } while (opc.containPart(pnOLE));
+
+        PackagePart pp = opc.createPart( pnOLE, "application/vnd.openxmlformats-officedocument.oleObject" );
+        
+        Ole10Native ole10 = new Ole10Native(label, fileName, command, oleData);
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream(oleData.length+500);
+        ole10.writeOut(bos);
+        
+        POIFSFileSystem poifs = new POIFSFileSystem();
+        DirectoryNode root = poifs.getRoot();
+        root.createDocument(Ole10Native.OLE10_NATIVE, new ByteArrayInputStream(bos.toByteArray()));
+        root.setStorageClsid(ClassID.OLE10_PACKAGE);
+
+        // TODO: generate CombObj stream
+
+        OutputStream os = pp.getOutputStream();
+        poifs.writeFilesystem(os);
+        os.close();
+        poifs.close();
+
+        return oleId;
+    }
 }

Added: poi/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java?rev=1778869&view=auto
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java (added)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java Sun Jan 15 02:04:57 2017
@@ -0,0 +1,125 @@
+/* ====================================================================
+   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.ss.usermodel;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.imageio.ImageIO;
+
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.sl.usermodel.AutoShape;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.sl.usermodel.Slide;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.ss.extractor.EmbeddedData;
+import org.apache.poi.ss.extractor.EmbeddedExtractor;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+import org.apache.poi.xssf.XSSFTestDataSamples;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.junit.Test;
+
+public class TestEmbedOLEPackage {
+    @Test
+    public void embedXSSF() throws IOException {
+        Workbook wb1 = new XSSFWorkbook();
+        Sheet sh = wb1.createSheet();
+        int picIdx = wb1.addPicture(getSamplePng(), Workbook.PICTURE_TYPE_PNG);
+        byte samplePPTX[] = getSamplePPT(true);
+        int oleIdx = wb1.addOlePackage(samplePPTX, "dummy.pptx", "dummy.pptx", "dummy.pptx");
+
+        Drawing<?> pat = sh.createDrawingPatriarch();
+        ClientAnchor anchor = pat.createAnchor(0, 0, 0, 0, 1, 1, 3, 6);
+        pat.createObjectData(anchor, oleIdx, picIdx);
+
+        Workbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
+
+        pat = wb2.getSheetAt(0).getDrawingPatriarch();
+        assertTrue(pat.iterator().next() instanceof ObjectData);
+
+        EmbeddedExtractor ee = new EmbeddedExtractor();
+        EmbeddedData ed = ee.extractAll(wb2.getSheetAt(0)).get(0);
+        assertArrayEquals(samplePPTX, ed.getEmbeddedData());
+
+        wb2.close();
+        wb1.close();
+    }
+
+    @Test
+    public void embedHSSF() throws IOException {
+        try {
+            Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
+        } catch (Exception e) {
+            assumeTrue(false);
+        }
+
+        Workbook wb1 = new HSSFWorkbook();
+        Sheet sh = wb1.createSheet();
+        int picIdx = wb1.addPicture(getSamplePng(), Workbook.PICTURE_TYPE_PNG);
+        byte samplePPT[] = getSamplePPT(false);
+        int oleIdx = wb1.addOlePackage(samplePPT, "dummy.ppt", "dummy.ppt", "dummy.ppt");
+
+        Drawing<?> pat = sh.createDrawingPatriarch();
+        ClientAnchor anchor = pat.createAnchor(0, 0, 0, 0, 1, 1, 3, 6);
+        pat.createObjectData(anchor, oleIdx, picIdx);
+
+        Workbook wb2 = HSSFTestDataSamples.writeOutAndReadBack((HSSFWorkbook)wb1);
+
+        pat = wb2.getSheetAt(0).getDrawingPatriarch();
+        assertTrue(pat.iterator().next() instanceof ObjectData);
+
+        EmbeddedExtractor ee = new EmbeddedExtractor();
+        EmbeddedData ed = ee.extractAll(wb2.getSheetAt(0)).get(0);
+        assertArrayEquals(samplePPT, ed.getEmbeddedData());
+
+        wb2.close();
+        wb1.close();
+    }
+
+    static byte[] getSamplePng() throws IOException {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        URL imgUrl = cl.getResource("javax/swing/plaf/metal/icons/ocean/directory.gif");
+        BufferedImage img = ImageIO.read(imgUrl);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ImageIO.write(img, "PNG", bos);
+        return bos.toByteArray();
+    }
+
+    static byte[] getSamplePPT(boolean ooxml) throws IOException {
+        SlideShow<?,?> ppt = (ooxml) ? new XMLSlideShow() : new org.apache.poi.hslf.usermodel.HSLFSlideShow();
+        Slide<?,?> slide = ppt.createSlide();
+
+        AutoShape<?,?> sh1 = slide.createAutoShape();
+        sh1.setShapeType(ShapeType.STAR_32);
+        sh1.setAnchor(new java.awt.Rectangle(50, 50, 100, 200));
+        sh1.setFillColor(java.awt.Color.red);
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ppt.write(bos);
+        ppt.close();
+
+        return bos.toByteArray();
+    }
+}

Propchange: poi/trunk/src/ooxml/testcases/org/apache/poi/ss/usermodel/TestEmbedOLEPackage.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org