wordpress hit counter
Find and update a picture content control in a document - WordprocessingML - Formats - OpenXML Developer

Find and update a picture content control in a document

Formats

Discussions about working with different Open XML Formats

Find and update a picture content control in a document

  • rated by 0 users
  • This post has 8 Replies |
  • 4 Followers
  • I have a word document where i have a content control (picture). I am using OpenXML to find the content control and then update the picture and save back the document. I was wondering what is the best way to do this. I appreciate any help. Thanks much.
  • Hi Mohammed,

    Here is code that looks for a picture content control with a tag of "MyPicture". It then finds and replaces the image with a new image named "After.jpg".

    Code formatting is a bit messed up - this will be fixed in the near future. In the mean time, I posted the code here:

    http://openxmldeveloper.org/archive/2011/03/28/131867.aspx


    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;
    using DocumentFormat.OpenXml.Drawing;

    class Program
    {
    static void Main(string[] args)
    {
    using (WordprocessingDocument doc =
    WordprocessingDocument.Open("Test1.docx", true))
    {
    SdtBlock cc = doc.MainDocumentPart.Document.Body.Descendants()
    .FirstOrDefault(c =>
    {
    SdtProperties p = c.Elements().FirstOrDefault();
    if (p != null)
    {
    // Is it a picture content control?
    SdtContentPicture pict =
    p.Elements().FirstOrDefault();
    // Get the alias.
    SdtAlias a = p.Elements().FirstOrDefault();
    if (pict != null && a.Val == "MyPicture")
    return true;
    }
    return false;
    });
    string embed = null;
    if (cc != null)
    {
    Drawing dr = cc.Descendants().FirstOrDefault();
    if (dr != null)
    {
    Blip blip = dr.Descendants().FirstOrDefault();
    if (blip != null)
    embed = blip.Embed;
    }
    }
    if (embed != null)
    {
    IdPartPair idpp = doc.MainDocumentPart.Parts
    .Where(pa => pa.RelationshipId == embed).FirstOrDefault();
    if (idpp != null)
    {
    ImagePart ip = (ImagePart)idpp.OpenXmlPart;
    using (FileStream fileStream =
    File.Open("After.jpg", FileMode.Open))
    ip.FeedData(fileStream);
    Console.WriteLine("done");
    }
    }
    }
    }
    }
  • Ok, these works only for the first picture control in a docx document. But how can a search more than one ? With a forech ? please give a example
  • Hi,

    I've written a small example that will iterate through all content controls in a document. You can use this axis method to find the specific content control you want, and then use the code that I presented earlier to replace the picture in a picture content control.

    http://openxmldeveloper.org/archive/2011/04/11/137383.aspx

    -Eric
  • Hi Eric!

    Thanks a lot!!
    Your example helps me a lot!
    My finish function for serarch and change the picture of a picture content control:

    static SdtAlias ChangePictureContentControl(WordprocessingDocument doc, string contentPictureTagName, string fileName)
            {
                try
                {
                    foreach (var cc in doc.ContentControls())
                    {
                        SdtProperties props = cc.Elements<SdtProperties>().FirstOrDefault();
                        Tag tag = props.Elements<Tag>().FirstOrDefault();
                         if (contentPictureTagName == tag.Val)
                         {
                             SdtAlias a = props.Elements<SdtAlias>().FirstOrDefault();
                            
                             //---------------change the found content picture control picture------------------
                             string embed = null;
                             if (cc != null)
                             {
                                 Drawing dr = cc.Descendants<Drawing>().FirstOrDefault();
                                 if (dr != null)
                                 {
                                     Blip blip = dr.Descendants<Blip>().FirstOrDefault();
                                     if (blip != null)
                                     {
                                         embed = blip.Embed;
                                         if (embed != null)
                                         {
                                             IdPartPair idpp = doc.MainDocumentPart.Parts.Where(pa => pa.RelationshipId == embed).FirstOrDefault();
                                             if (idpp != null)
                                             {
                                                 ImagePart ip = (ImagePart)idpp.OpenXmlPart;
                                                 using (FileStream fileStream = File.Open(fileName, FileMode.Open))
                                                 {
                                                     ip.FeedData(fileStream);
                                                 }
                                                 Console.WriteLine("Done.");
                                             }

                                         }
                                     }
                                 }
                             }

                             //------------------------------------------------------------------------------

                             return a;
                         }
                    }

                    return null;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return null;
                }
            }


    Best regards mimo



  • Hi Eric,

    Tthe code is working fine, but when i open the word document after completing the process, the picture is updating perfectly but still there in the icon is showing in the picutre content control like "Click to insert a picture".

    is there any way to diable that after update the image?

    Thanks

    LathaGokul

  • Any luck on getting rid of the icon that is covering the picture?

    update: an icon saying "click here to insert a picture" was being displayed becuase I placed a picture content control on the document, but did not select an initial image. When you look at the xml of the document I noticed that a ws:showingPlcHdr tag was in the properties collection for the image. By removing this property (of type ShowingPlaceholder) then the placeholder icon goes away.

  • I've implemented the code above, but sill finding that the content controls are all changing not just the one with the tag - if (contentPictureTagName == tag.Val)?

  • Hi Weston

    Just Try This

    Below Code Replace Particular Image

    Public string ApplySignature(string fileName, string imageName, string imageTagName, string SignatureName, string SignatureTag,
            string SignatureDesignation, string SignatureDesignationTag)
        {
                string folderPath = AppDomain.CurrentDomain.BaseDirectory + "shared-data\\";
                string imagePath = AppDomain.CurrentDomain.BaseDirectory + "temp\\" + imageName;
                string filePath = folderPath + fileName ;
                ApplyContentControl(SignatureName, SignatureTag, SignatureDesignation, SignatureDesignationTag, fileName);
                //ApplyImage(imagePath, fileName, imageTagName, filePath);
                string[] results = new string[2];
                string strResult = "";

                try
                {
                    FileInfo fInfo = new FileInfo(imagePath);

                    using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true))
                    {
                        DocumentFormat.OpenXml.Drawing.Blip blip = this.GetBlip(doc, imageTagName);
                        if (blip != null)
                        {
                            // Add image and change embeded id.
                           
                            blip.Embed = this.AddImagePart(doc, imagePath, imageTagName);
                            doc.Package.Flush();

                            results[0] = "OK";

                            results[1] = "0";
                        }
                    }
                    GC.Collect();
                }

                catch (Exception ex)
                {
                    results[0] = ex.Message;

                    results[1] = "-1";
                }

                strResult = results[0] + "|" + results[1];
                GenerateValidationFile(filePath + ".log", strResult);
                return strResult;
        }

    public DocumentFormat.OpenXml.Drawing.Blip GetBlip(WordprocessingDocument pDocument, string pPictureContentControlTagName)
        {
            foreach (SdtAlias alias in pDocument.MainDocumentPart.Document.Descendants<SdtAlias>().ToList())
                if (alias.Val == pPictureContentControlTagName)
                    return alias.Parent.Parent.Descendants<DocumentFormat.OpenXml.Drawing.Blip>().FirstOrDefault();
            return null;
        }

        public string AddImagePart(WordprocessingDocument pDocument, string pPicturePath, string pImagePartId)
        {
            OpenXmlPart part = pDocument.MainDocumentPart.GetPartById(pImagePartId);
            if (part != null)
            {
                pDocument.MainDocumentPart.DeletePart(part);
            }
            ImagePart imagePart = pDocument.MainDocumentPart.AddImagePart(GetImagePartType(pPicturePath), pImagePartId);
            using (FileStream stream = new FileStream(pPicturePath, FileMode.Open, FileAccess.Read))
            {
                imagePart.FeedData(stream);
            }

            return pImagePartId;
        }

        public ImagePartType GetImagePartType(string imagePath)
        {
            ImagePartType imagePartType = ImagePartType.Bmp;

            switch (System.IO.Path.GetExtension(imagePath).ToUpper())
            {
                case "BMP": imagePartType = ImagePartType.Bmp;
                    break;
                case "JPEG":
                case "JPG":
                    imagePartType = ImagePartType.Jpeg;
                    break;
                case "PNG": imagePartType = ImagePartType.Png;
                    break;
                case "GIF": imagePartType = ImagePartType.Gif;
                    break;
                default: imagePartType = ImagePartType.Bmp;
                    break;
            }
            return imagePartType;
        }

        private string GenerateValidationFile(string filePath, string Message)
        {
            string directoryPath = Path.GetDirectoryName(filePath);
            string finalFilename = Path.GetFileNameWithoutExtension(filePath) + ".log";
            StreamWriter SW;
            SW = System.IO.File.CreateText(directoryPath + @"\" + finalFilename);
            SW.WriteLine(Message);
            SW.Close();
            GC.Collect();
            return finalFilename;
        }

     

    Cheers

    Jinesh

     

Page 1 of 1 (9 items)