com.aurel.track.exchange.docx.exporter.AddPageNrToFooter.java Source code

Java tutorial

Introduction

Here is the source code for com.aurel.track.exchange.docx.exporter.AddPageNrToFooter.java

Source

/**
 * Genji Scrum Tool and Issue Tracker
 * Copyright (C) 2015 Steinbeis GmbH & Co. KG Task Management Solutions
    
 * <a href="http://www.trackplus.com">Genji Scrum Tool</a>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/* $Id:$ */

package com.aurel.track.exchange.docx.exporter;

import java.util.List;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.docx4j.jaxb.Context;
import org.docx4j.model.structure.SectionWrapper;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.FldChar;
import org.docx4j.wml.FooterReference;
import org.docx4j.wml.Ftr;
import org.docx4j.wml.HdrFtrRef;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.STFldCharType;
import org.docx4j.wml.SectPr;
import org.docx4j.wml.Text;

public class AddPageNrToFooter {
    private static final Logger LOGGER = LogManager.getLogger(AddPageNrToFooter.class);

    private AddPageNrToFooter() {
        // Hide the constructor
    }

    /**
     * First we create the package and the factory. Then we create the footer.
     * Finally we add two pages with text to the document and save it.
     */

    static void addFooterWithPageNo(WordprocessingMLPackage wordMLPackage) {
        ObjectFactory factory = Context.getWmlObjectFactory();
        Relationship relationship = null;
        try {
            relationship = createFooterPart(wordMLPackage, factory);
        } catch (InvalidFormatException e) {
            LOGGER.error("Creating the footer part failed with " + e.getMessage());
            LOGGER.debug(ExceptionUtils.getStackTrace(e));
        }
        createFooterReference(wordMLPackage, relationship, factory);
    }

    /**
     * As in the previous example, this method creates a footer part and adds it
     * to the main document and then returns the corresponding relationship.
     *
     * @return
     * @throws InvalidFormatException
     */
    private static Relationship createFooterPart(WordprocessingMLPackage wordMLPackage, ObjectFactory factory)
            throws InvalidFormatException {
        FooterPart footerPart = new FooterPart();
        footerPart.setPackage(wordMLPackage);

        footerPart.setJaxbElement(createFooterWithPageNr(factory));

        return wordMLPackage.getMainDocumentPart().addTargetPart(footerPart);
    }

    /**
     * As in the previous example, we create a footer and a paragraph object.
     * But this time, instead of adding text to a run, we add a field. And just
     * as with the table of content, we have to add a begin and end character
     * around the actual field with the page number. Finally we add the
     * paragraph to the content of the footer and then return it.
     *
     * @return
     */
    public static Ftr createFooterWithPageNr(ObjectFactory factory) {
        Ftr ftr = factory.createFtr();
        P paragraph = factory.createP();
        addFieldBegin(paragraph, factory);
        addPageNumberField(paragraph, factory);
        addFieldEnd(paragraph, factory);
        ftr.getContent().add(paragraph);
        return ftr;
    }

    /**
     * Creating the page number field is nearly the same as creating the field
     * in the TOC example. The only difference is in the value. We use the PAGE
     * command, which prints the number of the current page, together with the
     * MERGEFORMAT switch, which indicates that the current formatting should be
     * preserved when the field is updated.
     *
     * @param paragraph
     */
    private static void addPageNumberField(P paragraph, ObjectFactory factory) {
        R run = factory.createR();
        Text txt = new Text();
        txt.setSpace("preserve");
        txt.setValue(" PAGE   \\* MERGEFORMAT ");
        run.getContent().add(factory.createRInstrText(txt));
        paragraph.getContent().add(run);
    }

    /**
     * Every fields needs to be delimited by complex field characters. This
     * method adds the delimiter that precedes the actual field to the given
     * paragraph.
     *
     * @param paragraph
     */
    private static void addFieldBegin(P paragraph, ObjectFactory factory) {
        R run = factory.createR();
        FldChar fldchar = factory.createFldChar();
        fldchar.setFldCharType(STFldCharType.BEGIN);
        run.getContent().add(fldchar);
        paragraph.getContent().add(run);
    }

    /**
     * Every fields needs to be delimited by complex field characters. This
     * method adds the delimiter that follows the actual field to the given
     * paragraph.
     *
     * @param paragraph
     */
    private static void addFieldEnd(P paragraph, ObjectFactory factory) {
        FldChar fldcharend = factory.createFldChar();
        fldcharend.setFldCharType(STFldCharType.END);
        R run3 = factory.createR();
        run3.getContent().add(fldcharend);
        paragraph.getContent().add(run3);
    }

    /**
     * This method fetches the document final section properties, and adds a
     * newly created footer reference to them.
     *
     * @param relationship
     */
    public static void createFooterReference(WordprocessingMLPackage wordMLPackage, Relationship relationship,
            ObjectFactory factory) {

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

        SectPr sectPr = sections.get(sections.size() - 1).getSectPr();
        // There is always a section wrapper, but it might not contain a sectPr
        if (sectPr == null) {
            sectPr = factory.createSectPr();
            wordMLPackage.getMainDocumentPart().addObject(sectPr);
            sections.get(sections.size() - 1).setSectPr(sectPr);
        }

        FooterReference footerReference = factory.createFooterReference();
        footerReference.setId(relationship.getId());
        footerReference.setType(HdrFtrRef.DEFAULT);
        sectPr.getEGHdrFtrReferences().add(footerReference);
    }

    /**
     * Adds a page break to the document.
     *
     * @param documentPart
     */
}