Presentation created in C# with the Open XML SDK is corrupted and blank when opened

skgowiser 0 Reputation points
2023-11-10T10:15:03.94+00:00

Problem

I am trying to create a PowerPoint presentation in C# with Visual Studio using the Open XML SDK.

The presentation I create contains one slide with one table with 3 rows and 2 columns.

When I try to open the PowerPoint presentation created by the program, I am presented with the following error message:

PowerPoint found a problem with content in test3.pptx.
PowerPoint can attempt to repair the presentation.

If you trust the source of this presentation, click Repair.

When I click Repair, I am presented with another error message:

PowerPoint couldn't read some content in test3.pptx - Repaired and removed it.

Please check your presentation to see if the rest looks ok.

When I click Ok and check the contents of the presentation, it is empty.

QUESTION

How should I modify the program, so users can open the presentations without problems?

  • Am I using the wrong version of the Open XML SDK?
  • Is there something wrong with the code I've written?
  • Are there tools I can use to assist me in tracking down the error?
  • Other?

The version of PowerPoint I use to open the .pptx file

Microsoft® PowerPoint® for Microsoft 365 MSO (Version 2310 Build 16.0.16924.20054) 64-bit

My console project looks like this

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
  </ItemGroup>
</Project>

My main program looks like this

var builder = new OpenXMLBuilder.Test3();
builder.Doit(args);

My source code looks like this

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using D = DocumentFormat.OpenXml.Drawing;

#region disable_warnings
// Remove unnecessary suppression
#pragma warning disable IDE0079
// Member 'x' does not access instance data and can be marked as static
#pragma warning disable CA1822
// Remove unused parameter 'x'
#pragma warning disable IDE0060
// 'using' statement can be simplified
#pragma warning disable IDE0063
// 'new' expression can be simplified
#pragma warning disable IDE0090
// Object initialization can be simplified
#pragma warning disable IDE0017
#endregion

namespace OpenXMLBuilder
{
    class Test3
    {
        public void Doit(string[] args)
        {
            string filepath = "test3.pptx";
            CreatePresentation(filepath);
        }

        public static void CreatePresentation(string filepath)
        {
            // Create a presentation at a specified file path.
            using (PresentationDocument presentationDocument = PresentationDocument.Create(filepath, PresentationDocumentType.Presentation))
            {
                PresentationPart presentationPart = presentationDocument.AddPresentationPart();
                presentationPart.Presentation = new Presentation();
                CreateSlide(presentationPart);
            }
        }

        private static void CreateSlide(PresentationPart presentationPart)
        {
            // Create the SlidePart.
            SlidePart slidePart = presentationPart.AddNewPart<SlidePart>();
            slidePart.Slide = new Slide(new CommonSlideData(new ShapeTree()));

            // Declare and instantiate the table
            D.Table table = new D.Table();

            // Define the columns
            D.TableGrid tableGrid = new D.TableGrid();
            tableGrid.Append(new D.GridColumn() { Width = 3124200 });
            tableGrid.Append(new D.GridColumn() { Width = 3124200 });

            // Append the TableGrid to the table
            table.Append(tableGrid);

            // Create the rows and cells
            for (int i = 0; i < 3; i++) // 3 rows
            {
                D.TableRow row = new D.TableRow() { Height = 370840 };
                for (int j = 0; j < 2; j++) // 2 columns
                {
                    D.TableCell cell = new D.TableCell();
                    D.TextBody body = new D.TextBody(new D.BodyProperties(),
                                                         new D.ListStyle(),
                                                         new D.Paragraph(new D.Run(new D.Text($"Cell {i + 1},{j + 1}"))));
                    cell.Append(body);
                    cell.Append(new D.TableCellProperties());
                    row.Append(cell);
                }
                table.Append(row);
            }

            // Create a GraphicFrame to hold the table
            GraphicFrame graphicFrame = new GraphicFrame();
            graphicFrame.NonVisualGraphicFrameProperties = new NonVisualGraphicFrameProperties(
                new NonVisualDrawingProperties() { Id = 1026, Name = "Table" },
                new NonVisualGraphicFrameDrawingProperties(),
                new ApplicationNonVisualDrawingProperties());
            graphicFrame.Transform = new Transform(new D.Offset() { X = 0L, Y = 0L }, new D.Extents() { Cx = 0L, Cy = 0L });
            graphicFrame.Graphic = new D.Graphic(new D.GraphicData(table)
            {
                Uri = "http://schemas.openxmlformats.org/drawingml/2006/table"
            });
            // Sanity check
            if (slidePart.Slide.CommonSlideData == null)
                throw new InvalidOperationException("CreateSlide: CommonSlideData is null");
            if (slidePart.Slide.CommonSlideData.ShapeTree == null)
                throw new InvalidOperationException("CreateSlide: ShapeTree is null");
            // Append the GraphicFrame to the SlidePart
            slidePart.Slide.CommonSlideData.ShapeTree.AppendChild(graphicFrame);
            // Save the slide part
            slidePart.Slide.Save();

            // Create slide master
            SlideMasterPart slideMasterPart = presentationPart.AddNewPart<SlideMasterPart>();
            slideMasterPart.SlideMaster = new SlideMaster(new CommonSlideData(new ShapeTree()));
            slideMasterPart.SlideMaster.Save();

            // Create slide layout
            SlideLayoutPart slideLayoutPart = slideMasterPart.AddNewPart<SlideLayoutPart>();
            slideLayoutPart.SlideLayout = new SlideLayout(new CommonSlideData(new ShapeTree()));
            slideLayoutPart.SlideLayout.Save();
            // Create unique id for the slide
            presentationPart.Presentation.SlideIdList = new SlideIdList(new SlideId()
            {
                Id = 256U,
                RelationshipId = presentationPart.GetIdOfPart(slidePart)
            });
            // Set the size
            presentationPart.Presentation.SlideSize = new SlideSize() { Cx = 9144000, Cy = 6858000 };

            // Save the presentation
            presentationPart.Presentation.Save();
        }
    } // class
} // namespace
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
9,491 questions
Office Development
Office Development
Office: A suite of Microsoft productivity software that supports common business tasks, including word processing, email, presentations, and data management and analysis.Development: The process of researching, productizing, and refining new or existing technologies.
3,058 questions
{count} votes