wordpress hit counter
Dynamic production of repeating context controls by a WCF service - OpenXML Developer - Blog - OpenXML Developer

Dynamic production of repeating context controls by a WCF service

Blog

Samples, Demos, and Reference Articles

Dynamic production of repeating context controls by a WCF service

Rate This
  • Comments 7

(Updated to v2)

Greetings,

Due to my work as an ISV DE in MS, I had just recently been requested by an organisation to produce a small demo to demonstrate how the new custom xml parts could help them deal with an issue that is causing them trouble. More specifically, they have many client stores that produce documents based on local stored templates and client-based programs bearing logic on how to format/compile the document. As you can imagine, this architecture is difficult to maintain and more often than not causes inconsistencies between the documents produced by the various client apps.

The solution to this could be the creation of a client (a WinForm app) that would collect the data and then send them over to a WCF service. The service would produce a new docx file based on a template created by non-IT user (initially) and developers (secondary). The service would then insert all data in the new docx file (in the custom xml part) and send it back to the client as "binary" with streaming (so as not to cause unwanted overhead to the network). This way, the whole "logic" of the creation of the document is kept in the server-side (I have included a small sketch in the files to make it more clear). However, there are couple of things that need attention..

First, the people from the organisation stressed, almost from the first moment, that there are several cases where the length of the data is not known in advance: e.g. tables with arbitrary (i.e. user-defined) number of rows with data. This, of course, causes an interesting problem due to the fact that the custom xml part bearing the data, has a static schema that cannot change during runtime automatically. Therefore, the only option is to create as many content controls necessary, edit the schema of the custom xml part to add the corresponding entries and then establish the link (xpath) between them. This solution of course requires for the developer to load and deal with the content of the document and not just the custom xml part, which would have been simpler. Dispite the extra work though, it's feasible and not as complicated as one would think initially. This is shown in the demo in two ways: one by using pure xml, which inevitably results in several foreach loops, and one by using Xpath queries resulting in less and more legible code.

The second issue is the fact that the docx template might have several sections, which, depending on the options selected by the user, should or should not be displayed in the final docx. This could be implemented by using rich text content controls in the template docx, to embrace each section and then delete them as appropriate during the creation of the final docx. By the way, note that you can have other content controls within rich text content controls, and in fact pretty much anything else. This solution of course requires the developer to deal once again with the content part, which I believe in this case is understandable, since the issue is about the content/format and not the actual data. This is shown in demo with 4th and 5th section of the template. They both refer to the same topic (interest), but have deferent context. Thus, depending on what the user selects in the Loan Type field of the client application, one of the two section is deleted leaving the other to be displayed in the resulting document.

About the demo: remember to run the exes in admin mode (if you are using Vista with UAC) and unblock the port 81 from the firewall. I've highligted the content controls in the template docx to help spotting the changes in the final docx. Finally, bear in mind that the document created by the service is not deleted after sent, thus you will end up with two docs after running the demo: one random-named created by the service and one received/created by the client (called agreement).

Hope it helps,

Dimitris

 

 

Attachment: Source_v2.zip
  • Interesting, but it would have been more useful to not rely on tag name, but instead try to build a generic engine
  • Hmm.. how would you make the mapping between the input data and the content controls then?

    The only way I can think of is to go by some sort of rule like "the first data in matches the first content control, then the second data in matches the second cc.. etc". This way you wont have to touch the service again - the mapping is automatically done. Furthermore, if the service is automatically creating the custom part of the document "on the fly", then pratically the only thing that would change each time a non-IT user changes the template doc to add a new content control, is the front-end.

    That being said, though, I must say that things are never so easy/ideal in a bank, since several data are retrieved from various sources like databases, files etc.
  • Great example.. It was exactly what I was looking for. Just not sure how you're setting the content controls to be highlighted. How would i disable that?
  • nevermind got it
  •  cellNode.SelectSingleNode(@"./w:p/w:sdt/w:sdtPr", nsmgr).RemoveChild(cellNode.SelectSingleNode(@"./w:p/w:sdt/w:sdtPr/w:id", nsmgr))

    why are you removing this node after you add the xPath?
  • Hi NeoShred,

    Sorry for the late response, but being heavily envolved in other activities I wasn't really monitoring the site. So I guess you already solved the issue, but the sake of completeness here it is:
    In order to add an extra raw in the table I am copying (cloning) and pasting (apending) the first raw to the table. However, the cloning/appending doesn't modify the id (ideally it should auto-generate a new Id for each appending), it just copies the Id of the cloned raw. So I am removing the Id. Office Word will parse the table normally and the next time the user saves it, Word will provide an Id to the appended line.
  • This was great. However, I'm trying to copy a table row with multiple content controls, and only the first content control gets copied. This is really strange. Have you run across this?
Page 1 of 1 (7 items)