ARTICLE AD BOX
I am trying to create a new presentation with a single slide that contains an image. Every .pptx I make using OpenXml, when opening in PowerPoint, shows the following prompt:
PowerPoint found a problem with content in file.pptx. PowerPoint can attempt to repair the presentation
If I click repair, it repairs it and it shows up fine with the image. But I do not want that prompt every time, of course. I have used all the validation tools I could find (OpenXml's productivity code, in-code validation, ooxml, etc.) and none of them show an error.
The full code is shown here:
private const long EmusPerPoint = 12700L; private const long EmusPerInch = 914400L; private const int Left = 100; private const int Top = 100; private const uint SlideMasterId = 2147483648U; private const uint SlideLayoutId = 2147483649U; private const uint SlideId = 256U; public static void SendToPowerPoint(string imagePath) { try { var outputPath = Path.Combine( Path.GetTempPath(), $"tempPresentation-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.pptx" ); long cx; long cy; using (var bmp = System.Drawing.Image.FromFile(imagePath)) { cx = (long)(bmp.Width / bmp.HorizontalResolution * EmusPerInch); cy = (long)(bmp.Height / bmp.VerticalResolution * EmusPerInch); } long leftEmu = Left * EmusPerPoint; long topEmu = Top * EmusPerPoint; using (var pptx = PresentationDocument.Create(outputPath, PresentationDocumentType.Presentation)) { var presentationPart = pptx.AddPresentationPart(); presentationPart.Presentation = new Presentation(); var slideMasterPart = presentationPart.AddNewPart<SlideMasterPart>("rIdMaster"); var slideLayoutPart = slideMasterPart.AddNewPart<SlideLayoutPart>("rIdLayout"); slideLayoutPart.AddPart(slideMasterPart, "rIdMaster"); BuildSlideLayout(slideLayoutPart); BuildSlideMaster(slideMasterPart, slideLayoutPart); var slidePart = presentationPart.AddNewPart<SlidePart>("rIdSlide"); // reference the layout using SAME relationship ID slidePart.AddPart(slideLayoutPart, "rIdLayout"); // add image var imagePart = slidePart.AddImagePart(GetImagePartType(imagePath), "rIdImage"); using (var stream = File.OpenRead(imagePath)) imagePart.FeedData(stream); var picture = BuildPicture("rIdImage", leftEmu, topEmu, cx, cy); BuildSlide(slidePart, picture); var pres = presentationPart.Presentation; pres.SlideMasterIdList = new SlideMasterIdList( new SlideMasterId { Id = SlideMasterId, RelationshipId = "rIdMaster" }); pres.SlideIdList = new SlideIdList( new SlideId { Id = SlideId, RelationshipId = "rIdSlide" }); pres.SlideSize = new SlideSize { Cx = 9144000, Cy = 6858000 }; pres.NotesSize = new NotesSize { Cx = 6858000, Cy = 9144000 }; pres.DefaultTextStyle = new DefaultTextStyle(); pres.Save(); } System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo { FileName = outputPath, UseShellExecute = true }); } catch (Exception ex) { MessageBox.Show($"PowerPoint integration failed: {ex.Message}"); } } private static void BuildSlideLayout(SlideLayoutPart part) { part.SlideLayout = new SlideLayout( new CommonSlideData( new ShapeTree( new NonVisualGroupShapeProperties( new NonVisualDrawingProperties { Id = 1, Name = "" }, new NonVisualGroupShapeDrawingProperties(), new ApplicationNonVisualDrawingProperties() ), new GroupShapeProperties(new OpenXmlDrawing.TransformGroup()), new Shape( new NonVisualShapeProperties( new NonVisualDrawingProperties { Id = 2, Name = "Title Placeholder" }, new NonVisualShapeDrawingProperties(new OpenXmlDrawing.ShapeLocks { NoGrouping = true }), new ApplicationNonVisualDrawingProperties(new PlaceholderShape()) ), new ShapeProperties() ) ) ), new ColorMapOverride(new OpenXmlDrawing.MasterColorMapping()) ) { Type = SlideLayoutValues.Blank }; part.SlideLayout.Save(); } private static void BuildSlideMaster(SlideMasterPart masterPart, SlideLayoutPart layoutPart) { masterPart.SlideMaster = new SlideMaster( new CommonSlideData( new ShapeTree( new NonVisualGroupShapeProperties( new NonVisualDrawingProperties { Id = 1, Name = "" }, new NonVisualGroupShapeDrawingProperties(), new ApplicationNonVisualDrawingProperties() ), new GroupShapeProperties(new OpenXmlDrawing.TransformGroup()) ) ), new ColorMap { Background1 = OpenXmlDrawing.ColorSchemeIndexValues.Light1, Text1 = OpenXmlDrawing.ColorSchemeIndexValues.Dark1, Background2 = OpenXmlDrawing.ColorSchemeIndexValues.Light2, Text2 = OpenXmlDrawing.ColorSchemeIndexValues.Dark2, Accent1 = OpenXmlDrawing.ColorSchemeIndexValues.Accent1, Accent2 = OpenXmlDrawing.ColorSchemeIndexValues.Accent2, Accent3 = OpenXmlDrawing.ColorSchemeIndexValues.Accent3, Accent4 = OpenXmlDrawing.ColorSchemeIndexValues.Accent4, Accent5 = OpenXmlDrawing.ColorSchemeIndexValues.Accent5, Accent6 = OpenXmlDrawing.ColorSchemeIndexValues.Accent6, Hyperlink = OpenXmlDrawing.ColorSchemeIndexValues.Hyperlink, FollowedHyperlink = OpenXmlDrawing.ColorSchemeIndexValues.FollowedHyperlink }, new SlideLayoutIdList( new SlideLayoutId { Id = SlideLayoutId, RelationshipId = "rIdLayout" } ) ); masterPart.SlideMaster.Save(); } private static void BuildSlide(SlidePart part, Picture picture) { part.Slide = new Slide( new CommonSlideData( new ShapeTree( new NonVisualGroupShapeProperties( new NonVisualDrawingProperties { Id = 1, Name = "" }, new NonVisualGroupShapeDrawingProperties(), new ApplicationNonVisualDrawingProperties() ), new GroupShapeProperties(new OpenXmlDrawing.TransformGroup()), picture ) ), new ColorMapOverride(new OpenXmlDrawing.MasterColorMapping()) ); part.Slide.Save(); } private static Picture BuildPicture(string relId, long left, long top, long cx, long cy) { return new Picture( new NonVisualPictureProperties( new NonVisualDrawingProperties { Id = 2, Name = "Picture 1" }, new NonVisualPictureDrawingProperties(new OpenXmlDrawing.PictureLocks { NoChangeAspect = true }), new ApplicationNonVisualDrawingProperties() ), new BlipFill( new OpenXmlDrawing.Blip { Embed = relId }, new OpenXmlDrawing.Stretch(new OpenXmlDrawing.FillRectangle()) ), new ShapeProperties( new OpenXmlDrawing.Transform2D( new OpenXmlDrawing.Offset { X = left, Y = top }, new OpenXmlDrawing.Extents { Cx = cx, Cy = cy } ), new OpenXmlDrawing.PresetGeometry(new OpenXmlDrawing.AdjustValueList()) { Preset = OpenXmlDrawing.ShapeTypeValues.Rectangle } ) ); } private static ImagePartType GetImagePartType(string path) { switch (Path.GetExtension(path).ToLowerInvariant()) { case ".jpg": case ".jpeg": return ImagePartType.Jpeg; case ".png": return ImagePartType.Png; case ".gif": return ImagePartType.Gif; case ".bmp": return ImagePartType.Bmp; case ".tif": case ".tiff": return ImagePartType.Tiff; default: return ImagePartType.Png; } }