Search code examples
c#ms-wordopenxmlopenxml-sdk

Insert picture to header of Word document with OpenXML


I know that there was same question here, however answers are kinda vague and do not show the full source code. I've got a method for generating a header, but it does not work(shows x on the image place).

public static void AddPicHeader(string docxFileName) {
        using(WordprocessingDocument doc = WordprocessingDocument.Open(docxFileName, true)) {
            var mainDocPart = doc.MainDocumentPart;
            var imgPart = mainDocPart.AddImagePart(ImagePartType.Png, "rId999");
            var image = GetImageFromFile(logoFileName);
            var imagePartID = mainDocPart.GetIdOfPart(imgPart);
            GenerateImagePartContent(imgPart, image);

            if(!mainDocPart.HeaderParts.Any()) {
                mainDocPart.DeleteParts(mainDocPart.HeaderParts);
                var newHeaderPart = mainDocPart.AddNewPart<HeaderPart>();
                var rId = mainDocPart.GetIdOfPart(newHeaderPart);
                var headerRef = new HeaderReference { Id = rId };
                var sectionProps = doc.MainDocumentPart.Document.Body.Elements<SectionProperties>().LastOrDefault();
                if(sectionProps == null) {
                    sectionProps = new SectionProperties();
                    doc.MainDocumentPart.Document.Body.Append(sectionProps);
                }
                sectionProps.RemoveAllChildren<HeaderReference>();
                sectionProps.Append(headerRef);
                newHeaderPart.Header = GeneratePicHeader(imagePartID);
                newHeaderPart.Header.Save();
            }
        }
    }

    private static Header GeneratePicHeader(string relationshipId) {
        var element =
            new Drawing(
                new DW.Inline(
                    new DW.Extent() { Cx = 990000L, Cy = 792000L },
                    new DW.EffectExtent() {
                        LeftEdge = 0L,
                        TopEdge = 0L,
                        RightEdge = 0L,
                        BottomEdge = 0L
                    },
                    new DW.DocProperties() {
                        Id = (UInt32Value)1U,
                        Name = "NIS Logo"
                    },
                    new DW.NonVisualGraphicFrameDrawingProperties(
                        new A.GraphicFrameLocks() { NoChangeAspect = true }),
                    new A.Graphic(
                        new A.GraphicData(
                            new PIC.Picture(
                                new PIC.NonVisualPictureProperties(
                                    new PIC.NonVisualDrawingProperties() {
                                        Id = (UInt32Value)0U,
                                        Name = "nis.png"
                                    },
                                    new PIC.NonVisualPictureDrawingProperties()),
                                new PIC.BlipFill(
                                    new A.Blip(
                                        new A.BlipExtensionList(
                                            new A.BlipExtension() {
                                                Uri =
                                                    "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                            })
                                    ) {
                                        Embed = relationshipId,
                                        CompressionState =
                                            A.BlipCompressionValues.Print
                                    },
                                    new A.Stretch(
                                        new A.FillRectangle())),
                                new PIC.ShapeProperties(
                                    new A.Transform2D(
                                        new A.Offset() { X = 0L, Y = 0L },
                                        new A.Extents() { Cx = 990000L, Cy = 792000L }),
                                    new A.PresetGeometry(
                                        new A.AdjustValueList()
                                    ) { Preset = A.ShapeTypeValues.Rectangle }))
                        ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
                ) {
                    DistanceFromTop = (UInt32Value)0U,
                    DistanceFromBottom = (UInt32Value)0U,
                    DistanceFromLeft = (UInt32Value)0U,
                    DistanceFromRight = (UInt32Value)0U,
                    EditId = "50D07946"
                });

        var header = new Header();
        var paragraph = new Paragraph();
        var run = new Run();

        run.Append(element);
        paragraph.Append(run);
        header.Append(paragraph);
        return header;
    }

Maybe someone dealt with hit?


Solution

  • Sorry if it was not clear on my previous answer (in linked question). I will try to make this one less vague.

    To insert an image in a header, you must add an ImagePart to the HeaderPart, not to the mainDocumentPart.

    public static void AddPicHeader(string docxFileName) {
        using(WordprocessingDocument doc = WordprocessingDocument.Open(docxFileName, true)) {
    
            var mainDocPart = doc.MainDocumentPart;
            
            // the wrong part
            //var imgPart = mainDocPart.AddImagePart(ImagePartType.Png, "rId999");
            //var image = GetImageFromFile(logoFileName);
            //var imagePartID = mainDocPart.GetIdOfPart(imgPart);
            //GenerateImagePartContent(imgPart, image);
    
            if(!mainDocPart.HeaderParts.Any()) {
                mainDocPart.DeleteParts(mainDocPart.HeaderParts);
                var newHeaderPart = mainDocPart.AddNewPart<HeaderPart>();
    
                // try this instead
                var imgPart = newHeaderPart.AddImagePart(ImagePartType.Png, "rId999");
                              ^^^^^^^^^^^^^
                var image = GetImageFromFile(logoFileName);
                var imagePartID = newHeaderPart.GetIdOfPart(imgPart);
                                  ^^^^^^^^^^^^^
                GenerateImagePartContent(imgPart, image);
    
    
                var rId = mainDocPart.GetIdOfPart(newHeaderPart);
                var headerRef = new HeaderReference { Id = rId };
                var sectionProps = doc.MainDocumentPart.Document.Body.Elements<SectionProperties>().LastOrDefault();
                if(sectionProps == null) {
                    sectionProps = new SectionProperties();
                    doc.MainDocumentPart.Document.Body.Append(sectionProps);
                }
                sectionProps.RemoveAllChildren<HeaderReference>();
                sectionProps.Append(headerRef);
                newHeaderPart.Header = GeneratePicHeader(imagePartID);
                newHeaderPart.Header.Save();
            }
        }
    }