You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jm...@apache.org on 2016/10/13 01:13:45 UTC
svn commit: r1764563 - in /poi/trunk/src:
examples/src/org/apache/poi/xwpf/usermodel/
java/org/apache/poi/wp/usermodel/ ooxml/java/org/apache/poi/xwpf/model/
ooxml/java/org/apache/poi/xwpf/usermodel/
Author: jmarkmurphy
Date: Thu Oct 13 01:13:45 2016
New Revision: 1764563
URL: http://svn.apache.org/viewvc?rev=1764563&view=rev
Log:
53009: Problem creating header and footer
Task-Url: https://bz.apache.org/bugzilla/show_bug.cgi?id=53009
Added:
poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/SimpleDocumentWithHeader.java (with props)
poi/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java (with props)
Modified:
poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
Added: poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/SimpleDocumentWithHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/SimpleDocumentWithHeader.java?rev=1764563&view=auto
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/SimpleDocumentWithHeader.java (added)
+++ poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/SimpleDocumentWithHeader.java Thu Oct 13 01:13:45 2016
@@ -0,0 +1,60 @@
+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
Propchange: poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/SimpleDocumentWithHeader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/SimpleDocumentWithHeader.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: poi/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java?rev=1764563&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java (added)
+++ poi/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java Thu Oct 13 01:13:45 2016
@@ -0,0 +1,62 @@
+/* ====================================================================
+ 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);
+ }
+}
Propchange: poi/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: poi/trunk/src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java?rev=1764563&r1=1764562&r2=1764563&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java Thu Oct 13 01:13:45 2016
@@ -18,9 +18,6 @@ package org.apache.poi.xwpf.model;
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;
@@ -90,7 +87,7 @@ public class XWPFHeaderFooterPolicy {
* as required.
*/
public XWPFHeaderFooterPolicy(XWPFDocument doc) {
- this(doc, doc.getDocument().getBody().getSectPr());
+ this(doc, null);
}
/**
@@ -103,6 +100,12 @@ public class XWPFHeaderFooterPolicy {
// 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
@@ -154,7 +157,7 @@ public class XWPFHeaderFooterPolicy {
* 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);
}
@@ -163,33 +166,35 @@ public class XWPFHeaderFooterPolicy {
* 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);
}
@@ -198,25 +203,28 @@ public class XWPFHeaderFooterPolicy {
* 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) {
@@ -349,6 +357,21 @@ public class XWPFHeaderFooterPolicy {
}
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
@@ -365,19 +388,31 @@ public class XWPFHeaderFooterPolicy {
}
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);
}
/*
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java?rev=1764563&r1=1764562&r2=1764563&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java Thu Oct 13 01:13:45 2016
@@ -1,5 +1,6 @@
/* ====================================================================
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
@@ -14,6 +15,7 @@
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;
@@ -55,27 +57,13 @@ import org.apache.poi.util.Internal;
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>
@@ -438,13 +426,69 @@ public class XWPFDocument extends POIXML
}
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
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org