Search code examples
c#ms-wordheaderopenxmlopenxml-sdk

Insert Image as a HEADER in Open XML Word Document


I'm trying to add an Image as a header in to Word document using Open XML of Microsoft. I have achieved displaying image in document but unable to display the image in the header. Instead of displaying an image it shows a blank box without a picture.

static void Main(string[] args)
{
    string fileName = @ "C:\XmlWord4.docx";
    string imagePath = @ "C:\Picture3.png";
    AddPicInBody(fileName, imagePath); // This call works perfectly fine
    AddPicInHeader(fileName, imagePath); //This call doesn't show up the picture in header instead blank box appears
}

I'm facing issues with this header call.

static void AddPicInHeader(string document, string fileName)
{
    using(WordprocessingDocument wordprocessingDocument =
        WordprocessingDocument.Open(document, true))
    {
        var mainDocPart = wordprocessingDocument.MainDocumentPart;
        var imgPart = mainDocPart.AddImagePart(ImagePartType.Png);
        using(FileStream stream = new FileStream(fileName, FileMode.Open))
        {
            imgPart.FeedData(stream);
        }
        var image = fileName;
        var imagePartID = mainDocPart.GetIdOfPart(imgPart);

        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 = wordprocessingDocument.MainDocumentPart.Document.Body.Elements < SectionProperties > ().LastOrDefault();
            if (sectionProps == null)
            {
                sectionProps = new SectionProperties();
                wordprocessingDocument.MainDocumentPart.Document.Body.Append(sectionProps);
            }
            sectionProps.RemoveAllChildren < HeaderReference > ();
            sectionProps.Append(headerRef);
            newHeaderPart.Header = GeneratePicHeader(imagePartID);
            newHeaderPart.Header.Save();
        }
    }
}
static Header GeneratePicHeader(string relationshipId)
{
    int iWidth = 0;
    int iHeight = 0;
    string imagePath = @ "C:\Users\SAKS\HeaderPic.png";
    using(System.Drawing.Bitmap bmp = new(imagePath))
    {
        iHeight = bmp.Height;
        iWidth = bmp.Width;
    }

    iWidth = (int) Math.Round((decimal) iWidth);
    iHeight = (int) Math.Round((decimal) iHeight);
    // Define the reference of the image.
    var element =
        new Drawing(
            new DW.Inline(
                new DW.Extent()
                {
                    Cx = 990000 L, Cy = 792000 L
                },
                new DW.EffectExtent()
                {
                    LeftEdge = 0 L,
                        TopEdge = 0 L,
                        RightEdge = 0 L,
                        BottomEdge = 0 L
                },
                new DW.DocProperties()
                {
                    Id = (UInt32Value) 1 U,
                        Name = "Picture 1"
                },
                //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) 0 U,
                                        Name = "New Bitmap Image.jpg"
                                },
                                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 = 0 L, Y = 0 L
                                    },
                                    new A.Extents()
                                    {
                                        Cx = iWidth, Cy = iHeight
                                    }),
                                new A.PresetGeometry(
                                    new A.AdjustValueList()
                                )
                                {
                                    Preset = A.ShapeTypeValues.Rectangle
                                }))
                    )
                    {
                        Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
                    })
            )
            {
                DistanceFromTop = (UInt32Value) 0 U,
                    DistanceFromBottom = (UInt32Value) 0 U,
                    DistanceFromLeft = (UInt32Value) 0 U,
                    DistanceFromRight = (UInt32Value) 0 U,
                    EditId = "50D07946"
            });

    // Append the reference to body, the element should be in a Run.

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

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

The below method call to print a picture in the body of the document works perfectly fine.

static void AddPicInBody(string document, string fileName)


{
    using(WordprocessingDocument wordprocessingDocument =
        WordprocessingDocument.Open(document, true))
    {
        MainDocumentPart mainPart = wordprocessingDocument.MainDocumentPart;

        ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);

        using(FileStream stream = new FileStream(fileName, FileMode.Open))
        {
            imagePart.FeedData(stream);
        }
        AddImageToBody(wordprocessingDocument, mainPart.GetIdOfPart(imagePart));
    }
}

static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId)
{
    int iWidth = 0;
    int iHeight = 0;
    string imagePath = @ "C:\Users\SAKS\Picture3.png";
    using(System.Drawing.Bitmap bmp = new(imagePath))
    {
        iHeight = bmp.Height;
        iWidth = bmp.Width;
    }
    iWidth = (int) Math.Round((decimal) iWidth * 4000);
    iHeight = (int) Math.Round((decimal) iHeight * 4000);
    // Define the reference of the image.
    var element =
        new Drawing(
            new DW.Inline(
                new DW.Extent()
                {
                    Cx = iWidth, Cy = iHeight
                },
                new DW.EffectExtent()
                {
                    LeftEdge = 0 L,
                        TopEdge = 0 L,
                        RightEdge = 0 L,
                        BottomEdge = 0 L
                },
                new DW.DocProperties()
                {
                    Id = (UInt32Value) 1 U,
                        Name = "Picture 1"
                },
                //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) 0 U,
                                        Name = "New Bitmap Image.jpg"
                                },
                                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 = 0 L, Y = 0 L
                                    },
                                    new A.Extents()
                                    {
                                        Cx = iWidth, Cy = iHeight
                                    }),
                                new A.PresetGeometry(
                                    new A.AdjustValueList()
                                )
                                {
                                    Preset = A.ShapeTypeValues.Rectangle
                                }))
                    )
                    {
                        Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
                    })
            )
            {
                DistanceFromTop = (UInt32Value) 0 U,
                    DistanceFromBottom = (UInt32Value) 0 U,
                    DistanceFromLeft = (UInt32Value) 0 U,
                    DistanceFromRight = (UInt32Value) 0 U,
                    EditId = "50D07946"
            });

    // Append the reference to body, the element should be in a Run.
    wordDoc.MainDocumentPart.Document.Body.AppendChild(new Paragraph(new Run(element)));
}

Solution

  • Finally I'm able to bring up the Picture as Header in Word doc below is the code snippet I've used using DocumentFormat.OpenXml.Vml; for Shape

                string document = @"C:\Users\OpenXML.docx";
                string imagePath = @"C:\Users\Logo.png";
    
                AddHeader(document, headerLogo);
    
        static void AddHeader(string document, string imagePath)
                {
                    using (WordprocessingDocument doc = WordprocessingDocument.Open(document, true))
                    {
                        setHeaderPicture(imagePath);
                        MainDocumentPart mainDocumentPart1 = doc.MainDocumentPart;
                        if (mainDocumentPart1 != null)
                        {
                            mainDocumentPart1.DeleteParts(mainDocumentPart1.HeaderParts);
                            HeaderPart headPart1 = mainDocumentPart1.AddNewPart<HeaderPart>();
                            GenerateHeaderPart1Content(headPart1);
                            string rId = mainDocumentPart1.GetIdOfPart(headPart1);
                            ImagePart image = headPart1.AddNewPart<ImagePart>("image/jpeg", "rId999");
                            GenerateImagePart1Content(image);
                            IEnumerable<SectionProperties> sectPrs = mainDocumentPart1.Document.Body.Elements<SectionProperties>();
                            foreach (var sectPr in sectPrs)
                            {
                                sectPr.RemoveAllChildren<HeaderReference>();
                                sectPr.PrependChild<HeaderReference>(new HeaderReference() { Id = rId });
                            }
                        }
                    }
                }
                static void GenerateHeaderPart1Content(HeaderPart headerPart1)
                {
                    Header header1 = new Header();
                    Paragraph paragraph2 = new Paragraph();
                    Run run1 = new Run();
                    Picture picture1 = new Picture();                    
                    Shape shape1 = new Shape() { Id = "WordPictureWatermark75517470", Style = "position:absolute;left:0;text-align:center;margin-left:0;margin-top:0;width:140.0pt;height:40.0pt;mso-position-horizontal:right;", OptionalString = "_x0000_s2051", AllowInCell = false, Type = "#_x0000_t75" };
                    ImageData imageData1 = new ImageData() { Gain = "19661f", BlackLevel = "22938f", Title = "水印", RelationshipId = "rId999" };
                    shape1.Append(imageData1);
                    picture1.Append(shape1);
                    run1.Append(picture1);
                    paragraph2.Append(run1);
                    header1.Append(paragraph2);
                    headerPart1.Header = header1;
                }
                static void GenerateImagePart1Content(ImagePart imagePart1)
                {
                    System.IO.Stream data = GetBinaryDataStream(imagePart1Data);
                    imagePart1.FeedData(data);
                    data.Close();
                }
                static System.IO.Stream GetBinaryDataStream(string base64String)
                {
                    return new System.IO.MemoryStream(System.Convert.FromBase64String(base64String));
                }
                static string imagePart1Data = "";
                static void setHeaderPicture(string file)
                {
                    FileStream inFile;
                    byte[] byteArray;
                    try
                    {
                        inFile = new FileStream(file, FileMode.Open, FileAccess.Read);
                        byteArray = new byte[inFile.Length];
                        long byteRead = inFile.Read(byteArray, 0, (int)inFile.Length);
                        inFile.Close();
                        imagePart1Data = Convert.ToBase64String(byteArray, 0, byteArray.Length);
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }