Page 1 of 1

Setting font in default styles

PostPosted: Wed Aug 18, 2010 2:37 am
by garybentley
Is there any way to set the font name for the default styles such as Title, Normal and Heading1?

Currently I am doing:

Code: Select all
                WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
       
                MainDocumentPart mp = wordMLPackage.getMainDocumentPart ();
       
                // Sort out the styles.
                StyleDefinitionsPart sdp = mp.getStyleDefinitionsPart ();

                Map<String, Style> styles = sdp.getKnownStyles ();
               
                Style titleS = styles.get (NORMAL);
               
                if (titleS != null)
                {

                    // Get the rpr.
                    RPr rpr = titleS.getRPr ();
                   
                    if (rpr == null)
                    {
                       
                        rpr = new RPr ();
                        titleS.setRPr (rpr);
                       
                    }
                   
                    RFonts rf = rpr.getRFonts ();
                   
                    if (rf == null)
                    {
                       
                        rf = new RFonts ();
                        rpr.setRFonts (rf);
                       
                    }
                   
                    rf.setAscii ("Verdana");
                                                           
                }

But it doesn't work. Anyone any idea what I'm missing? I've checked the styles.xml file and it doesn't contain Verdana anywhere, the style for Normal usually winds up looking like this:

Code: Select all
<w:style w:default="true" w:styleId="Normal" w:type="paragraph"><w:name w:val="Normal"/><w:qFormat/><w:rsid w:val="004A3277"/></w:style>


There doesn't even appear to be any rPr element.

If it's not possible to set the values on the default styles how would I go about adding my own pre-built styles.xml file into the document?

Thanks in advance,

Gary

Re: Setting font in default styles

PostPosted: Wed Aug 18, 2010 4:43 am
by jason
It is indeed possible to set a font on a pre-existing style.

A quick note in passing:- instead of using new to create a org.docx4j.wml object, you should get into the habit of using the ObjectFactory. For example,

Code: Select all
    org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();
    RFonts rfonts = factory.createRFonts();


Usually using new works properly, but sometimes it doesn't. This is a JAXB things .. there is a web page somewhere which explains why.

But the real problem here is that knownStyles is a variety of pre-defined styles, available for use in a StyleDefinitionsPart. It is not the styles contained in your styles part.

StyleDefinitionsPart contains a method getDefaultParagraphStyle(), but there aren't convenience methods to get a style by name or ID. These should probably be added. In their absence, do something like:

Code: Select all
      Styles styles = wmlPackage.getMainDocumentPart().getStyleDefinitionsPart().getJaxbElement();      
      for ( org.docx4j.wml.Style s : styles.getStyle() ) {
            :


Once you have your Style s, change it as using code along the lines of what you posted.

FYI, note the document defaults in the styles part, for example:
Code: Select all
        <w:docDefaults>
         <w:rPrDefault>
            <w:rPr>
               <w:rFonts w:asciiTheme="minorHAnsi" w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi" />
               :
            </w:rPr>
         </w:rPrDefault>
         :
      </w:docDefaults>


would affect the default font.

StyleDefinitionsPart's createVirtualStylesForDocDefaults() makes explicit styles out of these,
so that their effect on effective styles is explicit, rather than implicit. If you save your resulting docx, you might see these extra styles.

Re: Setting font in default styles

PostPosted: Thu Aug 19, 2010 12:30 am
by garybentley
Thanks that works perfectly :)

Here is the full code for those also wanting to set the font on a default style:

Code: Select all
                WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
       
                MainDocumentPart mp = wordMLPackage.getMainDocumentPart ();
       
                Styles styles = mp.getStyleDefinitionsPart ().getJaxbElement ();
               
                ObjectFactory factory = Context.getWmlObjectFactory ();
               
                for (Style s : styles.getStyle ())
                {

                    if (s.getName ().getVal ().equals (NORMAL))
                    {

                        RPr rpr = s.getRPr ();
                       
                        if (rpr == null)
                        {

                            rpr = factory.createRPr ();
                            s.setRPr (rpr);
                           
                        }
                       
                        RFonts rf = rpr.getRFonts ();
                       
                        if (rf == null)
                        {

                            rf = factory.createRFonts ();
                            rpr.setRFonts (rf);
                           
                        }

                        // This is where you set your font name.
                        rf.setAscii ("Verdana");
                       
                    }
                   
                }


A useful link for rFonts: http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.runfonts.aspx

docx4j classes: http://dev.plutext.org/docx4j/javadoc-2.5.0/org/docx4j/wml/RPr.html and http://dev.plutext.org/docx4j/javadoc-2.5.0/org/docx4j/wml/RFonts.html are the ones to look at here.

Thanks again for the assistance.

Gary

Re: Setting font in default styles

PostPosted: Thu Aug 19, 2010 1:52 am
by garybentley
Just one follow up question.

Setting the font like this works fine for the Normal style but for Heading 1 and Title (and I assume the other styles) my "ascii" setting is ignored.

So for Title it looks like this:

Code: Select all
<w:style w:styleId="Title" w:type="paragraph">
  <w:name w:val="Title" />
  <w:basedOn w:val="Normal" />
  <w:next w:val="Normal" />
  <w:link w:val="TitleChar" />
  <w:uiPriority w:val="10" />
  <w:qFormat />
  <w:rsid w:val="00841CD9" />
- <w:pPr>
- <w:pBdr>
  <w:bottom w:space="4" w:sz="8" w:themeColor="accent1" w:color="4F81BD" w:val="single" />
  </w:pBdr>
  <w:spacing w:after="300" />
  <w:contextualSpacing />
  </w:pPr>
- <w:rPr>
  <w:rFonts w:cstheme="majorBidi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:asciiTheme="majorHAnsi" w:ascii="Segoe Script" />
  <w:color w:themeShade="BF" w:themeColor="text2" w:val="17365D" />
  <w:spacing w:val="5" />
  <w:kern w:val="28" />
  <w:sz w:val="52" />
  <w:szCs w:val="52" />
  </w:rPr>
  </w:style>


Any idea what I'm doing wrong?

Thanks,

Gary

Re: Setting font in default styles

PostPosted: Thu Aug 19, 2010 6:23 am
by jason
Can you have both w:asciiTheme="majorHAnsi" and w:ascii="Segoe Script"?

I suggest you create a document in Word, in which you redefine the style as required, and then look at the resulting XML. Its then just a matter of replicating that in docx4j.

Re: Setting font in default styles

PostPosted: Thu Aug 19, 2010 11:25 am
by garybentley
Yes, setting:

Code: Select all
rf.setAsciiTheme (null);


did the trick :)

And if you'll indulge me in one last question (I promise), do you have any idea on how to set the horizontal alignment of the text, i.e. left/right/justify, I've scoured everything I can find and can only find details on setting the vertical alignment and superscript/subscript, it's driving me nuts!

Thanks,

Gary

Re: Setting font in default styles

PostPosted: Thu Aug 19, 2010 6:25 pm
by jason

Re: Setting font in default styles

PostPosted: Thu Aug 19, 2010 6:40 pm
by garybentley
Thanks for that. "jc" soooo obvious that it stands for "paragraph alignment". Someone at Microsoft needs a good kick.

Thanks again for all the help.

Gary