--- /dev/null
+package org.apache.poi.xwpf.usermodel;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFRun;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
+
+/**
+ *
+ * @author Richard Ngo
+ *
+ */
+public class SimpleDocumentWithHeader {
+
+ private static XWPFParagraph[] pars;
+
+ public static void main(String[] args) {
+ XWPFDocument doc = new XWPFDocument();
+
+ XWPFParagraph p = doc.createParagraph();
+
+ XWPFRun r = p.createRun();
+ r.setText("Some Text");
+ r.setBold(true);
+ r = p.createRun();
+ r.setText("Goodbye");
+
+ CTP ctP = CTP.Factory.newInstance();
+ CTText t = ctP.addNewR().addNewT();
+ t.setStringValue("header");
+ pars = new XWPFParagraph[1];
+ p = new XWPFParagraph(ctP, doc);
+ pars[0] = p;
+
+ XWPFHeaderFooterPolicy hfPolicy = doc.createHeaderFooterPolicy();
+ hfPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT, pars);
+
+ ctP = CTP.Factory.newInstance();
+ t = ctP.addNewR().addNewT();
+ t.setStringValue("My Footer");
+ pars[0] = new XWPFParagraph(ctP, doc);
+ hfPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, pars);
+
+ try {
+ OutputStream os = new FileOutputStream(new File("header.docx"));
+ doc.write(os);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.wp.usermodel;
+
+/**
+ * @since POI v3.16 beta 1
+ */
+public enum HeaderFooterType {
+
+ /**
+ * This is the default header or Footer, It is displayed on every page where
+ * a more specific header or footer is not specified. It is always displayed
+ * on ODD pages that are not the first page of the section.
+ */
+ DEFAULT(2),
+
+ /**
+ * This is an even page header or footer, it is displayed on even pages that
+ * are not the first page of the section.
+ */
+ EVEN(1),
+
+ /**
+ * This is a first page header or footer It is displayed on the first page
+ * of the section.
+ */
+ FIRST(3);
+
+ private final int code;
+
+ private HeaderFooterType(int i) {
+ code = i;
+ }
+
+ public int toInt() {
+ return code;
+ }
+
+ public static HeaderFooterType forInt(int i) {
+ for (HeaderFooterType type : values()) {
+ if (type.code == i) {
+ return type;
+ }
+ }
+ throw new IllegalArgumentException("Invalid HeaderFooterType code: " + i);
+ }
+}
import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
-import java.io.IOException;
-import java.io.OutputStream;
-
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLDocumentPart.RelationPart;
import org.apache.poi.util.POILogFactory;
* as required.
*/
public XWPFHeaderFooterPolicy(XWPFDocument doc) {
- this(doc, doc.getDocument().getBody().getSectPr());
+ this(doc, null);
}
/**
// For now, we don't care about different ranges, as it
// doesn't seem that .docx properly supports that
// feature of the file format yet
+ if (sectPr == null) {
+ CTBody ctBody = doc.getDocument().getBody();
+ sectPr = ctBody.isSetSectPr()
+ ? ctBody.getSectPr()
+ : ctBody.addNewSectPr();
+ }
this.doc = doc;
for (int i = 0; i < sectPr.sizeOfHeaderReferenceArray(); i++) {
// Get the header
* Creates an empty header of the specified type, containing a single
* empty paragraph, to which you can then set text, add more paragraphs etc.
*/
- public XWPFHeader createHeader(Enum type) throws IOException {
+ public XWPFHeader createHeader(Enum type) {
return createHeader(type, null);
}
* supplied (and previously unattached!) paragraphs are
* added to.
*/
- public XWPFHeader createHeader(Enum type, XWPFParagraph[] pars) throws IOException {
- XWPFRelation relation = XWPFRelation.HEADER;
- String pStyle = "Header";
- int i = getRelationIndex(relation);
- HdrDocument hdrDoc = HdrDocument.Factory.newInstance();
-
- XWPFHeader wrapper = (XWPFHeader) doc.createRelationship(relation, XWPFFactory.getInstance(), i);
- wrapper.setXWPFDocument(doc);
-
- CTHdrFtr hdr = buildHdr(type, pStyle, wrapper, pars);
- wrapper.setHeaderFooter(hdr);
-
- OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
- hdrDoc.setHdr(hdr);
-
- assignHeader(wrapper, type);
- hdrDoc.save(outputStream, DEFAULT_XML_OPTIONS);
- outputStream.close();
-
- return wrapper;
+ public XWPFHeader createHeader(Enum type, XWPFParagraph[] pars) {
+ XWPFHeader header = getHeader(type);
+
+ if (header == null) {
+ HdrDocument hdrDoc = HdrDocument.Factory.newInstance();
+
+ XWPFRelation relation = XWPFRelation.HEADER;
+ int i = getRelationIndex(relation);
+
+ XWPFHeader wrapper = (XWPFHeader) doc.createRelationship(relation,
+ XWPFFactory.getInstance(), i);
+ wrapper.setXWPFDocument(doc);
+
+ String pStyle = "Header";
+ CTHdrFtr hdr = buildHdr(type, pStyle, wrapper, pars);
+ wrapper.setHeaderFooter(hdr);
+ hdrDoc.setHdr(hdr);
+ assignHeader(wrapper, type);
+ header = wrapper;
+ }
+
+ return header;
}
/**
* Creates an empty footer of the specified type, containing a single
* empty paragraph, to which you can then set text, add more paragraphs etc.
*/
- public XWPFFooter createFooter(Enum type) throws IOException {
+ public XWPFFooter createFooter(Enum type) {
return createFooter(type, null);
}
* supplied (and previously unattached!) paragraphs are
* added to.
*/
- public XWPFFooter createFooter(Enum type, XWPFParagraph[] pars) throws IOException {
- XWPFRelation relation = XWPFRelation.FOOTER;
- String pStyle = "Footer";
- int i = getRelationIndex(relation);
- FtrDocument ftrDoc = FtrDocument.Factory.newInstance();
-
- XWPFFooter wrapper = (XWPFFooter) doc.createRelationship(relation, XWPFFactory.getInstance(), i);
- wrapper.setXWPFDocument(doc);
-
- CTHdrFtr ftr = buildFtr(type, pStyle, wrapper, pars);
- wrapper.setHeaderFooter(ftr);
-
- OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
- ftrDoc.setFtr(ftr);
-
- assignFooter(wrapper, type);
- ftrDoc.save(outputStream, DEFAULT_XML_OPTIONS);
- outputStream.close();
- return wrapper;
+ public XWPFFooter createFooter(Enum type, XWPFParagraph[] pars) {
+ XWPFFooter footer = getFooter(type);
+
+ if (footer == null) {
+ FtrDocument ftrDoc = FtrDocument.Factory.newInstance();
+
+ XWPFRelation relation = XWPFRelation.FOOTER;
+ int i = getRelationIndex(relation);
+
+ XWPFFooter wrapper = (XWPFFooter) doc.createRelationship(relation,
+ XWPFFactory.getInstance(), i);
+ wrapper.setXWPFDocument(doc);
+
+ String pStyle = "Footer";
+ CTHdrFtr ftr = buildFtr(type, pStyle, wrapper, pars);
+ wrapper.setHeaderFooter(ftr);
+ ftrDoc.setFtr(ftr);
+ assignFooter(wrapper, type);
+ footer = wrapper;
+ }
+
+ return footer;
}
private int getRelationIndex(XWPFRelation relation) {
}
return defaultHeader;
}
+
+ /**
+ * Get this section header for the given type
+ *
+ * @param type of header to return
+ * @return {@link XWPFHeader} object
+ */
+ public XWPFHeader getHeader(Enum type) {
+ if (type == STHdrFtr.EVEN) {
+ return evenPageHeader;
+ } else if (type == STHdrFtr.FIRST) {
+ return firstPageHeader;
+ }
+ return defaultHeader;
+ }
/**
* Get the footer that applies to the given
}
return defaultFooter;
}
+
+ /**
+ * Get this section footer for the given type
+ *
+ * @param type of footer to return
+ * @return {@link XWPFFooter} object
+ */
+ public XWPFFooter getFooter(Enum type) {
+ if (type == STHdrFtr.EVEN) {
+ return evenPageFooter;
+ } else if (type == STHdrFtr.FIRST) {
+ return firstPageFooter;
+ }
+ return defaultFooter;
+ }
+
public void createWatermark(String text) {
XWPFParagraph[] pars = new XWPFParagraph[1];
- try {
- pars[0] = getWatermarkParagraph(text, 1);
- createHeader(DEFAULT, pars);
- pars[0] = getWatermarkParagraph(text, 2);
- createHeader(FIRST, pars);
- pars[0] = getWatermarkParagraph(text, 3);
- createHeader(EVEN, pars);
- } catch (IOException e) {
- LOG.log(POILogger.ERROR, "error while creating watermark", e);
- }
+ pars[0] = getWatermarkParagraph(text, 1);
+ createHeader(DEFAULT, pars);
+ pars[0] = getWatermarkParagraph(text, 2);
+ createHeader(FIRST, pars);
+ pars[0] = getWatermarkParagraph(text, 3);
+ createHeader(EVEN, pars);
}
/*
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
+
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
+
package org.apache.poi.xwpf.usermodel;
import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.PackageHelper;
+import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComment;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CommentsDocument;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.EndnotesDocument;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.FootnotesDocument;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.NumberingDocument;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocProtect;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
/**
* <p>High(ish) level class for working with .docx files.</p>
}
public XWPFHeaderFooterPolicy createHeaderFooterPolicy() {
if (headerFooterPolicy == null) {
- if (! ctDocument.getBody().isSetSectPr()) {
- ctDocument.getBody().addNewSectPr();
- }
+// if (! ctDocument.getBody().isSetSectPr()) {
+// ctDocument.getBody().addNewSectPr();
+// }
headerFooterPolicy = new XWPFHeaderFooterPolicy(this);
}
return headerFooterPolicy;
}
+
+ /**
+ * Create a header of the given type
+ *
+ * @param type {@link HeaderFooterType} enum
+ * @return object of type {@link XWPFHeader}
+ */
+ public XWPFHeader createHeader(HeaderFooterType type) {
+ XWPFHeaderFooterPolicy hfPolicy = createHeaderFooterPolicy();
+ // TODO this needs to be migrated out into section code
+ if (type == HeaderFooterType.FIRST) {
+ CTSectPr ctSectPr = getSection();
+ if (ctSectPr.isSetTitlePg() == false) {
+ CTOnOff titlePg = ctSectPr.addNewTitlePg();
+ titlePg.setVal(STOnOff.ON);
+ }
+ } else if (type == HeaderFooterType.EVEN) {
+ // TODO Add support for Even/Odd headings and footers
+ }
+ return hfPolicy.createHeader(STHdrFtr.Enum.forInt(type.toInt()));
+ }
+
+
+ /**
+ * Create a footer of the given type
+ *
+ * @param type {@link HeaderFooterType} enum
+ * @return object of type {@link XWPFFooter}
+ */
+ public XWPFFooter createFooter(HeaderFooterType type) {
+ XWPFHeaderFooterPolicy hfPolicy = createHeaderFooterPolicy();
+ // TODO this needs to be migrated out into section code
+ if (type == HeaderFooterType.FIRST) {
+ CTSectPr ctSectPr = getSection();
+ if (ctSectPr.isSetTitlePg() == false) {
+ CTOnOff titlePg = ctSectPr.addNewTitlePg();
+ titlePg.setVal(STOnOff.ON);
+ }
+ } else if (type == HeaderFooterType.EVEN) {
+ // TODO Add support for Even/Odd headings and footers
+ }
+ return hfPolicy.createFooter(STHdrFtr.Enum.forInt(type.toInt()));
+ }
+
+ /**
+ * Return the {@link CTSectPr} object that corresponds with the
+ * last section in this document.
+ *
+ * @return {@link CTSectPr} object
+ */
+ private CTSectPr getSection() {
+ CTBody ctBody = getDocument().getBody();
+ return (ctBody.isSetSectPr() ?
+ ctBody.getSectPr() :
+ ctBody.addNewSectPr());
+ }
/**
* Returns the styles object used