Page 1 of 1

how to create header and footer information for docx

PostPosted: Wed Feb 04, 2009 9:23 am
by sreemanth
how to create header and footer information for docx

Re: how to create header and footer information for docx

PostPosted: Wed Feb 04, 2009 11:56 am
by jason
Creating a header/footer is much like adding an image. See http://dev.plutext.org/trac/docx4j/browser/trunk/docx4j/src/main/java/org/docx4j/samples/AddImage.java?rev=565 for a basic example of adding an image.

You need to create the header and/or footer part, and then add it to the package (and in doing so, create a relationship in the Main Document Part's relationships).

Then you need to use that relId in the document's section properties.

The bits of XML you will end up with will look something like:

/word/_rels/document.xml.rels

Code: Select all
            <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
                <Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer1.xml"/>
                <Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/>
            </Relationships>


word/document.xml

Code: Select all
            <w:document>
                <w:body>
                    :
                    <w:sectPr>
                        <w:headerReference w:type="default" r:id="rId6"/>
                        <w:footerReference w:type="default" r:id="rId7"/>
                    </w:sectPr>
                </w:body>
            </w:document>


word/header1.xml

Code: Select all
            <w:hdr>
                <w:p>
                    <w:pPr>
                        <w:pStyle w:val="Header"/>
                    </w:pPr>
                    <w:r>
                        <w:t>My header</w:t>
                    </w:r>
                </w:p>
            </w:hdr>


footer1.xml omitted - its similar to header, except that the element is w:ftr.

The relevant objects are Ftr, FooterReference, Hdr, and HeaderReference in org.docx4j.wml

The Hdr and Ftr classes represent the elements inside the Header and
Footer part, pointed to by the HeaderReference or FooterReference
element.

If you use the JAXB ObjectFactory approach, in org.docx4j.wml.SectPr, you'll be after the field:

protected List<CTRel> egHdrFtrReferences;

If you need further help, feel free to post your code.

Re: how to create header and footer information for docx

PostPosted: Wed Feb 04, 2009 2:39 pm
by sreemanth
I am trying int the following way, but i am not able to create. can any one help why my following program is not working

package com.cwi.docx4j;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.HashMap;

import javax.xml.bind.JAXBException;

import org.docx4j.XmlUtils;
import org.docx4j.openpackaging.contenttype.ContentType;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.relationships.Relationships;
import org.docx4j.wml.Body;
import org.docx4j.wml.Hdr;
import org.docx4j.wml.HdrFtrRef;
import org.docx4j.wml.HeaderReference;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.SectPr;
import org.docx4j.wml.Text;

public class HeaderFooter {

private static ObjectFactory objectFactory = new ObjectFactory();

public static void main(String[] args) throws Docx4JException,
FileNotFoundException, JAXBException {

WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
.createPackage();

MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
createHeaderPart(wordMLPackage);

wordMLPackage.save(new File(System.getProperty("user.dir"),
"headerFooter.docx"));
mainDocumentPart.marshal(new FileOutputStream(new File(System
.getProperty("user.dir"), "headerfooter.xml")));

}

public static void createHeaderPart(
WordprocessingMLPackage wordprocessingMLPackage)
throws InvalidFormatException {
HeaderPart headerPart = new HeaderPart(
);
headerPart.setContentType(new ContentType(
"application/vnd.openxmlformats-package.relationships+xml"));

headerPart
.setRelationshipType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
headerPart.setJaxbElement(getHdr());
Relationship relationship = wordprocessingMLPackage
.addTargetPart(headerPart);

SectPr sectPr = objectFactory.createSectPr();

HeaderReference headerReference = objectFactory.createHeaderReference();
headerReference.setId(relationship.getId());
headerReference.setType(HdrFtrRef.DEFAULT);
sectPr.getEGHdrFtrReferences().add(headerReference);// add header or
// footer references
RelationshipsPart relationshipsPart = wordprocessingMLPackage
.getMainDocumentPart().getRelationshipsPart();
relationshipsPart.getRelationships().getRelationship()
.add(relationship);

wordprocessingMLPackage.getMainDocumentPart().addObject(sectPr);

wordprocessingMLPackage.getMainDocumentPart().addObject(getP());

}

public static Hdr getHdr() {

Hdr hdr = objectFactory.createHdr();

hdr.getEGBlockLevelElts().add(getP());
return hdr;

}

public static P getP() {
P headerP = objectFactory.createP();
R run1 = objectFactory.createR();
Text text = objectFactory.createText();
text.setValue("123head123");
run1.getRunContent().add(text);
headerP.getParagraphContent().add(run1);
return headerP;
}
}

Re: how to create header and footer information for docx

PostPosted: Wed Feb 04, 2009 3:19 pm
by sreemanth
Then i tried in the follwing way


package com.cwi.docx4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;

import javax.xml.bind.JAXBException;

import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.ObjectFactory;

public class HeaderFooterNew {
private static ObjectFactory objectFactory = new ObjectFactory();

public static void main(String[] args) throws Docx4JException,
FileNotFoundException, JAXBException {

WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
.createPackage();

MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
injectDocumentPart(wordMLPackage);
injectHeaderPart(wordMLPackage);

wordMLPackage.save(new File(System.getProperty("user.dir"),
"headerFooter.docx"));
mainDocumentPart.marshal(new FileOutputStream(new File(System
.getProperty("user.dir"), "headerfooter.xml")));

}

public static void injectHeaderPart(WordprocessingMLPackage wordMLPackage) {
HeaderPart headerPart;
try {
headerPart = new HeaderPart();

InputStream is = new FileInputStream(
"C:\\SVNLiberateForTest\\Docx4JProject\\resource\\header1.xml");

headerPart.unmarshal(is);

// headerPart.setJaxbElement(getHdr());

wordMLPackage.addTargetPart(headerPart);
} catch (Exception e) {
e.printStackTrace();
}
}

public static void injectDocumentPart(WordprocessingMLPackage wordMLPackage) {
MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
try {
mainDocumentPart
.unmarshal(new FileInputStream(
"C:\\SVNLiberateForTest\\Docx4JProject\\resource\\document.xml"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

still not working

Re: how to create header and footer information for docx

PostPosted: Thu Feb 05, 2009 1:54 pm
by jason
After commenting out a couple of things in your first program, it works:

Code: Select all
public class HeaderFooter {

   private static ObjectFactory objectFactory = new ObjectFactory();

   public static void main(String[] args) throws Docx4JException,
         FileNotFoundException, JAXBException {

      WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
            .createPackage();

      MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
      createHeaderPart(wordMLPackage);

      wordMLPackage.save(new File(System.getProperty("user.dir"),
            "headerFooter.docx"));
//      mainDocumentPart.marshal(new FileOutputStream(new File(System
//            .getProperty("user.dir"), "headerfooter.xml")));

   }

   public static void createHeaderPart(
         WordprocessingMLPackage wordprocessingMLPackage)
         throws InvalidFormatException {
      HeaderPart headerPart = new HeaderPart();
//      headerPart.setContentType(new ContentType(
//            "application/vnd.openxmlformats-package.relationships+xml"));
//
//      headerPart
//            .setRelationshipType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
      headerPart.setJaxbElement(getHdr());
      Relationship relationship = wordprocessingMLPackage.getMainDocumentPart()
            .addTargetPart(headerPart);

      SectPr sectPr = objectFactory.createSectPr();

      HeaderReference headerReference = objectFactory.createHeaderReference();
      headerReference.setId(relationship.getId());
      headerReference.setType(HdrFtrRef.DEFAULT);
      sectPr.getEGHdrFtrReferences().add(headerReference);// add header or
      // footer references
//      RelationshipsPart relationshipsPart = wordprocessingMLPackage
//            .getMainDocumentPart().getRelationshipsPart();
//      relationshipsPart.getRelationships().getRelationship()
//            .add(relationship);

      wordprocessingMLPackage.getMainDocumentPart().addObject(sectPr);

//      wordprocessingMLPackage.getMainDocumentPart().addObject(getP());

   }

   public static Hdr getHdr() {

      Hdr hdr = objectFactory.createHdr();

      hdr.getEGBlockLevelElts().add(getP());
      return hdr;

   }

   public static P getP() {
      P headerP = objectFactory.createP();
      R run1 = objectFactory.createR();
      Text text = objectFactory.createText();
      text.setValue("123head123");
      run1.getRunContent().add(text);
      headerP.getParagraphContent().add(run1);
      return headerP;
   }
}



With your second program, I suspect the problem is that the relId the header part is given in the document's relationships part doesn't match the id you provide in your header1.xml.

hope this helps,

Jason

Re: how to create header and footer information for docx

PostPosted: Mon Feb 09, 2009 2:35 pm
by sreemanth
Thanks for your reply jason. Can you please explain how to add binary image part to headerpart?.
How to add logo image to the headerpart?

Thanks
Sreemanth

Re: how to create header and footer information for docx

PostPosted: Wed Feb 11, 2009 11:09 am
by jason
Can you please explain how to add binary image part to headerpart?.
How to add logo image to the headerpart?


You want to end up with a .rels file for the relevant header, which contains a relationship entry pointing to the image part.

What happens when you do:

Code: Select all
headerPart.addTargetPart(imagePart)


(I haven't tried this myself)

cheers .. Jason

Re: how to create header and footer information for docx

PostPosted: Thu Feb 12, 2009 4:41 am
by jason
Hi Sreemanth

I've added to BinaryPartAbstractImage a new method which lets you specify the part the image will be attached to
(rather than just assuming it is the main document part):

Code: Select all
   /**
    * Create an image part from the provided byte array, attach it to the source part
    * (eg the main document part, a header part etc), and return it. */
   public static BinaryPartAbstractImage createImagePart(WordprocessingMLPackage wordMLPackage,
         Part sourcePart, byte[] bytes)


So now (using docx4j svn), the following example code will add an image in a header:

Code: Select all
package org.docx4j.samples;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.HashMap;

import javax.xml.bind.JAXBException;

import org.docx4j.XmlUtils;
import org.docx4j.dml.Inline;
import org.docx4j.openpackaging.contenttype.ContentType;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.relationships.Relationships;
import org.docx4j.wml.Body;
import org.docx4j.wml.Hdr;
import org.docx4j.wml.HdrFtrRef;
import org.docx4j.wml.HeaderReference;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.SectPr;
import org.docx4j.wml.Text;

public class HeaderFooter {

   private static ObjectFactory objectFactory = new ObjectFactory();

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

      WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
            .createPackage();

      MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
      
      Relationship relationship = createHeaderPart(wordMLPackage);
      
      createHeaderReference(wordMLPackage, relationship);

      wordMLPackage.save(new File(System.getProperty("user.dir"),
            "headerFooter.docx"));
//      mainDocumentPart.marshal(new FileOutputStream(new File(System
//            .getProperty("user.dir"), "headerfooter.xml")));

   }

   public static Relationship createHeaderPart(
         WordprocessingMLPackage wordprocessingMLPackage)
         throws Exception {
      
      HeaderPart headerPart = new HeaderPart();
      
      // Have to do this so that the next line can
      // add an image
      headerPart.setPackage(wordprocessingMLPackage);
      
      headerPart.setJaxbElement(getHdr(wordprocessingMLPackage, headerPart));
      return wordprocessingMLPackage.getMainDocumentPart()
            .addTargetPart(headerPart);

   }
   
   public static Hdr getHdr(WordprocessingMLPackage wordprocessingMLPackage,
         Part sourcePart) throws Exception {

      Hdr hdr = objectFactory.createHdr();
      hdr.getEGBlockLevelElts().add(
            newImage(wordprocessingMLPackage,
                  sourcePart, getBytes(), "filename", "alttext", 1, 2
                  )
      );
      return hdr;

   }
   
   public static byte[] getBytes() throws Exception {
      
      File file = new File("/home/dev/test.png" );
            
      java.io.InputStream is = new java.io.FileInputStream(file );
        long length = file.length();   
        // You cannot create an array using a long type.
        // It needs to be an int type.
        if (length > Integer.MAX_VALUE) {
           System.out.println("File too large!!");
        }
        byte[] bytes = new byte[(int)length];
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length
               && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
            offset += numRead;
        }
        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            System.out.println("Could not completely read file "+file.getName());
        }
        is.close();
       
        return bytes;            
      
   }

   

//   public static P getP() {
//      P headerP = objectFactory.createP();
//      R run1 = objectFactory.createR();
//      Text text = objectFactory.createText();
//      text.setValue("123head123");
//      run1.getRunContent().add(text);
//      headerP.getParagraphContent().add(run1);
//      return headerP;
//   }
   
   public static org.docx4j.wml.P newImage( WordprocessingMLPackage wordMLPackage,
         Part sourcePart,
         byte[] bytes,
         String filenameHint, String altText,
         int id1, int id2) throws Exception {
      
        BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage,
              sourcePart, bytes);
      
        Inline inline = imagePart.createImageInline( filenameHint, altText,
             id1, id2);
       
        // Now add the inline in w:p/w:r/w:drawing
      org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory();
      org.docx4j.wml.P  p = factory.createP();
      org.docx4j.wml.R  run = factory.createR();      
      p.getParagraphContent().add(run);       
      org.docx4j.wml.Drawing drawing = factory.createDrawing();      
      run.getRunContent().add(drawing);      
      drawing.getAnchorOrInline().add(inline);
      
      return p;
      
   }   
   
   
   public static void createHeaderReference(
         WordprocessingMLPackage wordprocessingMLPackage,
         Relationship relationship )
         throws InvalidFormatException {

      SectPr sectPr = objectFactory.createSectPr();

      HeaderReference headerReference = objectFactory.createHeaderReference();
      headerReference.setId(relationship.getId());
      headerReference.setType(HdrFtrRef.DEFAULT);
      sectPr.getEGHdrFtrReferences().add(headerReference);// add header or
      // footer references

      wordprocessingMLPackage.getMainDocumentPart().addObject(sectPr);

   }
   
}



Note that for the example to work, you need to specify an image file in the getBytes() method.

cheers

Jason