none
Using styles in OOXML without Word RRS feed

  • Question

  • My challenge should be covered by the answer to this: How do I create a docx file with one paragraph that is formatted with a built-in style (say, Heading 1) through OpenXML without having access to the Word application?  Related is how to create it as a JA language document.
    Monday, October 6, 2014 6:06 PM

Answers

  • Better yet, now that I understand things even more, I don't need to know Word's styleId. It only must be unique in the OOXML fragment I am creating, so I can use whatever ID I want. Apparently, Word will match up the style by name and the ID is only used to define the relationship in the OOXML between a style and the doc element that uses it.  That's MUCH easier.  Problem solved!
    • Marked as answer by JohnWhitmire Wednesday, October 22, 2014 8:04 PM
    Wednesday, October 22, 2014 8:04 PM

All replies

  • The easiest way to do that is using the Open XML SDK:
    http://msdn.microsoft.com/en-us/library/office/bb448854(v=office.15).aspx

    Here is a link with lots of samples of small steps to accomplish the task:
    http://msdn.microsoft.com/en-us/library/office/cc850833(v=office.15).aspx

    More from the ground up, you can start with a completely xml by following a post by Bryan Jones from the Office Team:

    http://blogs.msdn.com/b/brian_jones/archive/2005/07/05/intro-to-word-xml-part-1-simple-word-document.aspx

    In short you just create some XML in notepad or other editor:

    <?xml version="1.0"?>
    <w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml">
        <w:body>
            <w:p>
                <w:r>
                    <w:t>Hello World</w:t>
                </w:r>
            </w:p>
        </w:body>
    </w:wordDocument>

    Save it as test.xml, open it in Word to see that you just created a Word document with bold paragraph Hello World. Very basic but it is just a starter! Work from there to add your additional wishes.

    Maarten


    Software Engineer * MVP-Visual Developer-VSTO

    Monday, October 6, 2014 9:50 PM
    Moderator
  • Those are the parts that I know.  The key here is that I want to apply a built-in style to the paragraph.  All the referenced examples involve the creation of a new style, which always includes creation of the style node in the Styles part.  For a built-in style, all I have is the Styles part's lsdException node that will give me the style name (which I obviously already knew) but not the styleId or any of the other characteristics of the style.  Without those, I can't create a style node. 

    Some of my experimentation implies that the styleId may be the hardest part of this.  In another thread, Cindy Meister makes it clear that I can't get the styleId from the Word Object Model.  In the English version, it's not hard to figure out the general rules for discerning the styleId from the style name, but those rules don't work so well in other languages--particularly Japanese.

    Have you some deeper-detail help for this?



    Tuesday, October 7, 2014 1:25 PM
  • John,

    I suggest you create the document using MS Word. Then change that paragraph style to Heading I. Save the document as .docx.

    Then use a reflection tool from Open XML SDK productivity toolkit, find the chunk of code that apply the style. And all what's left is to copy-paste and re-factor the code.

    Regards,

    Michael

    Tuesday, October 7, 2014 6:13 PM
  • Either I don't understand what you are suggesting, or you missed my point.  As stated originally, I need to do this "without having access to the Word application," i.e., no Word API calls and no user involvement.  Just when were you suggesting I create what document in Word?

    Tuesday, October 14, 2014 1:39 PM
  • John, read the second paragraph of my reply.

    That reflection tool from the Open XML toolkit is indispensable tool for learning OOXML file format.

    Basically you do a reverse engineering to create your documents.

    Regards,

    Michael

    Tuesday, October 14, 2014 2:34 PM
  • OK, things are less fuzzy. You are suggesting I create a document with a representative style and then inspect it to see what the OOXML looks like. Is that right?

    I have done a lot of that with the VS add-in, mostly because I keep forgetting about that productivity toolkit tool. What hinders me is that the built-in styles don't reveal their characteristics until they have been used.  Even though I'm not going to need to know that about all 380 of them, I don't think I want to store the expanded style node from that inspection for the 120+ that I do expect to need.  On top of that, creating the style node from the style name (which is the info the code will have) requires the inaccessible styleId. Am I stuck in a corner where I have to inspect and save the instantiated style node for all those styles in all the target languages? Even the thought of that hurts.


    Tuesday, October 14, 2014 3:49 PM
  • John,

    The OOXML Productivity Kit has the option to generate the code to rebuild the document that you use as example.

    So what Michael said was: Create a very small document with the one style you want to examine. Use that document as output and generate the code that is used to re-create the document.

    There is a nice example video that explains this process:

    http://youtu.be/KSSMLR19JWA?t=2m28s

    You can watch the complete video if you want but with the link above you jump right into the location that shows you how to reflect (=reengineer) the code to generate the document again.

    Hope that helped,

    Maarten


    Software Engineer * MVP-Visual Developer-VSTO

    Tuesday, October 14, 2014 5:34 PM
    Moderator
  • Most of that I already knew and am using. The hard part comes from these lines (copied from the tool):

    Style style2 = new Style(){ Type = StyleValues.Paragraph, StyleId = "Heading1" };
    StyleName styleName2 = new StyleName(){ Val = "heading 1" };
    

    All my code knows at this point is Val="heading 1". It does not know StyleId="Heading1" which is a key datum for setting the paragraph style, nor any of the other characteristics of the selected style, unless they are all stored somewhere in the application. And it could be any Paragraph or Linked style from Word's built-in collection (about 120 of them), not just a subset of heading styles.

    (I will admit here that the application does have access to Word, but where I need this, most actions involving Word cause major problems with other aspects. That's why I'm asking for the "non-Word" approach.)

    Tuesday, October 14, 2014 6:05 PM
  • I just created a brand new documnt, changed a single paragraph style to "Heading1", and here is a snippet from the reflected code:

    Paragraph paragraph2 = new Paragraph();

    ParagraphProperties paragraphProperties2 = new ParagraphProperties();
    ParagraphStyleId paragraphStyleId2 = new ParagraphStyleId(){ Val = "Heading1" };

    paragraphProperties2.Append(paragraphStyleId2);

    I'm a bit confused, so sorry if that wasn't helpful

    Regards,

    Michael

    Thursday, October 16, 2014 8:45 PM
  • You cheated and jumped over the problem without realizing it. From where did you get the value for the new ParagraphStyleId? You created an instance of the style in a document via the Word UI and then inspected that document. 

    In my scenario, you don't have that luxury.  The supplied data tells you that the StyleName is "Xxxxx Yyyyyyy" and that it is a built-in style.  (Assume it came from the info in the latentStyles node of the document Styles part.)  You don't have the StyleId and you don't have a pre-generated document to inspect.  (In English, you can fabricate the ID since it will be "XxxxxYyyyyyy" [except for "heading 1" through "heading 9" which change the case of the 'h'], but you can't rely on that scheme in other languages.)

    I've found some work that will programmatically instantiate every built-in style in a document.  That's painful, but it's looking like I will have to use that approach so I can then inspect that document to find the style ID to use when creating the paragraph properties.

    Friday, October 17, 2014 1:03 PM
  • Ok, so it wasn't too clear to me what exactly was your problem. From what I understand is that you simply can't find the match between the Name and the ID of the styles in order for you to go further with that and manipulate the document using the found IDs and Names.

    What I did is check the OOXML ISO documentation (this is in fact the complete specification on how the document is defined, what is where and how it should be used). You can find it here: ISO/IEC 29500-1:2012

    If you go to "11.3.12 Style Definitions Part" you see that your information is stored in the styles.xml part:

    In your document (rename docx to zip, subdir Word, file styles.xml)

     Style Definitions Part

    This part contains the XML with the style definitions:

     Style ID in Style Definitions Part

    From there you can either go from (in your case) name to find your styleId. As you can see here, in -this- document the style named "heading 1" is called "Heading1".

    All of this can be done without Word, simply by accessing the XML file structure stored in the document that is 'just' a zipped container with XML files as I showed in the structure image above.

    Most of the information as defined in ISO/IEC 29500-1:2012 is made available through the OOXML SDK, but if not you can always go back to accessing the file and manipulate or read the XML files directly in the document. 

    Hope this helped,

    Maarten


    Software Engineer * MVP-Visual Developer-VSTO

    Saturday, October 18, 2014 8:44 PM
    Moderator
  • That's closer.  Still, either I'm not recognizing the perspective from which you are viewing your example or you missed the impact of my statement "You don't have the StyleId and you don't have a pre-generated document to inspect."  (Note that the user could have changed their definition of any of the styles, so any style nodes copied from something created at design time are unreliable.)  However, the link to the ISO standard is appreciated, and Section 17.7.4.17 was helpful, in a way.

    So..., all the bits and pieces are pointing to the painful route as the only solution.  There are no rules for assigning a style ID, so I cannot assume anything about it.  At runtime, I have to generate a document with all (120 or so) appropriate built-in styles instantiated and store (somewhere) a copy of its styles part so I can retrieve the selected style node from it.  Annoying, but feasible, and help is available from this site.


    • Marked as answer by JohnWhitmire Monday, October 20, 2014 12:43 PM
    • Edited by JohnWhitmire Monday, October 20, 2014 12:55 PM
    • Unmarked as answer by JohnWhitmire Wednesday, October 22, 2014 8:04 PM
    Monday, October 20, 2014 12:43 PM
  • Better yet, now that I understand things even more, I don't need to know Word's styleId. It only must be unique in the OOXML fragment I am creating, so I can use whatever ID I want. Apparently, Word will match up the style by name and the ID is only used to define the relationship in the OOXML between a style and the doc element that uses it.  That's MUCH easier.  Problem solved!
    • Marked as answer by JohnWhitmire Wednesday, October 22, 2014 8:04 PM
    Wednesday, October 22, 2014 8:04 PM