如何使用 OpenXML 将一张幻灯片插入另一张 PowerPoint 幻灯片?
How do I insert a slide into another PowerPoint slide using OpenXML?
我想制作一张 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
代码以 else-if 梯形图继续,其中包含以 .GroupShape
、.GraphicFrame
、.Shape
和 .ConnectionShape
结尾的元素类型名称的代码块,最后底部有一个 catchall else。
问题是此代码无法正确处理某些类型的对象。一方面,它根本不处理绘图(可能是因为其中一些源自旧版本的 PowerPoint),而当它处理时,它会做一些事情,比如改变绘图的颜色。
我希望有一种更基本的方法(即更简单的通用代码)将源 PowerPoint 幻灯片嵌入到另一个幻灯片中,将其视为单个对象,而无需专门查看源 PowerPoint 中的元素类型.
或者,以普通“形状”处理绘图或图像的方法是什么,这些图形或图像不会将自己具体标识为图像?
这是解决我上面描述的具体问题的代码:
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 是一种更好的方法。
我想制作一张 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
代码以 else-if 梯形图继续,其中包含以 .GroupShape
、.GraphicFrame
、.Shape
和 .ConnectionShape
结尾的元素类型名称的代码块,最后底部有一个 catchall else。
问题是此代码无法正确处理某些类型的对象。一方面,它根本不处理绘图(可能是因为其中一些源自旧版本的 PowerPoint),而当它处理时,它会做一些事情,比如改变绘图的颜色。
我希望有一种更基本的方法(即更简单的通用代码)将源 PowerPoint 幻灯片嵌入到另一个幻灯片中,将其视为单个对象,而无需专门查看源 PowerPoint 中的元素类型.
或者,以普通“形状”处理绘图或图像的方法是什么,这些图形或图像不会将自己具体标识为图像?
这是解决我上面描述的具体问题的代码:
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 是一种更好的方法。