Page 1 of 1

Copy the header from one document to another

PostPosted: Tue Jun 18, 2013 3:24 am
by RedRene
Dear all,

does someone has a full working code example how to copy the complete headers/footers from on docx to another one without replacing the content. I have read the posting in docx-java-f6/replacing-copying-header-footer-t632.html but I didn't get the point how to make it work.

Thank you and regards René

Re: Copy the header from one document to another

PostPosted: Tue Jun 18, 2013 8:49 am
by jason
Does your header contain anything other than text and tables eg hyperlinks, images?

Re: Copy the header from one document to another

PostPosted: Tue Jun 18, 2013 6:38 pm
by RedRene
Hi,
in the template file of the Header (could be a dotx- or docx-file) is only normal text, but the text is inside in 2-3 textfields (the ones you can insert via the ribbon from "insert | textfield").

I have added the header template file as an attachment. This header shall be copied at runtime to other document (which are in memory as WordprocessingMLPackage, because I need to do other processing too).


Regards René

Re: Copy the header from one document to another

PostPosted: Wed Jun 19, 2013 6:11 pm
by jason
OK, it is pretty straightforward since the only rel you need to worry about is that of the new header itself.

Here are the steps:

1. get the existing header
2. create a new HeaderPart (via its constructor)
3. set the content of the new HeaderPart, using the content of the existing header (there is a clone method in XmlUtils)
4. use addTargetPart to add the new HeaderPart to the MainDocumentPart of your target docx
5. make a reference from sectPr of the MainDocumentPart of your target docx (you need to decide whether you want default/odd/even), using the rel returned by addTargetPart

For help with 5, upload a docx with the header settings you want to the webapp (see menu above), and generate code for the sectPr

Feel free to post again (with your code) if any of these steps are giving you problems.

The sample https://github.com/plutext/docx4j/blob/ ... reate.java may also be of some assistance.

Re: Copy the header from one document to another

PostPosted: Wed Jun 19, 2013 8:58 pm
by RedRene
Hi Jason,

I ran into the first challenges. I used the example HeaderFooterCreate.java and instead of creating a new WordprocessingMLPackage I used mine docx-file in which I like to insert the Header from the template file. Unfortunatly the header with the picture did not show up in the generated docx-(output)-file

1. question: Do I have to prepare the WordprocessingMLPackage-object of the docx-file in some way?
2. question: I was able to filter the 3 header parts from the relationsship list. Do I have to add all 3 in the same way to the docx-file?
Code: Select all
      RelationshipsPart rpHeader = headerFile.getMainDocumentPart().getRelationshipsPart();
      List<Relationship> relList = rpHeader.getRelationships().getRelationship();
      Iterator<Relationship> relIter = relList.iterator();
      while (relIter.hasNext()) {
         Relationship relationship = (Relationship) relIter.next();
         if (relationship.getType().equals(Namespaces.HEADER)) {
            Part pHeader = rpHeader.getPart(relationship);
            log.debug(pHeader.getPartName().getName() + " " + relationship.getType());
         }
      }
      


3. question: How can I read the Header, so that I have a Hdr-object. I found the XMLUtil.deepCopy method to copy it after I found it. Afterwards I will use the 2 methods from the example: createHeaderPart and createHeaderReference for doing your mentioned necessary tasks.

Regards René

Re: Copy the header from one document to another

PostPosted: Thu Jun 20, 2013 10:48 pm
by jason
RedRene wrote: Do I have to prepare the WordprocessingMLPackage-object of the docx-file in some way?


No.

RedRene wrote: Do I have to add all 3 in the same way to the docx-file?


There can be different headers for first page, odd/even .. see the spec for details.

https://github.com/plutext/docx4j/blob/ ... rList.java will tell you what headers you have in your source docx

But if you want the same header setup as your source docx, it is easiest just to copy them all, and use the same settings in sectPr.

RedRene wrote:How can I read the Header, so that I have a Hdr-object. I


HeaderPart's getJaxbElement() method. That is how you do it for any JAXB XML part.

Re: Copy the header from one document to another

PostPosted: Fri Jun 21, 2013 1:49 am
by RedRene
Thank you,

now I did it in that way (not the best solution, but it works for me currently)

Code: Select all
         Hdr hdrFirst = null;
         Hdr hdrEven = null;
         Hdr hdrDefault = null;
         Hdr hdrOdd = null;

         // Find the part we want to copy
         WordprocessingMLPackage headerFile = sourcefile;
         WordprocessingMLPackage docxFile = targetfile;
         log.debug("########################### HEADER FILE ##########################################");

         List<SectionWrapper> sectionWrappers = headerFile.getDocumentModel().getSections();
         SectionWrapper sw = sectionWrappers.get(0);
         HeaderFooterPolicy hfp = sw.getHeaderFooterPolicy();
         if (hfp.getFirstHeader() != null) {
            hdrFirst = hfp.getFirstHeader().getJaxbElement();
         }
         if (hfp.getDefaultHeader() != null) {
            hdrDefault = hfp.getDefaultHeader().getJaxbElement();
         }
         if (hfp.getEvenHeader() != null) {
            hdrEven = hfp.getEvenHeader().getJaxbElement();
         }
         if (hfp.getOddHeader() != null) {
            hdrOdd = hfp.getOddHeader().getJaxbElement();
         }

         log.debug("########################### DOCX FILE ##########################################");
         sectionWrappers = docxFile.getDocumentModel().getSections();
         for (SectionWrapper swd : sectionWrappers) {
            HeaderFooterPolicy hfpd = swd.getHeaderFooterPolicy();
            if (hfpd.getFirstHeader() != null) {
               hfpd.getFirstHeader().setJaxbElement(hdrFirst);
            } else if (hdrFirst != null) {
               // add new First header: 1. the Header part, 2. an entry in
               // SectPr
               Relationship relationship = createHeaderPart(docxFile, hdrFirst);
               createHeaderReference(docxFile, relationship, HdrFtrRef.FIRST);
            }
            if (hfpd.getEvenHeader() != null) {
               hfpd.getEvenHeader().setJaxbElement(hdrEven);
            }
            if (hfpd.getOddHeader() != null) {
               hfpd.getOddHeader().setJaxbElement(hdrOdd);
            }
            if (hfpd.getDefaultHeader() != null) {
               hfpd.getDefaultHeader().setJaxbElement(hdrDefault);
            }
         }


Edit: this works only when the Header is already in the target docx-file. Unfortunatly the addition of the new Header in the above code is not working.

Regards René

Re: Copy the header from one document to another

PostPosted: Tue Jun 25, 2013 10:06 am
by jason
HeaderFooterPolicy is currently intended for read-only, not for adding headers/footers.

You should write directly to the relevant sectPr (use the code generation webapp if you like).

Sorry I haven't had a spare 30 mins to write copy/pastable code for you.