OpenXMLを使用してスライドを別のPowerPointスライドに挿入するにはどうすればよいですか?

Aug 20 2020

PowerPointスライド(「ソース」)を取得し、ソースPowerPointスライドの特定の位置で、すでにコンテンツが含まれている別のPowerPointスライド(「ターゲット」)に挿入したいと思います。

これを行うコードを調査するためにいくつかの方法を試しましたが、スライドをPowerPointプレゼンテーションにマージした結果が得られ続けています。これは私が望んでいることではありません。既存のスライドに写真を挿入するのと同じように、既存のスライドを別のスライドに挿入したいと思います。

別の同僚が作成した、ソーススライドのすべての要素のクローンを作成するコードがありますが、複雑で、要素タイプごとに異なるコードバリエーションを使用しています。そのコードの代表的なサンプルを次に示します。

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

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

        // Adjust the offsets so it is positioned correctly.
        ((Picture)elementClone).ShapeProperties.Transform2D.Offset.X += (Int64)shapeStruct.OffsetX;
        ((Picture)elementClone).ShapeProperties.Transform2D.Offset.Y += (Int64)shapeStruct.OffsetY;

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

        string rId = ((Picture)element).BlipFill.Blip.Embed.Value;

        ImagePart imagePart = (ImagePart)slideInstProc.SlidePart.GetPartById(rId);
        string contentType = imagePart.ContentType;

        // Locate the same object we cloned over to the slide.
        var blip = ((Picture)elementClone).BlipFill.Blip;

        slidePart = slideCard.SlidePart;

        try
        {
            ImagePart imagePart1 = slidePart.AddImagePart(contentType, rId);
            imagePart1.FeedData(imagePart.GetStream());
        }
        catch (XmlException)
        {
            //Console.WriteLine(xe.ToString());
            Console.WriteLine("Duplicate rId (" + rId + ")");
        }
    }
    if (elementTypeName.EndsWith(".GroupShape"))
    {
        ... etc

コードは、で終わる要素タイプ名のコードのブロックを含む他-IFラダーに続く.GroupShape.GraphicFrame.Shape、および.ConnectionShape、底部の他のキャッチオールと締結します。

問題は、このコードが一部のタイプのオブジェクトを適切に処理しないことです。1つには、図面をまったく処理せず(おそらく、一部の図面が古いバージョンのPowerPointから作成されたため)、処理する場合は、図面の色を変更するなどの処理を行います。

私が望んでいたのは、ソースPowerPoint内の要素タイプを具体的に調べることなく、ソースPowerPointスライドを別のスライドに埋め込み、単一のオブジェクトのように扱う、より基本的な方法(つまり、より単純で一般的なコード)があることです。

あるいは、画像として明確に識別されない通常の「形状」の図面や画像を処理する方法は何でしょうか。

回答

RobertHarvey Aug 25 2020 at 03:42

これは、私が上で説明した特定の問題を解決したコードです。

using A = DocumentFormat.OpenXml.Drawing;

foreach(A.BlipFill blipFill in shape.Descendants<A.BlipFill>())
{
    string rId = blipFill.Blip.Embed.Value;
    ImagePart imagePart = (ImagePart)slideInstProc.SlidePart.GetPartById(rId);
    string contentType = imagePart.ContentType;

    try
    {
        ImagePart imagePart1 = slidePart.AddImagePart(contentType, rId);
        imagePart1.FeedData(imagePart.GetStream());
    }
    catch (XmlException)
    {
        Console.WriteLine("Duplicate rId (" + rId + ")");
    }
}

これを適用するとelementTypeName.EndsWith(".shape");、まさに私が望む結果が得られます。

完全なスライドをプレゼンテーションに構成する場合(これには、私たちが行う生成メカニズムの一部は必要ありません)、OpenXmlPowerToolsははるかに優れたアプローチです。