"Embedded OLE Object" Image Appears instead of Prism File Preview

@andrey.pankov I am trying to add prism object and excel object in slide using Aspose cloud API, for excel object I am able to see the preview of file, but in case of prism object I am not able to see it, instead I see “Embedded OLE Object”, how can I see prism file data in prism object too?
image.png (81.3 KB)

@VoyagerIT,
Thank you for contacting support.

We are sorry that you have to encounter this problem. Please share the following files and information:

  • sample Prism file
  • code example to reproduce the problem
  • output presentation file
  • Aspose.Slides Cloud SDK version you used

@andrey.potapov
I am using Aspose.Slides Cloud API
Find the outputPresentation and sample prism object inside the zip attached.
prism object issue.zip (9.6 MB)

Below is the code I am using

public void addObjectToSlide(String accessToken, String filePath, int slideIndex, JSONObject objectDetails) throws IOException {
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .build();

        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, objectDetails.toString());

        String url = String.format("https://api.aspose.cloud/v3.0/slides/%s/slides/%d/shapes", filePath, slideIndex);
        Request request = new Request.Builder()
                .url(url)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Bearer " + accessToken)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            log.info("Object added to slide successfully: " + response.body().string());
        }
    }

public JSONObject createOleObjectDetails(String progId, String linkPath, double x, double y, double width, double height) {
        JSONObject objectDetails = new JSONObject();
        objectDetails.put("Type", "OleObjectFrame");
        objectDetails.put("X", x);
        objectDetails.put("Y", y);
        objectDetails.put("Width", width);
        objectDetails.put("Height", height);
        objectDetails.put("ObjectProgId", progId);
        objectDetails.put("LinkPath", linkPath);
        return objectDetails;
    }

    public void addObjectsToPPT(String filePath, DownloadImageAndGeneratePptDTO downloadImageAndGeneratePptDTO) throws IOException {
        log.info("Starting addObjectsToPPT with filePath: {}", filePath);

        String accessToken = asposeUtil.getAccessToken();
        log.debug("Access token obtained.");

        Map<String, LinkedList<String>> objectMap = filterObjectsByType(downloadImageAndGeneratePptDTO.getGeneratePptList());

        addObjectsToSlides(accessToken, filePath, objectMap);
        asposeUtil.downloadFile(accessToken, filePath, filePath);

        log.info("Finished addObjectsToPPT for filePath: {}", filePath);
    }

    private Map<String, LinkedList<String>> filterObjectsByType(List<GeneratePptDTO> generatePptList) throws IOException {
        Map<String, LinkedList<String>> objectMap = new HashMap<>();
        objectMap.put("prism", new LinkedList<>());
        objectMap.put("excelTable", new LinkedList<>());
        objectMap.put("JMP", new LinkedList<>());
        objectMap.put("Spotfire", new LinkedList<>());

        for (GeneratePptDTO pptDTO : generatePptList) {
            List<String> selectedObjects = pptDTO.getSelectedObjects();
            log.info("Processing GeneratePptDTO with {} selected objects.", selectedObjects.size());

            for (String objectPath : selectedObjects) {
                String extension = getFileExtension(objectPath);
                String objectName = Paths.get(objectPath).getFileName().toString();
                if(objectPath.contains(SITE)){
                    sharepointUtil.downloadFile(objectPath, objectName);
                }else{
                    s3BucketUtil.downloadS3Object(bucketName, objectPath, objectName);
                }
                log.debug("Downloaded object: {} with extension: {}", objectName, extension);

                switch (extension) {
                    case "prism":
                        objectMap.get("prism").add(objectName);
                        break;
                    case "xlsx":
                        objectMap.get("excelTable").add(objectName);
                        break;
                    case "jmp":
                        objectMap.get("JMP").add(objectName);
                        break;
                    case "spotfire":
                        objectMap.get("Spotfire").add(objectName);
                        break;
                    default:
                        log.warn("Unknown file extension: {}", extension);
                        break;
                }
            }
        }

        return objectMap;
    }

    private void addObjectsToSlides(String accessToken, String filePath, Map<String, LinkedList<String>> objectMap) {
        log.info("Starting addObjectsToSlides for filePath: {}", filePath);

        try (FileInputStream fis = new FileInputStream(filePath)) {
            XMLSlideShow ppt = new XMLSlideShow(fis);
            asposeUtil.uploadFile(accessToken, filePath, filePath);

            for (XSLFSlide slide : ppt.getSlides()) {
                log.debug("Processing slide number: {}", slide.getSlideNumber());

                for (XSLFShape shape : slide.getShapes()) {
                    if (shape instanceof XSLFTextShape) {
                        processPlaceholder(accessToken, filePath, objectMap, slide, (XSLFTextShape) shape);
                    }
                }
            }
        } catch (IOException e) {
            log.error("Error processing slides for filePath: {}", filePath, e);
            throw new RuntimeException(e);
        }

        log.info("Finished addObjectsToSlides for filePath: {}", filePath);
    }

    private void processPlaceholder(String accessToken, String filePath, Map<String, LinkedList<String>> objectMap, XSLFSlide slide, XSLFTextShape placeholder) throws IOException {
        String placeholderText = placeholder.getText();
        log.debug("Processing placeholder: {}", placeholderText);

        String objectType = getObjectTypeFromPlaceholder(placeholderText);
        if (objectType != null) {
            int index = getIndexFromPlaceholder(placeholderText, objectType + "Object");
            if (index != -1 && index < objectMap.get(objectType).size()) {
                String objectPath = objectMap.get(objectType).get(index);
                log.info("Adding object: {} to slide number: {}", objectPath, slide.getSlideNumber());
                placeholder.clearText();
                addObjectToSlide(accessToken, filePath, slide, placeholder, objectPath, objectType);
                File pptFile = new File(Paths.get(filePath).getFileName().toString());
                pptFile.delete();
            } else {
                log.warn("Index out of bounds or invalid for placeholder: {}", placeholderText);
            }
        } else {
            log.warn("Unknown placeholder type: {}", placeholderText);
        }
    }

    private void addObjectToSlide(String accessToken, String filePath, XSLFSlide slide, XSLFTextShape placeholder, String objectPath, String objectType) throws IOException {
        Rectangle2D placeholderAnchor = placeholder.getAnchor();
        String oleObjectType = getOleObjectType(objectType);

        JSONObject objectDetails = asposeUtil.createOleObjectDetails(oleObjectType, objectPath,
                placeholderAnchor.getX(), placeholderAnchor.getY(),
                placeholderAnchor.getWidth(), placeholderAnchor.getHeight());

        log.debug("Adding object to slide. ObjectType: {}, SlideNumber: {}, ObjectDetails: {}", objectType, slide.getSlideNumber(), objectDetails);

        asposeUtil.addObjectToSlide(accessToken, filePath, slide.getSlideNumber(), objectDetails);
    }

    private String getFileExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');
        return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
    }

    private int getIndexFromPlaceholder(String placeholderText, String prefix) {
        try {
            return Integer.parseInt(placeholderText.substring(prefix.length()));
        } catch (NumberFormatException e) {
            log.error("Error parsing index from placeholder: {}", placeholderText, e);
            return -1; // or handle appropriately
        }
    }

    private String getObjectTypeFromPlaceholder(String placeholderText) {
        if (placeholderText.startsWith("prismObject")) return "prism";
        if (placeholderText.startsWith("excelTableObject")) return "excelTable";
        if (placeholderText.startsWith("JMPObject")) return "JMP";
        if (placeholderText.startsWith("SpotfireObject")) return "Spotfire";
        return null;
    }

    private String getOleObjectType(String objectType) {
        switch (objectType) {
            case "prism":
                return "PrismObject";
            case "excelTable":
                return "Excel.Sheet.12";
            case "JMP":
                return "JMPObject";
            case "Spotfire":
                return "SpotfireObject";
            default:
                log.warn("Unknown object type: {}", objectType);
                return "";
        }
    }

@VoyagerIT,
Thank you for the additional information. I am working on the issue and will get back to you soon.

@VoyagerIT,
Thank you for your patience. With Aspose.Slides Cloud SDK for Java 24.7, I used the following code example:

String documentName = "MyPresentation.pptx";
int slideIndex = 1;

OleObjectFrame oleFrame = new OleObjectFrame();
oleFrame.setX(20d);
oleFrame.setY(20d);
oleFrame.setWidth(500d);
oleFrame.setHeight(500d);
oleFrame.setObjectProgId("PrismObject");
oleFrame.setLinkPath("VAT2304 HEM (SJC).prism");

slidesApi.createShape(documentName, slideIndex, oleFrame, null, null, null, null, null, null);

My output: output.zip (86.2 KB)
After updating the link, I see the Prism file preview. Please check the issue using the code example above.

More examples:
Add OLE Objects|Documentation

@andrey.potapov
I am still getting “embedded ole object” instead of prism preview.
Can it be because I am not having graphpad software in my system?

Also, I want to insert JMP and Sportfire objects also similar to prism objects. How can I do that? Sample files are attached in the zip along with the message
sample object files.zip (2.1 MB)

@VoyagerIT,

Yes, PowerPoint uses the software to prepare the preview for the linked OLE objects. But even if the software is installed and the presentation file and the linked file have been moved, the “embedded ole object” image may still appear and a message may appear asking you to update the link because the file paths were changed.

You can add any files as linked OLE objects to PowerPoint presentations in the same way as shown above. The difference is in the progId that needs to be passed in the setObjectProgId method.

Thanks @andrey.potapov, I tried installing the software and then adding prism objects, it worked fine.
But when I am trying to download the same presentation using Aspose.slides.cloud sdk, its again showing as “Embedded OLE Object”
abc_histology_2024_08_09_15_32_14_744.zip (5.4 MB)

Using below code to download presentation

File file = null;
file = asposeConfig.slidesApi().downloadFile(filePath, storageName, null);
// Save the file
try (InputStream inputStream = new FileInputStream(file);
     FileOutputStream outputStream = new FileOutputStream(outputPath)) {

    byte[] buffer = new byte[8192]; // Use a larger buffer size
    int bytesRead;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, bytesRead);
    }
}

@VoyagerIT,
I apologize for the delay. Please note that when you add a linked object, the embedded file still remains external, the presentation retains a link to it. When you move the presentation (for example, from storage to a local drive) and then open it, the image “Embedded OLE Object” may appear.

But if I am manually downloading the same file, it link persists and I am not able to see the objects as “Embedded OLE Object”
@andrey.potapov

@VoyagerIT,
I have checked the issue you described and found that in both cases I see the “Embedded OLE object” image and the PowerPoint message with the “Update Links” button. Could you kindly provide step-by-step instructions on how to reproduce the issue you are experiencing?

@andrey.potapov
Case 1 : Objects are visible as original preview in presentation

  1. Uploaded PPT in Aspose storage programmatically.
  2. Added objects to PPT programmatically.
  3. Downloaded PPT manually.

Case 2: Objects are visible as “Embedded OLE Object”

  1. Uploaded PPT in Aspose storage programmatically.
  2. Added objects to PPT programmatically.
  3. Downloaded PPT from Aspose Storage programmatically.

@VoyagerIT,
Thank you for the details. I am working on the issue and will get back to you soon.

@VoyagerIT,
Unfortunately, in both cases I get the same result. I see the image “Embedded OLE Object” and the preview updates when I click the button “Update Links” in PowerPoint. This is the correct behavior because the presentation file was moved.

@andrey.potapov
Then what is the alternative for this, because our requirement is that we will have to download the presentation to move it at different locations, in that case how can we expect the objects to work correctly?

@andrey.potapov

Additionally, we are encountering an issue with the Aspose.Cloud SDK, which imposes a limit of 100 API calls per day. Is there a way to increase the number of API calls we can make each day?

@VoyagerIT,

Instead of the object preview, you can use a file icon. The following code example shows you how to do this:

String documentName = "MyPresentation.pptx"; // in storage
int slideIndex = 1;
String oleFilePath = "MyWorkbook.xlsx";  // a local file
String oleProgId = "Excel.Sheet.12";
String iconFilePath = "MyExcelIcon.ico"; // a local file
String iconTitle = "My document";

byte[] iconData = Files.readAllBytes(Paths.get(iconFilePath));

OleObjectFrame oleFrame = new OleObjectFrame();
oleFrame.setX(20d);
oleFrame.setY(20d);
oleFrame.setWidth(70d);
oleFrame.setHeight(60d);
oleFrame.setLinkPath(oleFilePath);
oleFrame.setObjectProgId(oleProgId);

// Set the icon
oleFrame.setIsObjectIcon(true);
oleFrame.setSubstitutePictureFormat(new PictureFill());
oleFrame.getSubstitutePictureFormat().setBase64Data(Base64.getEncoder().encodeToString(iconData));
oleFrame.getSubstitutePictureFormat().setPictureFillMode(PictureFill.PictureFillModeEnum.STRETCH);
oleFrame.setSubstitutePictureTitle(iconTitle);

slidesApi.createShape(documentName, slideIndex, oleFrame, null, null, null, null, null, null);

Aspose Cloud provides free 150 API calls per month. If you need more, you have to obtain a license. You can contact our sales team on Aspose.Purchase forum.

@andrey.potapov
But I don’t want to show the objects as icon, I want it to be visible as an editable picture/preview.

@VoyagerIT,
The problem is related to the PowerPoint behavior. Unfortunately, I cannot offer you another way.

Hi @andrey.potapov,

Query 1 : When I am trying to embed an any object in ppt, first I am able to see “Embedded OLE Object” icon on download, but when I double click on that Icon, I am able to open the object (Tried objects- excel, jpeg, prism)

Query 2: Once I open that object in PPT, excel object is working fine but, other objects like prism and jpeg are then visible as icon.

Please find the PPTs, screenshots attached and find the used code below:

asposeConfig.slidesApi().createShape(filePath, slideIndex, oleFrame, null, null, null,null, null, null);

 public OleObjectFrame createOleObjectDetails(String progId, String linkPath, double x, double y, double width, double height, String base64FileData) {
        OleObjectFrame oleFrame = new OleObjectFrame();
        oleFrame.setX(x);
        oleFrame.setY(y);
        oleFrame.setWidth(width);
        oleFrame.setHeight(height);
        oleFrame.setObjectProgId(progId);
        oleFrame.setEmbeddedFileBase64Data(base64FileData);
        oleFrame.setEmbeddedFileExtension("xlsx");
        
        return oleFrame;
    }

Screenshots.zip (161.7 KB)

Sample Objects.zip (101.5 KB)

PPT with JPEG Object.zip (5.5 MB)

PPT with Excel Object.zip (5.5 MB)

PPT with Prism Object.zip (5.4 MB)