none
Automating Word 2007 content controls, custom xml, visual studio 2008 RRS feed

  • Question

  • Hi,

    I am doing a research to use Word 2007 for dynamic creating summaries for clients. Every summary consists of introduction, descriptive text, graphics pie charts, tables etc, just like an article of 20 pages. I am thinking of creating the layout in Word with content controls. Have a dynamic customxml being generated by C# in Visual Studio 2008 for every customer. The dynamic data (graphics, text) should be coming from a database table maintained by a coworker who enters the data for every customer. The pies, bars, tables might be generated by Reporting Services on schedule and exported as an image to be used by the customXML file per client. 

    Is it possible to gather all these information together at the end to build up the summary report per client? Also there should be a table of contents being generated at the end of the summary, resulting in a complete book as to say per client.

    I have been playing around with the Word 2007 Content Toolkit, but don't seem to be able to load up an image into the content control in Word after binding it. How should the data be within the image tag?...the whole path?...like <imagetag>D:\test.jpg</imagetag>?

    Hope to hear some advise how to quickly do all this. Thanks in advance.

    Tuesday, December 27, 2011 4:03 PM

Answers

  • Hi Ken,

    >>So i must read for a specific customer on a daily basis his/her data from the database, read the pictures location and insert the pics in each picturecontentcontrol in the report programmatically. How can i do this?

    Yes, you can delete the original picture and add new picture via path. You can refer to this thread:

    http://msgroups.net/microsoft.public.word.vba.general/replace-picture-in-content-control

    which contains the code snippet.

    Hope this can help you and just feel free to follow up after you have tried.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    • Proposed as answer by Bruce Song Monday, January 9, 2012 6:03 AM
    • Marked as answer by Bruce Song Tuesday, January 10, 2012 5:42 AM
    Thursday, January 5, 2012 3:35 AM
  • Hi Bruce,

    Thanks for the link. It really helped.

    I did not really managed to change a picture, but i think i was doing it too complicated. Don't know why i used a picturecontentcontrol in my template at all in the first place.

    I could just use 2 bookmarks (e.g. picStart, picEnd) in my template. Select these bookmarks in C# and just add the picture in that position that i wanted.

     

     

    private Object oMissing = System.Reflection.Missing.Value;

    // get start position of picture by locating bookmark in .dot document

     

    Object oBookmarkPictureStart = "picStart";

     

    Object oRangeStart = myDoc.Bookmarks.get_Item(ref oBookmarkPictureStart).Range.Start;

    // get end position of picture by locating bookmark in .dot document

     

    Object oBookmarkPictureEnd = "picEnd";

    Object oRangeEnd = myDoc.Bookmarks.get_Item(ref oBookmarkPictureEnd).Range.Start;

    // select it

    Object oRange = myDoc.Range(ref oRangeStart, ref oRangeEnd);  

     

    // insert picture, important to declare all parameters to be of type Object

     

     myDoc.InlineShapes.AddPicture(@"C:\Temp\new.jpg", ref oMissing, ref oMissing,ref oRange);

     



    • Edited by Word Researcher Thursday, January 5, 2012 12:27 PM
    • Proposed as answer by Bruce Song Monday, January 9, 2012 6:03 AM
    • Marked as answer by Bruce Song Tuesday, January 10, 2012 5:42 AM
    Thursday, January 5, 2012 12:21 PM

All replies

  • Hi Word Researcher,

    Thank you for posting and sorry for the late reply.

    >>I have been playing around with the Word 2007 Content Toolkit, but don't seem to be able to load up an image into the content control in Word after binding it. How should the data be within the image tag?...the whole path?...like <imagetag>D:\test.jpg</imagetag>?

    How did you bind the data to the content control? Would you show us the detail steps list? As far as I know, we can insert the picture to the content control via Open XML SDK, please see whether this thread can help you:

    http://social.msdn.microsoft.com/Forums/en-IN/oxmlsdk/thread/6009b96d-752d-4f9e-bab6-f6768ca44355

    Hope this can give you some hint and just feel free to follow up after you have tried.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Monday, January 2, 2012 3:01 AM
  • Hi Bruce,

    Thanks for your help. I already found something like that with openxml, but it looks like complex coding to me as a C# novice.... i try to accomplish this through the Word 2007 object model.

    I started with a new Word document where i put a picturecontentcontrol with a title and tag on. I saved this as .docx. Then i used the Word 2007 Content Control Kit, opened the .docx, created a customXML to enter some XML tags and bind this tag to this picturecontentcontrol. Initially i did not insert a picture. Then i save and exited the Content Control Kit.

    Since the idea is to generate reports consisting of several data, pics, graphics, i used C# in Visual Studio 2008 to automate Word and  open this .dot document in code and showing it in Word application.

    I managed to use myDoc.CustomXMLParts[1].SelectSingleNode(xPath-of-element-in-mycustomXMLfile).Text to change the text in other text content controls, where the xPath-of-element-in-mycustomXMLfile is path i see for the defined tag in the Content Control Kit in my customXML.

    I tried to do something like this also for the picturecontentcontrol, but did not succeed. Then i tried to traverse the Word object model, like:

    using Office = Microsoft.Office.Interop;

    foreach (Office.Word.ContentControl c in myDoc.ContentControls)

    {

         if (c.Type = wdContentControlPicture && c.Tag = ''myPicture")  // looking for the picture content control i want to update

                  string imagePath = @"c:\test\picture.jpg";

                  ...range.Select();  // how do i do this, i think i must select the picture content control range first

                 // tried casting the content control to a picture content control but not in same namespace

                 Microsoft.Office.Tools.Word.PictureContentControl myPictureContentControl = (Microsoft.Office.Tools.Word.PictureContentControl) c;

                 System.Drawing.Bitmap bitmap1 = new System.Drawing.Bitmap(imagePath, true);

                 myPictureContentControl.Image = bitmap1;

    }

    From logic i think this should work, but it doesn't...how can i solve this?

    I managed to create table of contents from C# code. I guess it is important to mark every area in my Word template with bookmarks, sections, paragraphs so selection can be done by the range in code to accomplish things, right?

    Its a little bit hard sometimes to know what object should be created as parameters for the methods since we are talking to unmanaged COM interface and all are always ref Object parameters.

    Since this is my 1st attempt doing this, i am not sure if i am doing things the right way. 

    My customXML is part of my Word template now and i am using C# to modify the contents programmatically. Should i not have my customXML part of my template and bind the tags/fields in C#? I think i could parse a separate customXML file in C#, find the tags, modify its contents and attach the customXML to my Word template and save it as a final customerX.docx document...but how to do this?

    Would like to hear advice on a good approach to this problem.

     

    Thank you in advance for your help.

     

    Regards,

    Ken.







    Monday, January 2, 2012 3:10 PM
  • Hi Ken,

    Happy new year to you.

    You can use the following code snippet to select the range, open the word insert picture dialog, then insert the choosen picture:

                     if (c.Type == WdContentControlType.wdContentControlPicture && c.Tag == "tag1")  // looking for the picture content control i want to update
                     {
                         //string imagePath = @"C:\Users\v-bpeng\Desktop\test.jpg";
                         c.Range.Select();
                         Dialog dialogBox = Globals.ThisDocument.Application.Dialogs[WdWordDialog.wdDialogInsertPicture];
                         dialogBox.Show();
                     }

    Hope this can help you and just feel free to follow up after you have tried.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Tuesday, January 3, 2012 6:59 AM
  • Hi Bruce,

    Happy New Year to you too!

    Thank you for your help, but i am using a C# program to generate reports, so there won't be any interactive actions from the user to select and choose a picture. Text and picture locations should be all coming from a database with records per (customer,date) and the text and pictures to be inserted in the Word template. At the end i should have several different reports (.docx), each per customer looking differently with his info from the database.

    So i must read for a specific customer on a daily basis his/her data from the database, read the pictures location and insert the pics in each picturecontentcontrol in the report programmatically. How can i do this?

    Regards,

    Ken.

    EDIT: i happened to notice i can delete the old picturecontentcontrol once i have located it, with the Delete() method. Maybe then i can insert a new picturecontentcontrol at the same place in my Word document and assign an image before adding it to the contentcontrols collection of my document?

    Something like...

    oldPictureContentControl.Range;

    oldPictureContentControl.Delete();

    Office.Tools.Word.PictureContentControl p = new Office.Tools.Word.PictureContentControl(...not sure what i should fill in here);

    p.Image = bitmap1

    myDoc.ContentControls.Add(WdContentControlType.wdContentControlPicture, ref "same tag name");


    Wednesday, January 4, 2012 10:01 AM
  • Hi Ken,

    >>So i must read for a specific customer on a daily basis his/her data from the database, read the pictures location and insert the pics in each picturecontentcontrol in the report programmatically. How can i do this?

    Yes, you can delete the original picture and add new picture via path. You can refer to this thread:

    http://msgroups.net/microsoft.public.word.vba.general/replace-picture-in-content-control

    which contains the code snippet.

    Hope this can help you and just feel free to follow up after you have tried.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    • Proposed as answer by Bruce Song Monday, January 9, 2012 6:03 AM
    • Marked as answer by Bruce Song Tuesday, January 10, 2012 5:42 AM
    Thursday, January 5, 2012 3:35 AM
  • Hi Bruce,

    Thanks for the link. It really helped.

    I did not really managed to change a picture, but i think i was doing it too complicated. Don't know why i used a picturecontentcontrol in my template at all in the first place.

    I could just use 2 bookmarks (e.g. picStart, picEnd) in my template. Select these bookmarks in C# and just add the picture in that position that i wanted.

     

     

    private Object oMissing = System.Reflection.Missing.Value;

    // get start position of picture by locating bookmark in .dot document

     

    Object oBookmarkPictureStart = "picStart";

     

    Object oRangeStart = myDoc.Bookmarks.get_Item(ref oBookmarkPictureStart).Range.Start;

    // get end position of picture by locating bookmark in .dot document

     

    Object oBookmarkPictureEnd = "picEnd";

    Object oRangeEnd = myDoc.Bookmarks.get_Item(ref oBookmarkPictureEnd).Range.Start;

    // select it

    Object oRange = myDoc.Range(ref oRangeStart, ref oRangeEnd);  

     

    // insert picture, important to declare all parameters to be of type Object

     

     myDoc.InlineShapes.AddPicture(@"C:\Temp\new.jpg", ref oMissing, ref oMissing,ref oRange);

     



    • Edited by Word Researcher Thursday, January 5, 2012 12:27 PM
    • Proposed as answer by Bruce Song Monday, January 9, 2012 6:03 AM
    • Marked as answer by Bruce Song Tuesday, January 10, 2012 5:42 AM
    Thursday, January 5, 2012 12:21 PM