Embedding OLE objects

After playing with Aspose.Slides a month or so back, I’d put it on hold for a while whilst we were firming up project requirements, but came back to it again to test embedded OLE intergration, which will be a key requirement for our software.

I’ve been attempting to write my own test harness, but when I attempt to add an Excel spreadsheet to a powerpoint, it doesn’t work. I started my test by iterating through OleObjectFrame shapes and printing information and saving the byte stream and then tried adding an ole object from a stream (actually one of the one’s I’d just saved) before iterating through the debug loop.

However, the added object had an object type of 4 instead of object type 3, and any attempt to call getObjectData() on this new object would cause an exception caused by an exception “Unexpected end of ZLIB input stream”.

I tired with this for some time, and then decided to try the example OleDemo, which outputs a completely empty powerpoint file, so it clearly wasn’t just my problem.

Has anyone managed to get this to work with any success, if so can you point to an example that works?

The zip / jar file doesn’t contain any version number that I can see, but it was downloaded on March 1st, and the most recent change in the zip file seems to have been 28/2/2006. However, according to the releases page at http://www.aspose.com/community/Blogs/alexey.zhilin/archive/category/1041.aspx, the last release was 17/2/2006, so I’m a little confused as to what version I’m actually testing.

ranulf wrote:
The zip / jar file doesn't contain any version number that I can see [...]


Ihave just downloaded the latest version and tested against that with exactly the same problems.

We changed blog category after renaming library. Please check:
http://www.aspose.com/Community/Blogs/alexey.zhilin/archive/category/1064.aspx

Jar contains version number in the Aspose.Slides.manifest file.

I have tested our OleDemo but it works.
Please could you show any example how you add Excel sheet to a slide?


import com.aspose.slides.AsposeLicenseException;
import com.aspose.slides.OleObjectFrame;
import com.aspose.slides.Placeholder;
import com.aspose.slides.PlaceholderType;
import com.aspose.slides.Placeholders;
import com.aspose.slides.PptException;
import com.aspose.slides.Presentation;
import com.aspose.slides.Shape;
import com.aspose.slides.Shapes;
import com.aspose.slides.Slide;
import com.aspose.slides.Slides;
import com.aspose.slides.Tags;
import com.aspose.slides.TextHolder;
import org.apache.log4j.Logger;
import org.apache.log4j.lf5.util.StreamUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestOLE {
protected static final Logger log = Logger.getLogger(TestOLE.class);

public static void main(String[] args) {
int segment = 0;

byte lastSheet[] = null;

try {
if (args.length<2) {
log.fatal(“Must supply old and new ppt filename”);
return;
}
File input = new File(args[0]);
FileInputStream inputStream = new FileInputStream(input);
Presentation presentation = new Presentation(inputStream);
inputStream.close();

Slides slides = presentation.getSlides();
for (int slideIndex = 0; slideIndex < slides.size(); slideIndex++) {
Slide slide = slides.get(slideIndex);
log.debug(“Slide " + slideIndex);

Placeholders placeholders = slide.getPlaceholders();

for (int placeholderIndex = 0; placeholderIndex < placeholders.size(); placeholderIndex++) {
Placeholder placeholder = placeholders.get(placeholderIndex);

if (placeholder instanceof TextHolder) {
log.debug(“TextHolder: " + ((TextHolder) placeholder).getText());
} else {
int placeholderType = placeholder.getPlaceholderType();
log.debug(“Placeholder type " + placeholderType + " class " + placeholder.getClass().getName());

if (placeholderType == PlaceholderType.NOTES_SLIDE_IMAGE) {
log.debug(“Adding new sheet”);
/* this next bit read from a file, doesn’t work either way
File newSheetFile = new File(“newsheet.xls”);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
FileInputStream newSheetInputStream = new FileInputStream(newSheetFile);
StreamUtils.copy(newSheetInputStream, byteArrayOutputStream);
newSheetInputStream.close();
byteArrayOutputStream.flush();
byte[] data = byteArrayOutputStream.toByteArray();
lastSheet = data;
*/
if (lastSheet!=null) {
String type = “Microsoft Office Excel Worksheet”;
// type =“Excel.Sheet.8”;
Shapes shapes = slide.getShapes();
OleObjectFrame oleObjectFrame = shapes.addOleObjectFrame(0, 0, 1000, 1000, type, lastSheet);
oleObjectFrame.setObjectProgId(“Excel.Sheet.8”);
oleObjectFrame.setObjectName(“Worksheet”);
}
}
}
}

Shapes shapes = slide.getShapes();
for (int shapeIndex = 0; shapeIndex < shapes.size(); shapeIndex++) {
Shape shape = shapes.get(shapeIndex);
if (shape instanceof OleObjectFrame) {
OleObjectFrame oleObjectFrame = (OleObjectFrame) shape;
log.debug(“Found OLE object class “+oleObjectFrame.getObjectClassName());
log.debug(” getObjectType " + oleObjectFrame.getObjectType());
log.debug(” getObjectName " + oleObjectFrame.getObjectName());
log.debug(” getObjectProgId " + oleObjectFrame.getObjectProgId());
log.debug(” getLinkPathLong " + oleObjectFrame.getLinkPathLong());
log.debug(” getLinkPathShort " + oleObjectFrame.getLinkPathShort());

// if (oleObjectFrame.getObjectType() == 3)
{
byte[] objectData = oleObjectFrame.getObjectData();
log.debug(" getObjectData length " + objectData.length);

lastSheet = objectData;

String segmentName = “segment-” + ++segment + “.dat”;
File segmentFile = new File(segmentName);
segmentFile.createNewFile();
FileOutputStream outputStream = new FileOutputStream(segmentFile);
outputStream.write(objectData);
outputStream.close();
log.debug("Saved as "+segmentName);
}
} else {
log.debug(“Found shape class " + shape.getClass().getName());
}
Tags tags = shape.getTags();
for (int tagIndex = 0; tagIndex < tags.size(); tagIndex++) {
String tag = tags.getTagName(tagIndex);
log.debug(” Shape tag “+tag+”: "+tags.get(tag));
}
}

}


log.debug(“Saving”);
File output = new File(args[1]);
output.createNewFile();
FileOutputStream outputStream = new FileOutputStream(output);
presentation.write(outputStream);
outputStream.close();
log.debug(“Done”);

} catch (FileNotFoundException e) {
log.error(“Caught exception”, e);
} catch (PptException e) {
log.error(“Caught exception”, e);
} catch (IOException e) {
log.error(“Caught exception”, e);
// } catch (AsposeLicenseException e) {
// log.error(“Caught exception”, e);
}
}
}

It is not so important what getObjectType() function returns. Probably this value even not used by PowerPoint.
But you must set correct ProgId when create OLE object. For excel it should be “Excel.Sheet.8”.

This code works:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
FileInputStream newSheetInputStream = new FileInputStream(“newsheet.xls”);

byte[] buf = new byte[4096];
while (true) {
int bytesRead = newSheetInputStream.read(buf, 0, buf.length);
if (bytesRead <= 0)
break;
byteArrayOutputStream.write(buf, 0, bytesRead);
}
newSheetInputStream.close();
byteArrayOutputStream.flush();
byte[] data = byteArrayOutputStream.toByteArray();

if (data != null) {
Shapes shapes = slide.getShapes();
OleObjectFrame oleObjectFrame = shapes.addOleObjectFrame(0, 0, 1000, 1000, “Excel.Sheet.8”, data);
}

alcrus wrote:
This code works:


Thanks for that. Your new example did work, and enabled me to track down why my example wasn't working.

For some reason, the Placeholder object on that page returns all zeros for coordinates, width and height. It appears that I actually need to iterate through the Shapes to find the the chart placeholder, although there appears to be no way of accurately identifying an empty shape meant to include a chart (shown in powerpoint as "Click icon to add content").