none
How To Create Style Heading1 in Office Open XML C# RRS feed

  • Question

  •  I try to create Heading1 style in the word document but nothing works.


    I have this code to create style and document.

        public static void CreateWord(string filepath)
        {
            var wdoc = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document);
            var mdoc = wdoc.AddMainDocumentPart();
    
            AddStylesPartToPackage(wdoc);
            // Create the document structure and add some text.
            mdoc.Document = new Document();
            var body = mdoc.Document.AppendChild(new Body());
    
            CreateStyleHeading(mdoc,"Heading1","Heading 1");
    
            var par = body.AppendChild(new Paragraph());
            var run = par.AppendChild(new Run());
            var r = run.AppendChild(new Run());
            r.AppendChild(new Text("Create text in body - CreateWordprocessingDocument"));
    
    
            // ReSharper disable once UseMethodAny.2
            if (par.Elements<ParagraphProperties>().Count() == 0)
                par.PrependChild<ParagraphProperties>(new ParagraphProperties());
            // Get the ParagraphProperties element of the paragraph.
            var pPr = par.Elements<ParagraphProperties>().First();
            // Set the value of ParagraphStyleId to "Heading3".
            pPr.ParagraphStyleId = new ParagraphStyleId() { Val = "Heading1" };
    
            wdoc.Close();
    
        }
    
        // Add a StylesDefinitionsPart to the document.  Returns a reference to it.
        public static StyleDefinitionsPart AddStylesPartToPackage(WordprocessingDocument doc)
        {
            StyleDefinitionsPart part;
            part = doc.MainDocumentPart.AddNewPart<StyleDefinitionsPart>();
            Styles root = new Styles();
            root.Save(part);
            return part;
        }
    
        public static void CreateStyleHeading(MainDocumentPart mdoc,  string styleid,string stylename)
        {
          
    
    
            var styles = mdoc.StyleDefinitionsPart.Styles;
            if (styles == null)
            {
                mdoc.StyleDefinitionsPart.Styles = new Styles();
                mdoc.StyleDefinitionsPart.Styles.Save();
            }
    
            // Create a new paragraph style element and specify some of the attributes.
            var style = new Style()
            {
                Type = StyleValues.Paragraph,
                StyleId = styleid,
                CustomStyle = true,
                Default = false
            };
    
            // Create and add the child elements (properties of the style).
            var uiPriority1 = new UIPriority { Val = 9 };
    
            //Aliases aliases1 = new Aliases() { Val = "" };
            var autoredefine1 = new AutoRedefine() { Val = OnOffOnlyValues.Off };
            var basedon1 = new BasedOn() { Val = "Normal" };
            var linkedStyle1 = new LinkedStyle() { Val = "OverdueAmountChar" };
            var locked1 = new Locked() { Val = OnOffOnlyValues.Off };
            var primarystyle1 = new PrimaryStyle() { Val = OnOffOnlyValues.On };
            var stylehidden1 = new StyleHidden() { Val = OnOffOnlyValues.Off };
            var semihidden1 = new SemiHidden() { Val = OnOffOnlyValues.Off };
            var styleName1 = new StyleName() { Val = stylename };
            var nextParagraphStyle1 = new NextParagraphStyle() { Val = "Normal" };
            var uipriority1 = new UIPriority() { Val = 1 };
            var unhidewhenused1 = new UnhideWhenUsed() { Val = OnOffOnlyValues.On };
    
            style.Append(uiPriority1);
            style.Append(autoredefine1);
            style.Append(basedon1);
            style.Append(linkedStyle1);
            style.Append(locked1);
            style.Append(primarystyle1);
            style.Append(stylehidden1);
            style.Append(semihidden1);
            style.Append(styleName1);
            style.Append(nextParagraphStyle1);
            style.Append(uipriority1);
            style.Append(unhidewhenused1);
    
            // Create the StyleRunProperties object and specify some of the run properties.
            var styleRunProperties1 = new StyleRunProperties();
            var bold1 = new Bold();
            var color1 = new Color() { ThemeColor = ThemeColorValues.Accent2 };
            var font1 = new RunFonts() { Ascii = "Lucida Console" };
            var italic1 = new Italic();
            // Specify a 12 point size.
            var fontSize1 = new FontSize() { Val = "24" };
            styleRunProperties1.Append(bold1);
            styleRunProperties1.Append(color1);
            styleRunProperties1.Append(font1);
            styleRunProperties1.Append(fontSize1);
            styleRunProperties1.Append(italic1);
    
            // Add the run properties to the style.
            style.Append(styleRunProperties1);
    
            // Add the style to the styles part.
            styles.Append(style);
        }





    But when I run:

        CreateWord("file.docx");

    When I open file.docx my style is renamed to "Heading 11" instead of "Heading 1" and there is no Navigation. ("This document does not contain headings"). [I cannot add pictures to this post]


    I found only how to create style. But i cannot find information how to create Heading1 style. When i unpack created .docx and .docx created by a Word document i found only that Heading1 is added to "latentStyles" but I cannot find how to do this in the code.

    Sunday, June 26, 2016 7:24 AM

Answers

  • Yest. I've got the same result but this is wrong. "Heading 1" is blue instead of Orange. If you move cursor to the orange Heading you will see "Heading 11". 

    If you try to create "table of contents" you will get empty ToC. But this paragraph is "Heading 1" and should be in the ToC. This is not "Heading 1" as I expected.

    I create my own solution based on the other topic and function FeedData. First i create word file and setup correct formatting for each heading and extract styles.xml from the zipped .docx file.

    I move this to the solution as a Embedded Resources.

    Next I wrote some functions to create new file:

        public static class WordStyles
        {
            // Add a StylesDefinitionsPart to the document.  Returns a reference to it.
            public static StyleDefinitionsPart AddStylesPartToPackage(WordprocessingDocument doc)
            {
                var part = doc.MainDocumentPart.AddNewPart<StyleDefinitionsPart>();
                var root = new Styles();
                root.Save(part);
                //  FileStream stylesTemplate =  new FileStream("styles.xml", FileMode.Open, FileAccess.Read);
                part.FeedData(Res.Resources.OpenStream("Styles.xml"));
                return part;
            }
    
            static readonly string Prefix = typeof(WordStyles).Namespace + ".";
    
            public static Stream OpenStream(string name)
            {
                var s = typeof(Resources).Assembly.GetManifestResourceStream($"{Prefix}{name}");
                if (s == null)
                    throw new FileNotFoundException("The resource file '" + name + "' was not found.");
                return s;
            }
    
            public static void CreateWord(string filename)
            {
                var word = WordprocessingDocument.Create(filename, WordprocessingDocumentType.Document);
                var mdoc = word.AddMainDocumentPart();
    
                // Create the document structure and add some text.
                mdoc.Document = new Document();
                var body = mdoc.Document.AppendChild(new Body());
    
                var stylepart = WordStyles.AddStylesPartToPackage(word);
    
                var style = stylepart.Styles.OfType<Style>().FirstOrDefault(i => i.StyleId == "Heading1");
                //var styleid =  stylepart.GetPartById("Heading1");
                var color1 = new Color() {Val = "FF0000"};
                style.StyleRunProperties.Append(color1);
    
                var par = body.AppendChild(new Paragraph());
                var run = par.AppendChild(new Run());
                var r = run.AppendChild(new Run());
                r.AppendChild(new Text("Create text in body - CreateWordprocessingDocument"));
    
    
                // ReSharper disable once UseMethodAny.2
                if (par.Elements<ParagraphProperties>().Count() == 0)
                    par.PrependChild<ParagraphProperties>(new ParagraphProperties());
                // Get the ParagraphProperties element of the paragraph.
                var pPr = par.Elements<ParagraphProperties>().First();
                // Set the value of ParagraphStyleId to "Heading3".
                pPr.ParagraphStyleId = new ParagraphStyleId() {Val = "Heading1"};
    
                word.Close();
    
            }
        }

    Now I can edit my style and put ToC into the document :)

     WordStyles.CreateWord("file.docx");


    • Marked as answer by alexiej Monday, June 27, 2016 8:03 PM
    • Edited by alexiej Monday, June 27, 2016 8:07 PM Spelling mistakes
    Monday, June 27, 2016 8:01 PM

All replies

  • I'm not sure but I would guess it's because Word already contains a built-in style with the name 'Heading1'. You could try using a different style id and name, or retrieving and modifying the existing style.

    Paul

    Sunday, June 26, 2016 3:35 PM
  • >>>When I open file.docx my style is renamed to "Heading 11" instead of "Heading 1" and there is no Navigation. ("This document does not contain headings"). [I cannot add pictures to this post]

    I found only how to create style. But i cannot find information how to create Heading1 style. When i unpack created .docx and .docx created by a Word document i found only that Heading1 is added to "latentStyles" but I cannot find how to do this in the code.<<<

    According to your description, I have create a sample with your sample code to try to reproduce this issue, unfortunately, I am not able. I got this result:

    Word Version:

    I suggest that you could refer about How to: Create and add a paragraph style to a word processing document (Open XML SDK)

    In addition you could use Open XML SDK Productivity Tool to analyse file and generated C# code.

    Monday, June 27, 2016 7:59 AM
  • Yest. I've got the same result but this is wrong. "Heading 1" is blue instead of Orange. If you move cursor to the orange Heading you will see "Heading 11". 

    If you try to create "table of contents" you will get empty ToC. But this paragraph is "Heading 1" and should be in the ToC. This is not "Heading 1" as I expected.

    I create my own solution based on the other topic and function FeedData. First i create word file and setup correct formatting for each heading and extract styles.xml from the zipped .docx file.

    I move this to the solution as a Embedded Resources.

    Next I wrote some functions to create new file:

        public static class WordStyles
        {
            // Add a StylesDefinitionsPart to the document.  Returns a reference to it.
            public static StyleDefinitionsPart AddStylesPartToPackage(WordprocessingDocument doc)
            {
                var part = doc.MainDocumentPart.AddNewPart<StyleDefinitionsPart>();
                var root = new Styles();
                root.Save(part);
                //  FileStream stylesTemplate =  new FileStream("styles.xml", FileMode.Open, FileAccess.Read);
                part.FeedData(Res.Resources.OpenStream("Styles.xml"));
                return part;
            }
    
            static readonly string Prefix = typeof(WordStyles).Namespace + ".";
    
            public static Stream OpenStream(string name)
            {
                var s = typeof(Resources).Assembly.GetManifestResourceStream($"{Prefix}{name}");
                if (s == null)
                    throw new FileNotFoundException("The resource file '" + name + "' was not found.");
                return s;
            }
    
            public static void CreateWord(string filename)
            {
                var word = WordprocessingDocument.Create(filename, WordprocessingDocumentType.Document);
                var mdoc = word.AddMainDocumentPart();
    
                // Create the document structure and add some text.
                mdoc.Document = new Document();
                var body = mdoc.Document.AppendChild(new Body());
    
                var stylepart = WordStyles.AddStylesPartToPackage(word);
    
                var style = stylepart.Styles.OfType<Style>().FirstOrDefault(i => i.StyleId == "Heading1");
                //var styleid =  stylepart.GetPartById("Heading1");
                var color1 = new Color() {Val = "FF0000"};
                style.StyleRunProperties.Append(color1);
    
                var par = body.AppendChild(new Paragraph());
                var run = par.AppendChild(new Run());
                var r = run.AppendChild(new Run());
                r.AppendChild(new Text("Create text in body - CreateWordprocessingDocument"));
    
    
                // ReSharper disable once UseMethodAny.2
                if (par.Elements<ParagraphProperties>().Count() == 0)
                    par.PrependChild<ParagraphProperties>(new ParagraphProperties());
                // Get the ParagraphProperties element of the paragraph.
                var pPr = par.Elements<ParagraphProperties>().First();
                // Set the value of ParagraphStyleId to "Heading3".
                pPr.ParagraphStyleId = new ParagraphStyleId() {Val = "Heading1"};
    
                word.Close();
    
            }
        }

    Now I can edit my style and put ToC into the document :)

     WordStyles.CreateWord("file.docx");


    • Marked as answer by alexiej Monday, June 27, 2016 8:03 PM
    • Edited by alexiej Monday, June 27, 2016 8:07 PM Spelling mistakes
    Monday, June 27, 2016 8:01 PM