使用OpenXML在word文档header中填充图片内容控件

Fill Picture content control in header of word doc using OpenXML

我想用这段代码填充我的图片内容控件,它位于我的 word 文档的 header 中:(我已经传递了内容控件标签和通过文档参数的图像流到此函数)

   public void FillDocument(Stream stream, XDocument document)
   {                
   using (WordprocessingDocument wordDocument =
            WordprocessingDocument.Open(stream, true))
        {
            List<SdtElement> descendants = wordDocument.MainDocumentPart.Document.Descendants<SdtElement>().ToList();
            foreach (var headerPart in wordDocument.MainDocumentPart.HeaderParts)
            {
                 descendants.AddRange(headerPart.Header.Descendants<SdtElement>().ToList());
            }
            foreach (var footerPart in wordDocument.MainDocumentPart.FooterParts)
            {
                descendants.AddRange(footerPart.Footer.Descendants<SdtElement>().ToList());
            }

            XDocument doc = document;

            foreach (SdtElement item in descendants)
            {
                SdtAlias alias = item.Descendants<SdtAlias>().FirstOrDefault();

                if (alias != null)
                {                                         
                    string sdtTitle = alias.Val.Value;

                    //if Sdt Content Control is Picture
                    string imageContent = (from xElement in doc.Descendants("Picture") where xElement.Attribute("Id").Value == sdtTitle select xElement.Value).FirstOrDefault();
                    if (imageContent != null)
                    {
                        MemoryStream result = (MemoryStream)StringToStream(imageContent);

                        SdtProperties p = item.Elements<SdtProperties>().FirstOrDefault();
                        if (p != null)
                        {
                            // Is it a picture content control?
                            SdtContentPicture pict = p.Elements<SdtContentPicture>().FirstOrDefault();
                            // Get the alias.
                            SdtAlias a = p.Elements<SdtAlias>().FirstOrDefault();
                            if (pict != null && a.Val.Value == sdtTitle)
                            {
                                string embed = null;
                                Drawing dr = item.Descendants<Drawing>().FirstOrDefault();
                                if (dr != null)
                                {
                                    D.Blip blip = dr.Descendants<D.Blip>().FirstOrDefault();
                                    if (blip != null)
                                        embed = blip.Embed;
                                    if (embed != null)
                                    {
                                        IdPartPair idpp = wordDocument.MainDocumentPart.Parts
                                            .Where(pa => pa.RelationshipId == embed).FirstOrDefault();
                                        if (idpp != null)
                                        {
                                            ImagePart ip = (ImagePart)idpp.OpenXmlPart;
                                            ip.FeedData(result);
                                        }
                                    }
                                }
                            }
                        }



                        continue;
                    }

    }
}

它在 word 文档中找到了内容控件,但是在这一行:

 ImagePart ip = (ImagePart)idpp.OpenXmlPart;

我收到这个错误:

Unable to cast object of type ‘DocumentFormat.OpenXml.Packaging.CustomXmlPart’ to type ‘DocumentFormat.OpenXml.Packaging.ImagePart’.

你能指导我吗?

我试图找到一个方法,这里是答案:

public void FillDocument(Stream stream, XDocument document)
    {    

using (WordprocessingDocument wordDocument =
            WordprocessingDocument.Open(stream, true))
        {
            List<SdtElement> descendants = wordDocument.MainDocumentPart.Document.Descendants<SdtElement>().ToList();
            foreach (HeaderPart headerPart in wordDocument.MainDocumentPart.HeaderParts)
            {
                descendants.AddRange(headerPart.Header.Descendants<SdtElement>().ToList());
            }
            foreach (var footerPart in wordDocument.MainDocumentPart.FooterParts)
            {
                descendants.AddRange(footerPart.Footer.Descendants<SdtElement>().ToList());
            }

            XDocument doc = document;


            foreach (SdtElement item in descendants)
            {
                SdtAlias alias = item.Descendants<SdtAlias>().FirstOrDefault();

                if (alias != null)
                {
                    string sdtTitle = alias.Val.Value;

                    //if Sdt Content Control is Picture
                    string imageContent = (from xElement in doc.Descendants("Picture") where xElement.Attribute("Id").Value == sdtTitle select xElement.Value).FirstOrDefault();
                    if (imageContent != null)
                    {
                        MemoryStream result = (MemoryStream)StringToStream(imageContent);

                        D.Blip blipElement = item.Descendants<D.Blip>().FirstOrDefault();
                        string imageId = "default value";

                        if (blipElement != null)
                        {
                            imageId = blipElement.Embed.Value;

                            ImagePartType imagePartType = ImagePartType.Png;

                            //Add image and change embeded id.
                            ImagePart imagePart = null;
                            Type p = item.Parent.GetType();
                            switch (p.Name)
                            {
                                case "Header":
                                    HeaderPart headerPart = ((Header)(item.Parent)).HeaderPart;
                                    imagePart = headerPart.AddImagePart(imagePartType);
                                    imagePart.FeedData(result);
                                    blipElement.Embed = headerPart.GetIdOfPart(imagePart);
                                    break;
                                case "Body":
                                    MainDocumentPart mainDocumentPart = wordDocument.MainDocumentPart;
                                    imagePart = mainDocumentPart.AddImagePart(imagePartType);
                                    imagePart.FeedData(result);
                                    blipElement.Embed = mainDocumentPart.GetIdOfPart(imagePart);
                                    break;
                                case "Footer":
                                    FooterPart footerPart = ((Footer)(item.Parent)).FooterPart;
                                    imagePart = footerPart.AddImagePart(imagePartType);
                                    imagePart.FeedData(result);
                                    blipElement.Embed = footerPart.GetIdOfPart(imagePart);
                                    break;
                                default:
                                    break;
                            }

                        }
                        continue;
                    }
            }

        }

   }}

效果很好,可以在header or footer or body中填充图片内容控件!