简体   繁体   English

使用openXML创建模板演示文稿“.potx”的副本到新的“.pptx”

[英]create a copy of template presentation “.potx” to a new “.pptx” using openXML

I have a powerpoint template with .potx extension, i need to create a copy of the template file, but the created file does not have any content present in it, it is a blank presentation, below is the function i am using to create a destination file using template file. 我有一个扩展名为.potx的powerpoint模板,我需要创建一个模板文件的副本,但创建的文件中没有任何内容,它是一个空白的演示文稿,下面是我用来创建一个目标文件使用模板文件。

    /// <summary>
    /// Creates a copy of the source template file
    /// </summary>
    /// <param name="sourceFile">sourcce file which has to be copied</param>
    /// <param name="destinationFile">destination file where the new file has to be placed.</param>
       public static void CreateFileFromTemplate(this string sourceFile, string destinationFile)
    {
        try
        {
            //File.Copy(sourceFile, destinationFile, true);
            if (System.IO.Path.GetExtension(sourceFile) == ".potx")
            {
                if (System.IO.Path.GetExtension(destinationFile) == ".potx")
                {
                    PresentationDocument destinationDoc = PresentationDocument.Create(destinationFile, PresentationDocumentType.Presentation);
                    PresentationPart presentationPart = destinationDoc.AddPresentationPart();
                    presentationPart.Presentation = new Presentation();
                    presentationPart.Presentation.Save();
                    destinationDoc.Close();
                    //Package destinationPackage = Package.Open(destinationFile, FileMode.Open, FileAccess.ReadWrite);
                    using (destinationDoc = PresentationDocument.Open(destinationFile, true))
                    {
                        Package templatePackage = Package.Open(sourceFile, FileMode.Open);
                        using (PresentationDocument templateDocument = PresentationDocument.Open(templatePackage))
                        {
                            PresentationPart sourcePresPart = templateDocument.PresentationPart;
                            PresentationPart destinationPresrPart = destinationDoc.PresentationPart;
                            //var templateSlideCount = templateDocument.CountSlides();
                            //for (int slides = 1; slides <= templateSlideCount; slides++)
                            //{

                            //}
                            SlidePart sourceSlidePart;
                            SlidePart destinationSlidePart;
                            foreach (SlideId slideId in sourcePresPart.Presentation.SlideIdList)
                            {
                                //int i=0;

                                sourceSlidePart = (SlidePart)sourcePresPart.GetPartById(slideId.RelationshipId);
                                destinationSlidePart = sourceSlidePart.Clone();
                                SlideIdList slideIdList = destinationPresrPart.Presentation.SlideIdList;

                                destinationPresrPart.AddPart(destinationSlidePart);
                                // Save the modified presentation.
                                destinationPresrPart.Presentation.Save();
                            }
                        }
                    }
                }
                else
                {
                    throw new FileFormatException("Invalid destination file format, Valid file should have .pptx as extension");
                }
            }
            else
            {
                throw new FileFormatException("Invalid file format, Valid file should have .potx as extension");
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }

Extension method used to clone a slide 用于克隆幻灯片的扩展方法

    /// <summary>
    /// Clones the specified slide.
    /// </summary>
    /// <param name="sourceSlide">The slide to clone.</param>
    /// <returns>Cloned slide.</returns>
    public static SlidePart Clone(this SlidePart sourceSlide)
    {
        // find the presentationPart: makes the API more fluent
        var presentationPart = sourceSlide.GetParentParts()
            .OfType<PresentationPart>()
            .Single();

        // clone slide contents
        Slide currentSlide = (Slide)sourceSlide.Slide.CloneNode(true);
        var slidePartClone = presentationPart.AddNewPart<SlidePart>();

        currentSlide.Save(slidePartClone);

        // copy layout part
        slidePartClone.AddPart(sourceSlide.SlideLayoutPart);

        //copy all embedded elements
        foreach (ChartPart part in sourceSlide.ChartParts)
        {
            ChartPart newpart = slidePartClone.AddNewPart<ChartPart>(part.ContentType, sourceSlide.GetIdOfPart(part));
            newpart.FeedData(part.GetStream());
            newpart.AddNewPart<EmbeddedPackagePart>(part.EmbeddedPackagePart.ContentType, part.GetIdOfPart(part.EmbeddedPackagePart));
            newpart.EmbeddedPackagePart.FeedData(part.EmbeddedPackagePart.GetStream());
        }
        foreach (EmbeddedObjectPart part in sourceSlide.EmbeddedObjectParts)
        {
            EmbeddedObjectPart newpart = slidePartClone.AddNewPart<EmbeddedObjectPart>(part.ContentType, sourceSlide.GetIdOfPart(part));
            newpart.FeedData(part.GetStream());
        }
        foreach (EmbeddedPackagePart part in sourceSlide.EmbeddedPackageParts)
        {
            EmbeddedPackagePart newpart = slidePartClone.AddNewPart<EmbeddedPackagePart>(part.ContentType, sourceSlide.GetIdOfPart(part));
            newpart.FeedData(part.GetStream());
        }
        foreach (ImagePart part in sourceSlide.ImageParts)
        {
            ImagePart newpart = slidePartClone.AddNewPart<ImagePart>(part.ContentType, sourceSlide.GetIdOfPart(part));
            newpart.FeedData(part.GetStream());
        }
        foreach (VmlDrawingPart part in sourceSlide.VmlDrawingParts)
        {
            VmlDrawingPart newpart = slidePartClone.AddNewPart<VmlDrawingPart>(part.ContentType, sourceSlide.GetIdOfPart(part));
            newpart.FeedData(part.GetStream());
        }
        foreach (UserDefinedTagsPart part in sourceSlide.UserDefinedTagsParts)
        {
            UserDefinedTagsPart newpart = slidePartClone.AddNewPart<UserDefinedTagsPart>(part.ContentType, sourceSlide.GetIdOfPart(part));
            newpart.FeedData(part.GetStream());
        }
        return slidePartClone;
    }

in my main method i have below code which calls these functions to create the ppt 在我的主要方法中,我有下面的代码调用这些函数来创建ppt

 string sourceFilePath =@"C:\TempFolder\template.potx";
 string destinationFilePath = @"C:\TempFolder\ClonedFile.potx";
 sourceFilePath.CreateFileFromTemplate(destinationFilePath);

but the final created ppt will not have any slides in it, 但是最终创建的ppt中没有任何幻灯片,

any help would be appreciated 任何帮助,将不胜感激

I posted a similar answer before on saving an excel template to an actual excel document here and you should be able to apply the same logic with a power point template. 我对储蓄Excel模板到实际的excel文档之前张贴了类似的答案在这里 ,你应该能够与电源点模板应用相同的逻辑。 Instead of the SpreadsheetDocument you will want to use the PresentationDocument and call ChangeDocumentType on it. 您将需要使用PresentationDocument并在其上调用ChangeDocumentType,而不是SpreadsheetDocument Something along these lines: 这些方面的东西:

byte[] byteArray = File.ReadAllBytes("C:\\temp\\sa123.potx");
using (MemoryStream stream = new MemoryStream())
{
    stream.Write(byteArray, 0, (int)byteArray.Length);
    using (PresentationDocument presentationDoc = PresentationDocument.Open(stream, true))
    {
       // Change from template type to presentation type
       presentationDoc.ChangeDocumentType(PresentationDocumentType.Presentation);
    }
    File.WriteAllBytes("C:\\temp\\sa123.pptx", stream.ToArray()); 
}

You can then reopen that saved file and do whatever extra stuff you want to it without touching the template file. 然后,您可以重新打开该已保存的文件,并在不触及模板文件的情况下执行您想要的任何额外操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM