Page 1 of 1

First page header not appearing

PostPosted: Fri Dec 14, 2012 2:22 am
by mgrela
Hi,

I want to generate a docx document with a "first" and "default" headers using docx-2.8.1. Unfortunately, the resulting docx when opened in Microsoft Word for Mac 2011 the "default" header appears on the first page instead of the "first" header. The generated docx is attached. The first page's header should say "Cover header text" but instead is says "Content header text".
The problem can be reproduced by running the following code:

Code: Select all
package docxtest;

// imports skipped

public class HeaderTest {   

    private static org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory();

    private static P makePageBr() throws Exception {
        P p = factory.createP();
        R r = factory.createR();
        Br br = factory.createBr();
        br.setType(STBrType.PAGE);
        r.getContent().add(br);
        p.getContent().add(r);
        return p;
    }

    public static P makeParagraph(Part part, String text)
    {
   P p = factory.createP();
   R r = factory.createR(); p.getContent().add(r);
   org.docx4j.wml.Text t = factory.createText(); r.getContent().add(t);
   t.setValue(text);
   return p;
    }

    public static void main(String[] args) throws Exception {

   WordprocessingMLPackage pkg = WordprocessingMLPackage.createPackage();
   MainDocumentPart main_part = pkg.getMainDocumentPart();

   main_part.addStyledParagraphOfText("Normal", "Cover page (TODO)");

   HeaderPart cover_hdr_part = new HeaderPart(new PartName("/word/cover-header.xml")), content_hdr_part = new HeaderPart(new PartName("/word/content-header.xml"));
   pkg.getParts().put(cover_hdr_part); pkg.getParts().put(content_hdr_part);

   Hdr cover_hdr = factory.createHdr(), content_hdr = factory.createHdr();

   // Bind the header JAXB elements as representing their header parts
   cover_hdr_part.setJaxbElement(cover_hdr); content_hdr_part.setJaxbElement(content_hdr);

   // Add the reference to both header parts to the Main Document Part
   Relationship cover_hdr_rel = main_part.addTargetPart(cover_hdr_part);
   Relationship content_hdr_rel = main_part.addTargetPart(content_hdr_part);

   cover_hdr.getContent().add(makeParagraph(cover_hdr_part, "Cover header text"));
   content_hdr.getContent().add(makeParagraph(content_hdr_part, "Content header text"));

   List<SectionWrapper> sections = pkg.getDocumentModel().getSections();

   // Get last section SectPr and create a new one if it doesn't exist
   SectPr sectPr = sections.get(sections.size() - 1).getSectPr();
   if (sectPr == null ) {
       sectPr = factory.createSectPr();
       pkg.getMainDocumentPart().addObject(sectPr);
       sections.get(sections.size() - 1).setSectPr(sectPr);
   }

   // link cover and content headers
   HeaderReference hdr_ref; // this variable is reused

   hdr_ref = factory.createHeaderReference();
   hdr_ref.setId(cover_hdr_rel.getId());
   hdr_ref.setType(HdrFtrRef.FIRST);
   sectPr.getEGHdrFtrReferences().add(hdr_ref);

   hdr_ref = factory.createHeaderReference();
   hdr_ref.setId(content_hdr_rel.getId());
   hdr_ref.setType(HdrFtrRef.DEFAULT);
   sectPr.getEGHdrFtrReferences().add(hdr_ref);
   
     main_part.addObject(makePageBr());
   // end cover page

   main_part.addStyledParagraphOfText("Heading1", "Overview");
     main_part.addObject(makePageBr());
   main_part.addStyledParagraphOfText("Normal", "Second page");
     main_part.addObject(makePageBr());
   pkg.save(new java.io.File("header_test.docx"));
    }


I have found a couple of forum posts related to this problem (like here docx-java-f6/two-different-headers-from-template-t1173.html#p4103) and I've checked, that:
- both header parts contain the right content
- both header parts have relationships and are referenced in SectPr

What can be the reason why it doesn't work?

Re: First page header not appearing

PostPosted: Fri Dec 14, 2012 7:32 am
by jason
You need to add <w:titlePg /> to your sectPr.

Re: First page header not appearing

PostPosted: Fri Dec 14, 2012 10:08 pm
by mgrela
This helped, thanks a lot!

Re: First page header not appearing

PostPosted: Tue Aug 13, 2013 4:46 am
by utaylsa
Added the following to the above code and it worked perfectly!

BooleanDefaultTrue boolanDefaultTrue = new BooleanDefaultTrue();
sectPr.setTitlePg(boolanDefaultTrue);


Posting the entire code so you can see the context!

Way cool! Victory dance! Victory dance!

import java.util.List;

import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.Br;
import org.docx4j.wml.Hdr;
import org.docx4j.wml.HdrFtrRef;
import org.docx4j.wml.HeaderReference;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.STBrType;
import org.docx4j.wml.SectPr;
import org.docx4j.model.structure.SectionWrapper;

// imports skipped

public class HeaderTest {

private static org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory();

private static P makePageBr() throws Exception {
P p = factory.createP();
R r = factory.createR();
Br br = factory.createBr();
br.setType(STBrType.PAGE);
r.getContent().add(br);
p.getContent().add(r);
return p;
}

public static P makeParagraph(Part part, String text) {
P p = factory.createP();
R r = factory.createR();
p.getContent().add(r);
org.docx4j.wml.Text t = factory.createText();
r.getContent().add(t);
t.setValue(text);
return p;
}

public static void main(String[] args) throws Exception {

WordprocessingMLPackage pkg = WordprocessingMLPackage.createPackage();
MainDocumentPart main_part = pkg.getMainDocumentPart();

main_part.addStyledParagraphOfText("Normal", "Cover page (TODO)");

HeaderPart cover_hdr_part = new HeaderPart(new PartName(
"/word/cover-header.xml")), content_hdr_part = new HeaderPart(
new PartName("/word/content-header.xml"));
pkg.getParts().put(cover_hdr_part);
pkg.getParts().put(content_hdr_part);

Hdr cover_hdr = factory.createHdr(), content_hdr = factory.createHdr();

// Bind the header JAXB elements as representing their header parts
cover_hdr_part.setJaxbElement(cover_hdr);
content_hdr_part.setJaxbElement(content_hdr);

// Add the reference to both header parts to the Main Document Part
Relationship cover_hdr_rel = main_part.addTargetPart(cover_hdr_part);
Relationship content_hdr_rel = main_part
.addTargetPart(content_hdr_part);

cover_hdr.getContent().add(
makeParagraph(cover_hdr_part, "Cover header text"));
content_hdr.getContent().add(
makeParagraph(content_hdr_part, "Content header text"));

List<SectionWrapper> sections = pkg.getDocumentModel().getSections();

// Get last section SectPr and create a new one if it doesn't exist
SectPr sectPr = sections.get(sections.size() - 1).getSectPr();
if (sectPr == null) {
sectPr = factory.createSectPr();
pkg.getMainDocumentPart().addObject(sectPr);
sections.get(sections.size() - 1).setSectPr(sectPr);
}

// link cover and content headers
HeaderReference hdr_ref; // this variable is reused

hdr_ref = factory.createHeaderReference();
hdr_ref.setId(cover_hdr_rel.getId());
hdr_ref.setType(HdrFtrRef.FIRST);
sectPr.getEGHdrFtrReferences().add(hdr_ref);

hdr_ref = factory.createHeaderReference();
hdr_ref.setId(content_hdr_rel.getId());
hdr_ref.setType(HdrFtrRef.DEFAULT);
sectPr.getEGHdrFtrReferences().add(hdr_ref);

BooleanDefaultTrue boolanDefaultTrue = new BooleanDefaultTrue();
sectPr.setTitlePg(boolanDefaultTrue);


main_part.addObject(makePageBr());
// end cover page

main_part.addStyledParagraphOfText("Heading1", "Overview");
main_part.addObject(makePageBr());
main_part.addStyledParagraphOfText("Normal", "Second page");
main_part.addObject(makePageBr());
pkg.save(new java.io.File("header_test.docx"));
}
}