Replace OLE Embedded Objects in Word Document with Updated / Modified Files using C# .NET Code of Aspose.Words | Detect File Format

Hi Team,

I would like to inquire about OLE objects in Aspose.Words for .NET.

I intend to process a DOCX file which contains another file (e.g: DOCX) and process the embedded one too. Something like this (it is just a simplified part of the code):

NodeCollection shapes = document.GetChildNodes(NodeType.Shape, true);
foreach (Shape shape in shapes)
{
    if (null != shape.OleFormat)
    {
        OleFormat oleObject = shape.OleFormat;                    
        if (!oleObject.IsLink)
        {
            MemoryStream stream = new MemoryStream();
            oleObject.Save(stream);
            Document embeddedDocument = new Document(stream);
            // edit the embedded document
            // replace the original embedded document with the new one
        }
    }
}
// save the parent document which should contain the edited OLE object

However, I could not find any solution to update the existing embedded document with the processed embedded document. I have found a previous forum post that it was not possible some years ago, but it might have changed till now.

So my question is that is it possible to replace an OLE object with another in Aspose.Words for .NET?

Best regards,
Tamas Boldizsar

@tamas.boldizsar,

You can implement the following workflow to meet this requirement:

  1. Use Shape.OleFormat.Save(Stream) to save object to stream,
  2. Use Aspose.Words to modify the Document and save it to a Stream
  3. Delete old shape in Aspose.Words
  4. Use DocumentBuilder.InsertOleObject to insert the updated object back into the document as a new shape

Sample code:

Document document = new Document("C:\\Temp\\source.docx");

NodeCollection shapes = document.GetChildNodes(NodeType.Shape, true);
foreach (Shape shape in shapes)
{
    if (null != shape.OleFormat)
    {
        OleFormat oleObject = shape.OleFormat;
        if (!oleObject.IsLink)
        {
            MemoryStream stream = new MemoryStream();
            oleObject.Save(stream);

            Document embeddedDocument = new Document(stream);
            // edit the embedded document
            embeddedDocument.FirstSection.Body.Tables[0].LastRow.LastCell.FirstParagraph.Runs.Add(new Run(embeddedDocument, "new content"));
            // Save the embedded document
            MemoryStream editedStream = new MemoryStream();
            embeddedDocument.Save(editedStream, SaveFormat.Docx);
            editedStream.Position = 0;
            // Insert embedded document at the same place where original object was
            DocumentBuilder builder = new DocumentBuilder(document);
            Shape editedOleObject = builder.InsertOleObject(editedStream, oleObject.ProgId, true, null);
            shape.ParentNode.InsertAfter(editedOleObject, shape);
            // remove original shape
            shape.Remove();
            break;
        }
    }
}
// save the parent document which should contain the edited OLE object
document.Save("C:\\Temp\\21.2.docx");

@awais.hafeez

Thank you for you reply, it was a great help!

I have yet another question though. Is OleFormat.ProgId the only property which helps to determine the OLE object’s type in Word documents? Or are there any further IDs, enums or something like that for this purpose?

@tamas.boldizsar,

You can make use of FileFormatUtil.DetectFileFormat(Stream) Method to detect if the type of embedded object is supported by Aspose.Words for .NET or not. Similarly, other Aspose APIs also provide similar methods. For example, check following links:

@awais.hafeez

Thank you, they are really useful!

Meanwhile I ran into an issue regarding your advice for object insertion. Without breaking the “for” cycle, it gets an endless loop. However, if there is a “break;” in it, it always handles only the first embedded object in the document, but there can be more of them in it. Could you please help with this issue?

@awais.hafeez

I managed to solve it. “foreach” loop was the cause of the issue. After changing it to a traditional “for” loop, the problem disappeared.

Thanks again for your help and tips!

@tamas.boldizsar,

It is great that you were able to resolve this issue on your end. Please let us know any time you may have any further queries in future.