none
Interested to split and merge Powerpoint Presentation RRS feed

  • Question

  •  

    Hi,

          Can anybody help me in splitting a pptx file into individual pptx files having exaclty one slide in each file based on number of slides in source pptx. Then merge these files into a single pptx file. i.e.,

     

    source pptx with 3 slides --- split---> (slide1.pptx, slide2.pptx, slide3.pptx) --- Merge ---> Destination pptx with 3 slides.

    Tuesday, October 23, 2007 7:08 AM

All replies

  • I'm not testing this but I'l tell you my first (what I think I should do put in your place ).

    It's not easy but not too difficult as I see. The problem here is that you can't merely change the slide's stream beacuse it's associated with other files into the package (like the SlideLayout files)

    1)Save a copy (using Powerpoint)  with only 1 slide (any)

    2)Change the XML content of the slide with the XML content of another slide in the original file.

    3)Open the .pptx with Powerpoint

    3)The slide will not be equal to the original because of the included relations

    4)Pull of each one of the differences to get the relation involved (the documentation will help you)

    5)Start real coding here...

    Wednesday, October 31, 2007 2:33 PM
  • HELP

    I need to combine 4 different pptx packages. Is that possible, so that they run consecutively ?

    Friday, May 16, 2008 1:00 PM
  • Same styles, same template, same design?

    (or n differents pptx)

     

    Friday, August 1, 2008 5:45 PM
  • 你好 我实现了一部分(将pptx 拆分为 slide1.pptx,slide2.pptx,slide3.pptx

    Hello I implemented part of it (split PPTX into slide1. PPTX, slide2. PPTX, slide3. PPTX)

    我的方法是使用删除来实现的,可以作为参考

    • My method is to use delete to achieve, can be used as a reference

    以下是我实现的方式:

      • Here's how I did it:

    新建文件 OpenXmlPptHelp.cs 

    • Create a new file openxmlppthelp.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using DocumentFormat.OpenXml.Presentation;
    using DocumentFormat.OpenXml.Packaging;
    using Drawing = DocumentFormat.OpenXml.Drawing;
    
    namespace PowerPointAddIn.Vstor
    {
        /// <summary>
        /// OpenXml帮助类。注意:所有的幻灯片的索引从0开始,vsto的索引从1开始
        /// </summary>
        public class OpenXmlPptHelp
        {
            /// <summary>
            /// 计算演示文稿中的幻灯片。
            /// </summary>
            /// <param name="presentationFile"></param>
            /// <returns></returns>
            public static int CountSlides(string presentationFile)
            {
                //以只读方式打开表示。
                using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
                {
                    // 将演示传递给下一个CountSlides方法
                    // 返回幻灯片计数。
                    return CountSlides(presentationDocument);
                }
            }
    
            /// <summary>
            /// 计算演示文稿中的幻灯片。
            /// </summary>
            /// <param name="presentationDocument"></param>
            /// <returns></returns>
            public static int CountSlides(PresentationDocument presentationDocument)
            {
                //检查空文档对象。
                if (presentationDocument == null)
                {
                    throw new ArgumentNullException("presentationDocument");
                }
    
                int slidesCount = 0;
    
                // 获取文档的演示部分。
                PresentationPart presentationPart = presentationDocument.PresentationPart;
    
                // 从SlideParts获取幻灯片计数。
                if (presentationPart != null)
                {
                    slidesCount = presentationPart.SlideParts.Count();
                }
    
                // 将幻灯片计数返回到前面的方法。
                return slidesCount;
            }
    
            /// <summary>
            /// 从演示文稿中删除指定的幻灯片。
            /// </summary>
            public static void DeleteSlide(string presentationFile, int slideIndex)
            {
                // 以读/写的方式打开源文档。
                using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
                {
                    //将要删除的源文档和幻灯片的索引传递给下一个DeleteSlide方法。
                    DeleteSlide(presentationDocument, slideIndex);
                }
            }
    
            /// <summary>
            /// 从演示文稿中保留指定的幻灯片。
            /// </summary>
            public static void ReserveSlide(string presentationFile, int slideIndex)
            {
                // 以读/写的方式打开源文档。
                using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
                {
                    int count = CountSlides(presentationDocument);
                    //删除的幻灯片索引
                    int index = 0;
                    for (int i = 0; i < count; i++)
                    {
                        if (i == slideIndex)
                        {
                            //保留此幻灯片
                            index ++;
                            continue;
                        }
    
                        //将要删除的源文档和幻灯片的索引传递给下一个DeleteSlide方法。
                        DeleteSlide(presentationDocument, index);
                    }
                }
            }
    
            /// <summary>
            /// 从演示文稿中删除指定的幻灯片。
            /// </summary>
            public static void DeleteSlide(PresentationDocument presentationDocument, int slideIndex)
            {
                if (presentationDocument == null)
                {
                    throw new ArgumentNullException("presentationDocument");
                }
    
                // 使用CountSlides示例获得演示文稿中的幻灯片数量。
                int slidesCount = CountSlides(presentationDocument);
    
                if (slideIndex < 0 || slideIndex >= slidesCount)
                {
                    throw new ArgumentOutOfRangeException("slideIndex");
                }
    
                // 从演示文稿文档中获取演示文稿部分。
                PresentationPart presentationPart = presentationDocument.PresentationPart;
    
                // 从演示部分获取演示文稿。
                Presentation presentation = presentationPart.Presentation;
    
                // 获取演示文稿中的幻灯片id列表。
                SlideIdList slideIdList = presentation.SlideIdList;
    
                // 获取指定幻灯片的幻灯片ID
                SlideId slideId = slideIdList.ChildElements[slideIndex] as SlideId;
    
                // 获取幻灯片中的关系ID。
                string slideRelId = slideId.RelationshipId;
    
                // 从幻灯片列表中删除幻灯片。
                slideIdList.RemoveChild(slideId);
    
                // 从所有自定义显示中删除对幻灯片的引用。
                if (presentation.CustomShowList != null)
                {
                    // 遍历自定义显示列表。
                    foreach (var customShow in presentation.CustomShowList.Elements<CustomShow>())
                    {
                        if (customShow.SlideList != null)
                        {
                            // 声明幻灯片列表项的链接列表。
                            LinkedList<SlideListEntry> slideListEntries = new LinkedList<SlideListEntry>();
                            foreach (SlideListEntry slideListEntry in customShow.SlideList.Elements())
                            {
                                // 找到要从自定义显示中移除的幻灯片引用。
                                if (slideListEntry.Id != null && slideListEntry.Id == slideRelId)
                                {
                                    slideListEntries.AddLast(slideListEntry);
                                }
                            }
    
                            // 从自定义放映中删除对幻灯片的所有引用。
                            foreach (SlideListEntry slideListEntry in slideListEntries)
                            {
                                customShow.SlideList.RemoveChild(slideListEntry);
                            }
                        }
                    }
                }
    
                // 保存修改后的表示。
                presentation.Save();
    
                // 获取指定幻灯片的幻灯片部分。
                SlidePart slidePart = presentationPart.GetPartById(slideRelId) as SlidePart;
    
                // 删除 slidePart.
                presentationPart.DeletePart(slidePart);
            }
    
            /// <summary>
            /// 将幻灯片移动到演示文稿中幻灯片顺序中的不同位置。
            /// </summary>
            /// <param name="presentationFile"></param>
            /// <param name="from"></param>
            /// <param name="to"></param>
            public static void MoveSlide(string presentationFile, int from, int to)
            {
                using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
                {
                    MoveSlide(presentationDocument, from, to);
                }
            }
            /// <summary>
            /// 将幻灯片移动到演示文稿中幻灯片顺序中的不同位置。
            /// </summary>
            /// <param name="presentationDocument"></param>
            /// <param name="from"></param>
            /// <param name="to"></param>
            public static void MoveSlide(PresentationDocument presentationDocument, int from, int to)
            {
                if (presentationDocument == null)
                {
                    throw new ArgumentNullException("presentationDocument");
                }
    
                // 调用CountSlides方法来获得演示文稿中的幻灯片数量。
                int slidesCount = CountSlides(presentationDocument);
    
                // 验证from和to位置都在范围内,并且彼此不同。
                if (from < 0 || from >= slidesCount)
                {
                    throw new ArgumentOutOfRangeException("from");
                }
    
                if (to < 0 || from >= slidesCount || to == from)
                {
                    throw new ArgumentOutOfRangeException("to");
                }
    
                // 从演示文稿文档中获取演示文稿部分。
                PresentationPart presentationPart = presentationDocument.PresentationPart;
    
                // 幻灯片计数不是零,因此演示文稿必须包含幻灯片。
                Presentation presentation = presentationPart.Presentation;
                SlideIdList slideIdList = presentation.SlideIdList;
    
    
                //获取源幻灯片的幻灯片ID。
                SlideId sourceSlide = slideIdList.ChildElements[from] as SlideId;
    
                SlideId targetSlide = null;
    
                // 确定目标幻灯片的位置,然后移动源幻灯片。
                if (to == 0)
                {
                    targetSlide = null;
                }
                else if (from < to)
                {
                    targetSlide = slideIdList.ChildElements[to] as SlideId;
                }
                else
                {
                    targetSlide = slideIdList.ChildElements[to - 1] as SlideId;
                }
    
                // 从其当前位置移除源幻灯片。
                sourceSlide.Remove();
    
                // 将源幻灯片插入到目标幻灯片之后的新位置。
                slideIdList.InsertAfter(sourceSlide, targetSlide);
    
                // 保存修改后的表示。
                presentation.Save();
            }
    
            /// <summary>
            /// 在源文档中移动TextBody形状中的段落范围转换为目标文档中的另一个TextBody形状。
            /// </summary>
            /// <param name="sourceFile"></param>
            /// <param name="targetFile"></param>
            public static void MoveParagraphToPresentation(string sourceFile, string targetFile)
            {
                // 以读/写的方式打开源文件。
                using (PresentationDocument sourceDoc = PresentationDocument.Open(sourceFile, true))
                {
                    // 以读/写的方式打开源文件。
                    using (PresentationDocument targetDoc = PresentationDocument.Open(targetFile, true))
                    {
                        // 获取源演示文稿中的第一张幻灯片。
                        SlidePart slide1 = GetFirstSlide(sourceDoc);
    
                        // 获取其中的第一个TextBody形状。
                        TextBody textBody1 = slide1.Slide.Descendants<TextBody>().First();
    
                        // 获取文本的第一段。
                        // 注意:“Drawing”是名称空间 DocumentFormat.OpenXml.Drawing 的别名
                        Drawing.Paragraph p1 = textBody1.Elements<Drawing.Paragraph>().First();
    
                        // 在目标演示中获得第一张幻灯片。
                        SlidePart slide2 = GetFirstSlide(targetDoc);
    
                        // 获取其中的第一个TextBody形状。
                        TextBody textBody2 = slide2.Slide.Descendants<TextBody>().First();
    
                        // 克隆源段落并插入克隆的段落。段落变成目标文本的形状。
                        // 传递“true”将创建一个深度克隆,它将创建
                        // 段落对象以及该对象直接或间接引用的所有内容。
                        textBody2.Append(p1.CloneNode(true));
    
                        //从源文件中删除源段落。
                        textBody1.RemoveChild<Drawing.Paragraph>(p1);
    
                        // 用占位符替换删除的段落。
                        textBody1.AppendChild<Drawing.Paragraph>(new Drawing.Paragraph());
    
                        //将幻灯片保存到源文件中。
                        slide1.Slide.Save();
    
                        // 将幻灯片保存到目标文件中。
                        slide2.Slide.Save();
                    }
                }
            }
    
            // 在演示文档中获取第一张幻灯片的 slidePart
            public static SlidePart GetFirstSlide(PresentationDocument presentationDocument)
            {
                // 获取第一张幻灯片的关系ID
                PresentationPart part = presentationDocument.PresentationPart;
                SlideId slideId = part.Presentation.SlideIdList.GetFirstChild<SlideId>();
                string relId = slideId.RelationshipId;
    
                // 通过关系ID获取幻灯片部分。
                SlidePart slidePart = (SlidePart)part.GetPartById(relId);
    
                return slidePart;
            }
    
        }
    }
    

    这样子使用:

    Use it this way:

            /// <summary>
            /// 输出为模板文件
            /// </summary>
            /// <param name="slideIndex">幻灯片索引</param>
            /// <param name="FileDir">输出文件夹</param>
            /// <returns>路径</returns>
            public string ExportPotx(int slideIndex, string FileDir)
            {
                FileDir = @"D:\test\";
    
                if (!Directory.Exists(FileDir))//如果不存在就创建文件夹  
                    Directory.CreateDirectory(FileDir);
    
                string name = Path.GetFileNameWithoutExtension(ppt.Name);
                string filePath = Path.Combine(FileDir, name + "_" + slideIndex + ".potx");
    
                //是否为wps
                if (!IsWps())
                {
                    ppt.Slides[slideIndex].Export(filePath, "potx");
                }
                else
                {
                    ppt.SaveCopyAs(filePath, PpSaveAsFileType.ppSaveAsOpenXMLTemplate, MsoTriState.msoTrue);
                    OpenXmlPptHelp.ReserveSlide(filePath, slideIndex - 1);
                }
    
                return filePath;
            }

    核心代码:OpenXmlPptHelp.ReserveSlide(filePath, slideIndex - 1);

    The core code: OpenXmlPptHelp ReserveSlide (filePath, slideIndex - 1);

    然后筛选出每一页:

    Then select each page:

                PptHelp pptHelp = new PptHelp();
                foreach (Slide slide in pptHelp.ppt.Slides)
                {
                    pptHelp.ExportPotx(slide.SlideIndex, "");
                }

    说明:我是结合VSTO和OpenXml实现的,只有第一个代码块是纯openxml,OpenXmlPptHelp.cs 类库可以完成你需要的{将pptx 拆分为 slide1.pptx,slide2.pptx,slide3.pptx}这一个功能。I combine VSTO and OpenXml, only the first code block is pure OpenXml, openxmlppthelp.cs class library can complete you need to {PPTX split into slide1.pptx, slide2.pptx, slide3.pptx} this function.

    Wednesday, November 6, 2019 8:17 AM