gpt4 book ai didi

c# - 使用 Open XML SDK 将幻灯片从一个演示文稿复制到另一个

转载 作者:太空狗 更新时间:2023-10-30 01:00:05 25 4
gpt4 key购买 nike

对不起我的英语:)

有密码

using (var sourceDoc = PresentationDocument.Open(@"d:\source.pptx", false))
{
using (var destDoc = PresentationDocument.Open(@"d:\dest.pptx", true))
{

}
}

我尝试从 sourceDoc 复制幻灯片 №2 并粘贴到 destDoc 位置 4。


有相同标题的文章"Copying A Slide From One Presentation To Another""How to Assemble Multiple PowerPoint Decks" ,但不幸的是我不能应用它。我只是困惑。例如:

uniqueId = GetMaxIdFromChild(destPresPart.Presentation.SlideMasterIdList);

什么意思?编译时报错。


更新#1

我创建了将幻灯片复制到另一个演示文稿的方法

/// <summary>
/// Copy one slide to another presentation
/// </summary>
/// <param name="sourcePresentationPath"></param>
/// <param name="slidePosition">
/// Slide number from source presentation which will be copy to destinition presentation
/// </param>
/// <param name="destPresentationPath"></param>
/// <remarks>Slide copy to end destinition presentation</remarks>
public static void CopySlideTo(string sourcePresentationPath, int slidePosition, string destPresentationPath)
{
using (PresentationDocument sourcePresentationDocument = PresentationDocument.Open(sourcePresentationPath, false))
{
var sourcePresentationPart = sourcePresentationDocument.PresentationPart;
var sourcePresentation = sourcePresentationPart.Presentation;
SlideIdList sourceSlideIdList = sourcePresentation.SlideIdList;
SlideId slideIdSelectedSlide = sourceSlideIdList.ChildElements[slidePosition - 1] as SlideId;
SlidePart sourceSlidePart = sourcePresentationPart.GetPartById(slideIdSelectedSlide.RelationshipId) as SlidePart;

SlidePart destSlidePart = null;
SlideIdList destSlideIdList = null;
PresentationPart destPresentationPart = null;
using (PresentationDocument destPresentationDocument = PresentationDocument.Open(destPresentationPath, true))
{
var addedSlidePart = destPresentationDocument.PresentationPart.AddPart(sourceSlidePart);

destSlideIdList = destPresentationDocument.PresentationPart.Presentation.SlideIdList;

destPresentationPart = destPresentationDocument.PresentationPart;

SlideId lastSlideIdInDestPresentation = destSlideIdList.ChildElements.Last() as SlideId;

// Insert the new slide into the slide list after last slide
SlideId addedSlideId = destSlideIdList.InsertAfter(new SlideId(), lastSlideIdInDestPresentation);
addedSlideId.Id = lastSlideIdInDestPresentation.Id++;
addedSlideId.RelationshipId = destPresentationPart.GetIdOfPart(addedSlidePart);

destPresentationPart.Presentation.Save();
}
}

幻灯片已复制,但没有背景。还怎么动背景?


更新 #2

我终于创建了将幻灯片复制到另一个演示文稿的方法

public class Extensions
{
static uint uniqueId;

/// <summary>
/// Copy one slide to another presentation
/// </summary>
/// <param name="sourcePresentationPath"></param>
/// <param name="slidePosition">
/// Slide number from source presentation which will be copy to destinition presentation
/// </param>
/// <param name="destPresentationPath"></param>
/// <remarks>Slide is copied to end destinition presentation</remarks>
[SuppressMessage("ReSharper", "SuggestVarOrType_SimpleTypes")]
public static void CopySlideTo(string sourcePresentationPath, int slidePosition, string destPresentationPath)
{
using (PresentationDocument sourcePresentationDocument = PresentationDocument.Open(sourcePresentationPath, false))
{
var sourcePresentationPart = sourcePresentationDocument.PresentationPart;
var sourcePresentation = sourcePresentationPart.Presentation;
SlideIdList sourceSlideIdList = sourcePresentation.SlideIdList;
SlideId slideIdSelectedSlide = sourceSlideIdList.ChildElements[slidePosition - 1] as SlideId;
SlidePart sourceSlidePart = sourcePresentationPart.GetPartById(slideIdSelectedSlide.RelationshipId) as SlidePart;
using (PresentationDocument destPresentationDocument = PresentationDocument.Open(destPresentationPath, true))
{
var addedSlidePart = destPresentationDocument.PresentationPart.AddPart(sourceSlidePart);

var destSlideIdList = destPresentationDocument.PresentationPart.Presentation.SlideIdList;

var destPresentationPart = destPresentationDocument.PresentationPart;

SlideId lastSlideIdInDestPresentation = destSlideIdList.ChildElements.Last() as SlideId;

// Insert the new slide into the slide list after last slide
SlideId addedSlideId = destSlideIdList.InsertAfter(new SlideId(), lastSlideIdInDestPresentation);
addedSlideId.Id = lastSlideIdInDestPresentation.Id++;
addedSlideId.RelationshipId = destPresentationPart.GetIdOfPart(addedSlidePart);

// Get the existing slide master part.
SlideMasterPart destPresPartSlideMasterPart = destPresentationPart.SlideMasterParts.ElementAt(0);
string relationshipId = destPresentationPart.GetIdOfPart(destPresPartSlideMasterPart);

// Get the new slide master part.
SlideMasterPart sourcePresPartSlideMasterPart = sourcePresentationPart.SlideMasterParts.ElementAt(0);

// Remove the existing theme part.
destPresentationPart.DeletePart(destPresentationPart.ThemePart);

// Remove the old slide master part.
destPresentationPart.DeletePart(destPresPartSlideMasterPart);

// Import the new slide master part, and reuse the old relationship ID.
sourcePresPartSlideMasterPart = destPresentationPart.AddPart(sourcePresPartSlideMasterPart, relationshipId);

// Change to the new theme part.
destPresentationPart.AddPart(sourcePresPartSlideMasterPart.ThemePart);

var newSlideLayouts = new Dictionary<string, SlideLayoutPart>();

foreach (var slideLayoutPart in sourcePresPartSlideMasterPart.SlideLayoutParts)
{
newSlideLayouts.Add(GetSlideLayoutType(slideLayoutPart), slideLayoutPart);
}

// Remove the slide layout relationship on all slides.
foreach (var slidePart in destPresentationPart.SlideParts)
{
string layoutType = null;

if (slidePart.SlideLayoutPart != null)
{
// Determine the slide layout type for each slide.
layoutType = GetSlideLayoutType(slidePart.SlideLayoutPart);

// Delete the old layout part.
slidePart.DeletePart(slidePart.SlideLayoutPart);
}

SlideLayoutPart newLayoutPart = null;
if (layoutType != null && newSlideLayouts.TryGetValue(layoutType, out newLayoutPart))
{
// Apply the new layout part.
slidePart.AddPart(newLayoutPart);
}
}
FixSlideLayoutIds(destPresentationPart);
destPresentationPart.Presentation.Save();
}
}
}

static void FixSlideLayoutIds(PresentationPart presPart)
{
// Make sure that all slide layouts have unique ids.
foreach (SlideMasterPart slideMasterPart in presPart.SlideMasterParts)
{
foreach (SlideLayoutId slideLayoutId in slideMasterPart.SlideMaster.SlideLayoutIdList)
{
uniqueId++;
slideLayoutId.Id = (uint)uniqueId;
}

slideMasterPart.SlideMaster.Save();
}
}

/// <summary>
/// Get the slide layout type.
/// </summary>
/// <param name="slideLayoutPart"></param>
/// <returns></returns>
private static string GetSlideLayoutType(SlideLayoutPart slideLayoutPart)
{
CommonSlideData slideData = slideLayoutPart.SlideLayout.CommonSlideData;

return slideData.Name;
}
}

// Client code
Extensions.CopySlideTo(@"D:\temp\source.pptx", 1, @"D:\temp\dest.pptx");

现在当我打开结果 (d:\temp\dest.pptx) 时看到

enter image description here

但是,如果点击Repair,结果是ok的。

为什么会这样?如何解决?我怀疑幻灯片布局添加有问题。

最佳答案

幸运的是,我还是赢了:

public static void Copy(Stream sourcePresentationStream, uint copiedSlidePosition, Stream destPresentationStream)
{
using (var destDoc = PresentationDocument.Open(destPresentationStream, true))
{
var sourceDoc = PresentationDocument.Open(sourcePresentationStream, false);
var destPresentationPart = destDoc.PresentationPart;
var destPresentation = destPresentationPart.Presentation;

_uniqueId = GetMaxIdFromChild(destPresentation.SlideMasterIdList);
uint maxId = GetMaxIdFromChild(destPresentation.SlideIdList);

var sourcePresentationPart = sourceDoc.PresentationPart;
var sourcePresentation = sourcePresentationPart.Presentation;

int copiedSlideIndex = (int)--copiedSlidePosition;

int countSlidesInSourcePresentation = sourcePresentation.SlideIdList.Count();
if (copiedSlideIndex < 0 || copiedSlideIndex >= countSlidesInSourcePresentation)
throw new ArgumentOutOfRangeException(nameof(copiedSlidePosition));

SlideId copiedSlideId = sourcePresentationPart.Presentation.SlideIdList.ChildElements[copiedSlideIndex] as SlideId;
SlidePart copiedSlidePart = sourcePresentationPart.GetPartById(copiedSlideId.RelationshipId) as SlidePart;

SlidePart addedSlidePart = destPresentationPart.AddPart<SlidePart>(copiedSlidePart);

SlideMasterPart addedSlideMasterPart = destPresentationPart.AddPart(addedSlidePart.SlideLayoutPart.SlideMasterPart);


// Create new slide ID
maxId++;
SlideId slideId = new SlideId
{
Id = maxId,
RelationshipId = destDoc.PresentationPart.GetIdOfPart(addedSlidePart)
};
destPresentation.SlideIdList.Append(slideId);

// Create new master slide ID
_uniqueId++;
SlideMasterId slideMaterId = new SlideMasterId
{
Id = _uniqueId,
RelationshipId = destDoc.PresentationPart.GetIdOfPart(addedSlideMasterPart)
};
destDoc.PresentationPart.Presentation.SlideMasterIdList.Append(slideMaterId);

// change slide layout ID
FixSlideLayoutIds(destDoc.PresentationPart);

destDoc.PresentationPart.Presentation.Save();
}
sourcePresentationStream.Close();
destPresentationStream.Close();
}

关于c# - 使用 Open XML SDK 将幻灯片从一个演示文稿复制到另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49453527/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com