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
I was able to create a starting point similar to your (create a presentation and add a table to it). The code is not super easy nor short, but I wasn't able to reduce it. Still, it produces a new powerpoint with a table in the first page!
Code took by Microsoft DOC and Microsoft sample