I am trying to generated Presentations from different sources. Basically I have about 200 slides from a number of PowerPoint presentations. In order to accomplish this I'm using OpenXml Sdk. The flow of the program is as follows:
- open template presentation
- open new presentation
- merge the slides from the second presentation into the template presentation
At the end I'm saving the new Presentation to the disk. Trying to open it with PowerPoint 2013 breaks it, with the following info: Problem signature:
Problem Event Name: APPCRASH
Application Name: POWERPNT.EXE
Application Version: 15.0.4454.1000
Application Timestamp: 509a3abf
Fault Module Name: oart.dll
Fault Module Version: 15.0.4605.1000
Fault Module Timestamp: 531f9b2a
Exception Code: c00000fd
Exception Offset: 00003051
OS Version: 6.2.9200.2.0.0.272.7
Locale ID: 1033
Additional information about the problem:
LCID: 1033
skulcid: 1033
Opening it with PowerPoint 2010
however works just fine. There is no problem with it.
This is the code:
private static void MergePresentation(string generatedPresentation, string presentationToBeMerged)
{
try
{
int id = 0;
// Open the destination presentation.
using (PresentationDocument generatedPresentationDeck = PresentationDocument.Open(generatedPresentation, true))
{
PresentationPart generatedPresentationPart = generatedPresentationDeck.PresentationPart;
// If the merged presentation does not have a SlideIdList
// element yet, add it.
if (generatedPresentationPart.Presentation.SlideIdList == null)
{
generatedPresentationPart.Presentation.SlideIdList = new SlideIdList();
}
// Open the source presentation. This will throw an exception if
// the source presentation does not exist.
using (PresentationDocument mySourceDeck = PresentationDocument.Open(presentationToBeMerged, false))
{
PresentationPart sourcePresPart = mySourceDeck.PresentationPart;
// Get unique ids for the slide master and slide lists
// for use later.
_uniqueId = GetMaxSlideMasterId(generatedPresentationPart.Presentation.SlideMasterIdList);
uint maxSlideId = GetMaxSlideId(generatedPresentationPart.Presentation.SlideIdList);
// Copy each slide in the source presentation, in order, to
// the destination presentation.
foreach (SlideId slideId in sourcePresPart.Presentation.SlideIdList)
{
SlidePart sp;
SlidePart destSp;
SlideMasterPart destMasterPart;
string relId;
SlideMasterId newSlideMasterId;
SlideId newSlideId;
// Create a unique relationship id.
id++;
sp = (SlidePart)sourcePresPart.GetPartById(slideId.RelationshipId);
//sp.Slide.Transition.Remove();
relId = Path.GetFileNameWithoutExtension(presentationToBeMerged).Replace(" ", "_") + id;
// Add the slide part to the destination presentation.
destSp = generatedPresentationPart.AddPart<SlidePart>(sp, relId);
// The slide master part was added. Make sure the
// relationship between the main presentation part and
// the slide master part is in place.
destMasterPart = destSp.SlideLayoutPart.SlideMasterPart;
generatedPresentationPart.AddPart(destMasterPart);
// Add the slide master id to the slide master id list.
_uniqueId++;
newSlideMasterId = new SlideMasterId();
newSlideMasterId.RelationshipId = generatedPresentationPart.GetIdOfPart(destMasterPart);
newSlideMasterId.Id = _uniqueId;
generatedPresentationPart.Presentation.SlideMasterIdList.Append(newSlideMasterId);
// Add the slide id to the slide id list.
maxSlideId++;
newSlideId = new SlideId();
newSlideId.RelationshipId = relId;
newSlideId.Id = maxSlideId;
generatedPresentationPart.Presentation.SlideIdList.Append(newSlideId);
}
// Make sure that all slide layout ids are unique.
FixSlideLayoutIds(generatedPresentationPart);
}
// Save the changes to the destination deck.
generatedPresentationPart.Presentation.Save();
}
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// Find the maximum value of ID of all slide masters
/// </summary>
/// <param name="slideMasterIdList" />
/// <returns>
private static uint GetMaxSlideMasterId(SlideMasterIdList slideMasterIdList)
{
// Slide master identifiers have a minimum value of greater than
// or equal to 2147483648.
uint max = 2147483648;
if (slideMasterIdList != null)
// Get the maximum id value from the current set of children.
foreach (SlideMasterId child in
slideMasterIdList.Elements<SlideMasterId>())
{
uint id = child.Id;
if (id > max)
max = id;
}
return max;
}
/// <summary>
/// Find the maximum ID of all slides
/// </summary>
/// <param name="slideIdList" />
/// <returns>
private static uint GetMaxSlideId(SlideIdList slideIdList)
{
// Slide identifiers have a minimum value of greater than or
// equal to 256 and a maximum value of less than 2147483648.
uint max = 256;
if (slideIdList != null)
// Get the maximum id value from the current set of children.
foreach (SlideId child in slideIdList.Elements<SlideId>())
{
uint id = child.Id;
if (id > max)
max = id;
}
return max;
}
/// <summary>
/// Fix the IDs of all slide layouts by making sure that all the slide layout IDs in the
/// destination slide are unique.
/// </summary>
/// <param name="presPart" />
private 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();
}
}
The way I call the Merge function is:
string templateFilePath = @"C:\Users\mm\Desktop\testing pp\Presentation1.pptx";
string newFilePath = @"C:\Users\mm\Desktop\testing pp\Generated Presentation-105.pptx";
MergePresentation(templateFilePath, newFilePath);
Any ideas?
Thanks