Search code examples
c#openxmlopenxml-sdk

OpenXML "Heading2" does not work, but "Heading1" does work


I am having the issue when using OpenXML heading1 style is functioning correctly but heading2 style is not. The reason I should have access to the headings is because I am copying a template word document that already have the styles preloaded on them.

Function for creating the heading

public static Paragraph CreateHeading(string text, Body body, string type)
 {
            Paragraph para = body.AppendChild(new Paragraph());
            Run run = para.AppendChild(new Run());
            run.AppendChild(new Text(text));
            para.ParagraphProperties = new ParagraphProperties(new ParagraphStyleId() { Val = type });

            return para;
 }

public CustomizationInformation GenerateDocumentation(WordprocessingDocument document, EntityMetadata metadata, CustomizationInformation customizations)
        {
            _metadata = metadata;
            _customizations = customizations;

            // Create our table
            _table = TableFactory.CreateTable();


            //ParagraphFactory.CreateHeading("Attributes", document.MainDocumentPart.Document.Body, "Heading1"); // **
            ParagraphFactory.CreateHeading("Attributes", document.MainDocumentPart.Document.Body, "Heading2"); // **

            document.MainDocumentPart.Document.Body.Append(ParagraphFactory.Create("The following attributes are exposed on this entity."));

            // Initialize table
            initializeTable();
            addAttributes();

            // Add our table to the document
            document.MainDocumentPart.Document.Body.Append(_table);

            return _customizations;
        }

Where the * are located in the above code. The Heading1 function works fine, but the Heading2 does not show up.

Thank you for the help I appreciate it.


Solution

  • I've made a test and it seems that several things must be considered when using styles in Word documents:

    • In a document file, there may not be definitions of all styles (even not all the basic ones, unless they are applied to text in the document), so when editing a document from code, You should verify that appropriate style declaration exists (and add one if required), if You want to use it for a paragraph.
    • values specified in Val attribute of ParagraphStyleId should not be treated as constants, even for basic styles (like headings), because in other language versions of MS Word those styles can be named differently.

    You should be able to find styles definitions in the document in StyleDefinitionsPart part. You can list styles defined in a document using this code (it's only for testing and I wanted to keep it simple, but if You want to use it in Your app, You should add checking for null values and handling of multiple elements in parts collection):

    var sDParts = document.MainDocumentPart.GetPartsOfType<StyleDefinitionsPart>();
    foreach (var style in sDParts.First().Styles.ChildElements.OfType<Style>())
    {
        Console.WriteLine("Style id: {0}, style name: {1}", 
            style.StyleId, 
            style.StyleName.Val);
    }
    

    I suppose that value set in the style.StyleId is the one that should be used for the Val attribute in PagraphStyleId element.