Search code examples
c#powerpointgembox-presentation

C# Add images and text to PowerPoint slides


I'm trying to add images from a folder and their names below each image. In master slide[0] there should be Title. My problem is that my code is generating single PowerPoint file for each image instead of adding all images to one PowerPoint file. Can someone help me with my come or simar code that can work out

I've attached an image of what I'm trying to achieve. Here's the code I'm working with using C# and GemBoxPresentation API:

    //Create new powerpoint presentation
        var presentation = new PresentationDocument();
        //change the path format
        string dir = txtPath.Text.Replace("/", "\\");
        fontRootFolder = dir.Replace(Path.GetDirectoryName(dir) + Path.DirectorySeparatorChar, "");
        string workingPath = Application.StartupPath + @"\Zip Extracts\" + fontRootFolder + "\\png";

        if (Directory.Exists(workingPath))
        {
            // Get the directory
            DirectoryInfo ImagePath = new DirectoryInfo(workingPath);
            // Using GetFiles() method to get list of all png files present in the png folder
            FileInfo[] Files = ImagePath.GetFiles();
            foreach (FileInfo fi in Files)
            {
                for (int i = 0; i < fi.Length; i++)
                {
                    Cursor = Cursors.WaitCursor;
                    // Get slide size.
                    var size = presentation.SlideSize;

                    // Set slide size.
                    size.SizedFor = SlideSizeType.OnscreenShow16X10;
                    size.Orientation = GemBox.Presentation.Orientation.Landscape;
                    size.NumberSlidesFrom = 1;

                    // Create new presentation slide.
                    var slide = presentation.Slides.AddNew(SlideLayoutType.Custom);

                    // Create first picture from path.
                    Picture picture = null;
                    using (var stream = File.OpenRead(fi.FullName))
                        picture = slide.Content.AddPicture(PictureContentType.Png, stream, 1.45, 1.35, 1.45, 1.35, LengthUnit.Centimeter);

                    var textBox = slide.Content.AddTextBox(ShapeGeometryType.Rectangle, 1.03, 1.03, 6, 6, LengthUnit.Centimeter);

                    var paragraph = textBox.AddParagraph();
                    paragraph.Format.Alignment = GemBox.Presentation.HorizontalAlignment.Center;

                    paragraph.AddRun(fi.Name);

                    SaveFileDialog sfd = new SaveFileDialog();
                    sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    sfd.Title = "Save PowerPoint Icons";
                    sfd.CheckFileExists = false;
                    sfd.CheckPathExists = true;
                    sfd.DefaultExt = "pptx";
                    sfd.Filter = "Powerpoint Files (*.pptx) | *.pptx";
                    sfd.FilterIndex = 1;
                    sfd.RestoreDirectory = true;
                    if (sfd.ShowDialog() == DialogResult.OK)
                    {
                        //string file = sfd.FileName;
                        presentation.Save(sfd.FileName);
                        Cursor = Cursors.Default;
                    }
                    Cursor = Cursors.Default;
                }
            }
        }

Expected PowerPoint output


Solution

  • I developed a similar tool.

    The base class:

    using System;
    using System.Collections.Generic;
    
    namespace akGraphics2Pptx
    {
        class GraphicsConverter
        {
            static string[] usageText =
            {
                "akGraphics2Pptx - Graphics to Powerpoint/PDF Converter",
                "------------------------------------------------------",
                "",
                "Usage:",
                "",
                "akGraphics2Pptx graphics_file [graphics_file ...] output_file",
                "",
                "Enter more than one graphics file name to get more than one slide.",
                "Type of output file can be .pptx or .pdf",
                ""
            };
    
            protected IEnumerable<string> getFileNames(string[] args, string[] extensions)
            {
                List<string> names = new List<string>();
    
                foreach (string arg in args)
                {
                    foreach (string ext in extensions)
                    {
                        if (arg.ToLower().EndsWith("." + ext))
                        {
                            names.Add(arg);
                            break;
                        }
                    }
                }
    
                return names;
            }
    
            /// <summary>
            /// Create a Powerpoint file with one slide per graphics file argument.
            /// The arguments can have any order. The files are distinguished by their extensions.
            /// </summary>
            /// <param name="args">The arguments</param>
            public virtual void convert(string[] args)
            {
            }
    
            protected void usage()
            {
                foreach (string s in usageText)
                {
                    Console.WriteLine(s);
                }
            }
        }
    }
    

    The specific converter for PowerPoint output (I also have a PDF output):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Ppt = Microsoft.Office.Interop.PowerPoint;
    using static Microsoft.Office.Core.MsoTriState;
    using System.IO;
    
    namespace akGraphics2Pptx
    {
        class Graphics2PptxConverter : GraphicsConverter
        {
            private static string[] knownGraphicsFileExtensions = { "gif", "jpg", "png", "tif", "bmp", "wmf", "emf" };
            private static string[] powerpointFileExtensions = { "ppt", "pptx" };
    
            private IEnumerable<string> getGraphicsFileNames(string[] args)
            {
                return getFileNames(args, knownGraphicsFileExtensions);
            }
    
            private IEnumerable<string> getPowerpointFileNames(string[] args)
            {
                return getFileNames(args, powerpointFileExtensions);
            }
    
            /// <summary>
            /// Create a Powerpoint file with one slide per graphics file argument.
            /// The arguments can have any order. The files are distinguished by their extensions.
            /// </summary>
            /// <param name="args">The arguments</param>
            public void convert(string[] args)
            {
                var graphicsFileNames = getGraphicsFileNames(args);
                var powerpointFileNames = getPowerpointFileNames(args);
    
                if (!graphicsFileNames.Any() || (powerpointFileNames.Count() != 1))
                {
                    usage();
                }
                else
                {
                    //  inspired by http://stackoverflow.com/a/26372266/1911064
    
                    Ppt.Application pptApplication = new Ppt.Application();
    
                    // Create the Presentation File
                    Ppt.Presentation pptPresentation = 
                        pptApplication.Presentations.Add(WithWindow: msoFalse);
    
                    Ppt.CustomLayout customLayout = 
                        pptPresentation.SlideMaster.CustomLayouts[Ppt.PpSlideLayout.ppLayoutText];
    
                    foreach (string graphicsFileName in graphicsFileNames)
                    {
                        if (!File.Exists(graphicsFileName))
                        {
                            Console.WriteLine($"Graphics file {graphicsFileName} not found!");
                        }
                        else
                        {
                            // Create new Slide
                            Ppt.Slides slides = pptPresentation.Slides;
                            Ppt._Slide slide =
                                slides.AddSlide(Index: slides.Count + 1, pCustomLayout: customLayout);
    
                            // Add title
                            Ppt.TextRange objText = slide.Shapes[1].TextFrame.TextRange;
                            objText.Text = Path.GetFileName(graphicsFileName);
                            objText.Font.Name = "Arial";
                            objText.Font.Size = 32;
    
                            Ppt.Shape shape = slide.Shapes[2];
                            objText = shape.TextFrame.TextRange;
                            objText.Text = "Content goes here\nYou can add text";
    
                            string fullName = Path.GetFullPath(graphicsFileName);
                            slide.Shapes.AddPicture(fullName, msoFalse, msoTrue, shape.Left, shape.Top, shape.Width, shape.Height);
    
                            slide.NotesPage.Shapes[2].TextFrame.TextRange.Text = graphicsFileName;
                        }
                    }
    
                    string pptFullName = Path.GetFullPath(powerpointFileNames.First());
                    Console.WriteLine("Powerpoint file created: " + pptFullName);
                    Console.WriteLine("Graphics slides:         " + pptPresentation.Slides.Count);
                    Console.WriteLine("");
    
                    pptPresentation.SaveAs(pptFullName, Ppt.PpSaveAsFileType.ppSaveAsDefault, msoTrue);
                    pptPresentation.Close();
                    pptApplication.Quit();
                }
            }
        }
    }