none
Copy a slide to another presentation

    Question

  • Sorry my English :)

    I created method to copy slide to another presentation

    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> 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

    CopySlideTo(@"d:\temp\source.pptx", 2, @"d:\temp\dest.pptx");

    Now when I open d:\temp\dest.pptx

    found a problem with content

    However, if click Repair result is ok.

    Why this is happend? How fix it? I suspect that something wrong with slide layout adding.



    lundi 26 mars 2018 08:59

Réponses

  • Luckily, I still pulled out the win:

    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();
    }

    • Marqué comme réponse adamShakhabov dimanche 1 avril 2018 20:41
    dimanche 1 avril 2018 20:41

Toutes les réponses

  • Hi adamShakhabov,

    I try to check your code and find that you did not post the full code.

    I can see that you are using method below.

    FixSlideLayoutIds(destPresentationPart);
    

    but this method is not available in your code.

    which generates an error.

    I suggest you to post your full code, so that we can try to make a test and try to find the issue in code.

    Regards

    Deepak


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    mardi 27 mars 2018 06:30
    Modérateur
  • Luckily, I still pulled out the win:

    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();
    }

    • Marqué comme réponse adamShakhabov dimanche 1 avril 2018 20:41
    dimanche 1 avril 2018 20:41