Using the SDK I'm building Word documents that contain reports. These documents need to have TOC. Does anybody have a complete solution that I can follow in order to understand how to do this?
(I've read everything on http://openxmldeveloper.org/)
Have a look at Fourth and Final Screen-Cast in Series on Adding/Updating the TOC in OpenXML WordprocessingML Documents by Eric White.
Hope that helps!
UPDATE:
According FAQ from MSDN Forums I see that this feature is not supported:
8) How to generate TOC (table of contents) in Word document?
Open XML SDK 2.0 does not have this feature supported. But you can generate a small TOC through Word app, and reflect the TOC parts with Document Reflector component in Open XML SDK Productivity Tool to see how to generate a TOC programmatically. For more detailed information, please refer to:
UPDATE 2
Based on our comments below I could propose to use this scenario:
- You manually create an empty DOCX file and insert TOC inside it.
- Then you save this file and open it in OpenXML SDK 2.0 Tool, which provides you with the C# code to generate such empty file with TOC placeholder inside.
- Then you programmatically flush all the data you need to this DOCX file and save it.
- In addition you will need provide the mechanism that will auto update TOC once the data are flushed (or once the document is opened). There are a few options to do that - see screen-casts 3-5 fromthe link to Eric White post I provided above. Especially, I think youshould pay your attention to 5th one - "Shows how to use an AutoOpen macro to update the TOC whenever any document that contains a TOC is opened".
All of that look a bit tricky, but I hope that helps.
Thanks to Dmitri Pavlov (@DmitryPavlov) for the help.
I don't want to give an answer to my own question, but this is just to illustrate the steps that I’ve taken.
The advice for anyone interested is to watch the 5-part screen-cast by Eric White - Exploring Tables-of-Contents in Open XML WordprocessingML Documents. This has all the info with respect to adding and updating a TOC (am much more).
My solution was to use a Template (just a regular empty document that had styles for everything I needed: Header 1-5, TOC style, etc.). This is particularly useful as a quick fix for the styles issue (the new document, that has the TOC, will have a new style.xml created; this file has some additional data; as a result the hierarchy in the TOC isn’t as expected – i.e., header 2 is the child of header 1, header 3 is a child of header 2, etc.).
Therefore:
Create a Word document and add all the elements that you expect to be added later programmatically (e.g., Header 1-5, Table of Contents, etc.). Delete all the contents and save the document (the reason for this is to create styles for all the necessary elements).
I personally added the template (the file created at step #1) as a resource in my project.
In your code, create a new copy of the template (this will be the actual file that you will work on). I used:
byte[] stream = Properties.Resources.Template; File.WriteAllBytes(@"D:\Template.docx", stream); File.Copy(@"D:\Template.docx", @"D:\New.docx");
Flush all the data to this document.
Add the source files from screen-cast 2, 3 or 4 to your project (for this please see screen-cast 3) - at the end of those posts you will find a link to download TocAdder.zip. Or just add a reference to TocAdder.dll.
Insert the TOC. Just an example:
using (WordprocessingDocument wdoc = WordprocessingDocument.Open(@"D:\New.docx", true)) { XElement firstPara = wdoc .MainDocumentPart .GetXDocument() .Descendants(W.p) .FirstOrDefault(); TocAdder.AddToc(wdoc, firstPara, @"TOC \o '1-3' \h \z \u", null, null); }
Replace the styles in the newly created document with the ones from the template. You can use this resource from MSDN: Replacing the Styles Parts in Word 2010 Documents by Using the Open XML SDK 2.0. Again, an example:
string fromDoc = @"D:\Template.docx"; string toDoc = @"D:\New.docx"; var node = WDExtractStyles(fromDoc, false); if (node != null) WDReplaceStyles(toDoc, node, false); node = WDExtractStyles(fromDoc); if (node != null) WDReplaceStyles(toDoc, node);
Optionally use one of the methods described in screen-cast 3, 4 or 5 in order to get around the problem with the modal dialog box that Word puts up.
Hope this will be useful for somebody.
If you have a TOC field, this will cause it to be updated when the document is opened in Word (body is a reference to the document body):
DocumentFormat.OpenXml.Wordprocessing.SimpleField f;
f = new SimpleField();
f.Instruction="sdtContent";
f.Dirty = true;
body.Append(f);
来源:https://stackoverflow.com/questions/9762684/how-to-generate-table-of-contents-using-openxml-sdk-2-0