Search code examples
c#openxmlopenxml-sdk

Adding hyperlink to existing image using Open XML SDK


I am struggling to work out a concise way to do what I'd imagine would be quite simple... I have a simple existing PowerPoint presentation with one slide and in it one image.

I want to programatically open this with the Open XML SDK (hosted in a .Net Core web application) and add a hyperlink to this, and save it... such that when it's reopened in PowerPoint, one can control+click on the image to visit the link.

        using (var ppt = PresentationDocument.Open("powerpoint.pptx", true))
        {
            var image = ppt.PresentationPart.SlideParts.First().ImageParts.First();

            // Code to add hyperlink to image here - a bit like:
            // image.HyperLink = "http://somewebpage"

            ppt.Save();
        }

Solution

  • Thanks to the help from the comment from @Cindy Mester, I was able to strip down the suggested migration code from the Open XML SDK Productivity Tool to this:

            using (var ms = new MemoryStream())
            {
                var original = File.OpenRead("withoutlink.pptx");
                original.CopyTo(ms);
    
                using (var ppt = PresentationDocument.Open(ms, true))
                {
                    var slidePart1 = ppt.PresentationPart.SlideParts.First();
    
                    var slide1 = slidePart1.Slide;
    
                    var commonSlideData1 = slide1.GetFirstChild<CommonSlideData>();
    
                    var shapeTree1 = commonSlideData1.GetFirstChild<ShapeTree>();
    
                    var picture1 = shapeTree1.GetFirstChild<Picture>();
    
                    var nonVisualPictureProperties1 = picture1.GetFirstChild<NonVisualPictureProperties>();
    
                    var nonVisualDrawingProperties1 =
                        nonVisualPictureProperties1.GetFirstChild<NonVisualDrawingProperties>();
    
                    var nonVisualDrawingPropertiesExtensionList1 = nonVisualDrawingProperties1
                        .GetFirstChild<A.NonVisualDrawingPropertiesExtensionList>();
    
                    var relationshipId = "rId" + nonVisualPictureProperties1.Count();
    
                    var hyperlinkOnClick1 = new A.HyperlinkOnClick {Id = relationshipId};
                    nonVisualDrawingProperties1.InsertBefore(hyperlinkOnClick1,
                        nonVisualDrawingPropertiesExtensionList1);
    
                    slidePart1.AddHyperlinkRelationship(new Uri("http://www.google.com/", UriKind.Absolute), true,
                        relationshipId);
    
                    ppt.SaveAs("withlink.pptx");
                }
    

    In order that I could edit the file without modifying the original I copied to memory stream and opened that - In my web app I can the stream this memory stream back to the client.