Browse Source

53009: Problem creating header and footer

Task-Url: https://bz.apache.org/bugzilla/show_bug.cgi?id=53009

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1764563 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_16_BETA1
Mark Murphy 7 years ago
parent
commit
37f1598ac2

+ 60
- 0
src/examples/src/org/apache/poi/xwpf/usermodel/SimpleDocumentWithHeader.java View File

@@ -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();
}
}
}

+ 62
- 0
src/java/org/apache/poi/wp/usermodel/HeaderFooterType.java View File

@@ -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);
}
}

+ 90
- 55
src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java View File

@@ -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);
}

/*

+ 63
- 19
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java View File

@@ -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 POIXMLDocument implements Document, IBody {
}
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

Loading…
Cancel
Save