我有下面的代码,我尝试将幻灯片从一个 ppt 复制到另一个 ppt。我这样做是因为第二个 ppt 已经在应用程序的另一个区域中实现了逻辑,现在我想将幻灯片加入到当前幻灯片中,以便在需要时获得所有可用信息。
我遇到的真正问题是,当第二个 ppt 包含不止一张幻灯片时,我会在打开最终报告时收到图片中出现的错误。
值得一提的是,对于单张幻灯片来说,一切正常,幻灯片的内容基本相同,因此我认为这与缺乏信息无关。
public ReportResult ExportEVReportToPowerPointFile(EVReport evReportData, string exportLanguage, string currentRequestUrl, MemoryStream topIssueStream)
{
var folderPath = _folderPathRepository.GetByCode($"EV-Report-{exportLanguage.ToUpperInvariant()}");
var reportTemplatePath = folderPath?.Path;
if (string.IsNullOrEmpty(reportTemplatePath))
{
return null;
}
var reportMS = _generateEVStatusReportService.ExportEVReportToPowerPointFile(evReportData, reportTemplatePath, exportLanguage, currentRequestUrl);
using (var reportPresentation = PresentationDocument.Open(reportMS, true))
using (var topIssuePresentation = PresentationDocument.Open(topIssueStream, true))
{
var reportPresentationPart = reportPresentation.PresentationPart;
var slideIdList = reportPresentationPart.Presentation.SlideIdList;
uint maxSlideId = slideIdList.ChildElements.Cast<SlideId>().Max(s => s.Id.Value);
foreach (var topIssueSlidePart in topIssuePresentation.PresentationPart.SlideParts)
{
// Clone the entire slide
CloneSlide(topIssueSlidePart, reportPresentationPart);
// Add the slide to the SlideIdList
var slideId = slideIdList.AppendChild(new SlideId());
slideId.Id = ++maxSlideId;
slideId.RelationshipId = reportPresentationPart.GetIdOfPart(reportPresentationPart.SlideParts.Last());
}
reportPresentation.Save();
}
var result = new ReportResult
{
RootPath = reportTemplatePath,
FilePath = reportTemplatePath,
Filename = evReportData.IsSnapshot ? $"EV_Snapshot_{DateTime.Now:dd_MM_yyyy}" : $"EV_Status_{DateTime.Now:dd_MM_yyyy}",
Base64EncodedFile = Convert.ToBase64String(reportMS.ToArray(), Base64FormattingOptions.None)
};
return result;
}
private void CloneSlide(SlidePart sourceSlidePart, PresentationPart destinationPresentationPart)
{
// Create a new slide part in the destination presentation
var newSlidePart = destinationPresentationPart.AddNewPart<SlidePart>();
// Copy the slide content
newSlidePart.FeedData(sourceSlidePart.GetStream());
// Copy the slide layout and its dependencies
if (sourceSlidePart.SlideLayoutPart != null)
{
SlideLayoutPart newSlideLayoutPart = GetOrCreateSlideLayoutPart(sourceSlidePart.SlideLayoutPart, destinationPresentationPart);
// Add the slide layout part to the new slide part
newSlidePart.AddPart(newSlideLayoutPart);
}
// Clone other related parts and their relationships
foreach (var part in sourceSlidePart.Parts)
{
if (!(part.OpenXmlPart is SlideLayoutPart))
{
var clonedPart = newSlidePart.AddPart(part.OpenXmlPart, part.RelationshipId);
clonedPart.FeedData(part.OpenXmlPart.GetStream());
}
}
}
private SlideLayoutPart GetOrCreateSlideLayoutPart(SlideLayoutPart sourceSlideLayoutPart, PresentationPart destinationPresentationPart)
{
SlideMasterPart sourceSlideMasterPart = sourceSlideLayoutPart.SlideMasterPart;
SlideMasterPart destinationSlideMasterPart = GetOrCreateSlideMasterPart(sourceSlideMasterPart, destinationPresentationPart);
// Find or create the slide layout part
SlideLayoutPart newSlideLayoutPart = destinationSlideMasterPart.SlideLayoutParts
.FirstOrDefault(slp => slp.Uri == sourceSlideLayoutPart.Uri);
if (newSlideLayoutPart == null)
{
newSlideLayoutPart = destinationSlideMasterPart.AddNewPart<SlideLayoutPart>();
newSlideLayoutPart.FeedData(sourceSlideLayoutPart.GetStream());
// Clone related parts like images, charts, etc.
foreach (var part in sourceSlideLayoutPart.Parts)
{
var clonedPart = newSlideLayoutPart.AddPart(part.OpenXmlPart, part.RelationshipId);
clonedPart.FeedData(part.OpenXmlPart.GetStream());
}
}
return newSlideLayoutPart;
}
private SlideMasterPart GetOrCreateSlideMasterPart(SlideMasterPart sourceSlideMasterPart, PresentationPart destinationPresentationPart)
{
// Find or create the slide master part
SlideMasterPart newSlideMasterPart = destinationPresentationPart.SlideMasterParts
.FirstOrDefault(smp => smp.Uri == sourceSlideMasterPart.Uri);
if (newSlideMasterPart == null)
{
newSlideMasterPart = destinationPresentationPart.AddNewPart<SlideMasterPart>();
newSlideMasterPart.FeedData(sourceSlideMasterPart.GetStream());
// Clone related parts like themes, fonts, etc.
foreach (var part in sourceSlideMasterPart.Parts)
{
var clonedPart = newSlideMasterPart.AddPart(part.OpenXmlPart, part.RelationshipId);
clonedPart.FeedData(part.OpenXmlPart.GetStream());
}
}
return newSlideMasterPart;
}
您可以使用 ShapeCrawler 库复制幻灯片:
var sourcePres = new Presentation("source.pptx");
var targetPres = new Presentation("target.pptx");
var copyingSlide = sourcePres.Slide(1);
targetPres.Slides.Add(copyingSlide);
sourcePres.SaveAs("result.pptx");