将OLE对象从一张幻灯片复制到另一张幻灯片会损坏生成的PowerPoint

问题描述

我有将一张PowerPoint幻灯片的内容复制到另一张PowerPoint幻灯片中的代码。下面是一个如何处理图像的示例。

foreach (OpenXmlElement element in sourceSlide.CommonSlideData.ShapeTree.ChildElements.ToList())
{
    string elementType = element.GetType().ToString();

    if (elementType.EndsWith(".Picture"))
    {
        // Deep clone the element.
        elementClone = element.CloneNode(true);
        var picture = (Picture)elementClone;

        // Get the picture's original rId
        var blip = picture.BlipFill.Blip;
        string rId = blip.Embed.Value;
        
        // Retrieve the ImagePart from the original slide by rId
        ImagePart sourceImagePart = (ImagePart)sourceSlide.SlidePart.GetPartById(rId);

        // Add the image part to the new slide,letting OpenXml generate the new rId
        ImagePart targetImagePart = targetSlidePart.AddImagePart(sourceImagePart.ContentType);

        // And copy the image data.
        targetImagePart.FeedData(sourceImagePart.GetStream());

        // Retrieve the new ID from the target image part,string id = targetSlidePart.GetIdOfPart(targetImagePart);

        // and assign it to the picture.
        blip.Embed.Value = id;

        // Get the shape tree that we're adding the clone to and append to it.
        ShapeTree shapeTree = targetSlide.CommonSlideData.ShapeTree;
        shapeTree.Append(elementClone);
    }

此代码可以正常工作。对于其他情况,例如“图形框架”,它看起来有点不同,因为每个图形框架可以包含多个图片对象。

// Go thru all the Picture objects in this GraphicFrame.
foreach (var sourcePicture in element.Descendants<Picture>())
{
    string rId = sourcePicture.BlipFill.Blip.Embed.Value;
    ImagePart sourceImagePart = (ImagePart)sourceSlide.SlidePart.GetPartById(rId);
    var contentType = sourceImagePart.ContentType;

    var targetPicture = elementClone.Descendants<Picture>().First(x => x.BlipFill.Blip.Embed.Value == rId);
    var targetBlip = targetPicture.BlipFill.Blip;

    ImagePart targetImagePart = targetSlidePart.AddImagePart(contentType);
    targetImagePart.FeedData(sourceImagePart.GetStream());
    string id = targetSlidePart.GetIdOfPart(targetImagePart);
    targetBlip.Embed.Value = id;
}

现在我需要对OLE对象做同样的事情。

// Go thru all the embedded objects in this GraphicFrame.
foreach (var oleObject in element.Descendants<OleObject>())
{
    // Get the rId of the embedded OLE object.
    string rId = oleObject.Id;

    // Get the EmbeddedPart from the source slide.
    var embeddedOleObj = sourceSlide.SlidePart.GetPartById(rId);

    // Get the content type.
    var contentType = embeddedOleObj.ContentType;

    // Create the Target Part.  Let OpenXML assign an rId.
    var targetObjectPart = targetSlide.SlidePart.AddNewPart<EmbeddedObjectPart>(contentType,null);

    // Get the embedded OLE object data from the original object.
    var objectStream = embeddedOleObj.GetStream();

    // And give it to the ObjectPart.
    targetObjectPart.FeedData(objectStream);

    // Get the new rId and assign it to the OLE Object.
    string id = targetSlidePart.GetIdOfPart(targetObjectPart);
    oleObject.Id = id;
}

但是没有用。生成的PowerPoint已损坏。

我在做什么错了?


注意::除OLE对象中的rId处理外,所有代码均有效。我知道它是有效的,因为如果我只是将原始rId从源对象传递到目标对象部分,就像这样:

var targetObjectPart = targetSlide.SlidePart
   .AddNewPart<EmbeddedObjectPart>(contentType,rId);

只要目标幻灯片中没有rId,它就会正常运行, 显然,它每次都无法像我需要的那样工作。

源幻灯片和目标幻灯片来自不同的PPTX文件。我们使用的是OpenXML,而不是Office Interop。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)