createHeader/Footer methods + tests
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@805422 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c83d6bfa24
commit
05c8f883e4
@ -190,11 +190,11 @@ public class POIXMLDocumentPart {
|
||||
* @param factory the factory that will create an instance of the requested relation
|
||||
* @return the created child POIXMLDocumentPart
|
||||
*/
|
||||
protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){
|
||||
public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){
|
||||
return createRelationship(descriptor, factory, -1, false);
|
||||
}
|
||||
|
||||
protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){
|
||||
public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){
|
||||
return createRelationship(descriptor, factory, idx, false);
|
||||
}
|
||||
|
||||
@ -209,11 +209,9 @@ public class POIXMLDocumentPart {
|
||||
*/
|
||||
protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){
|
||||
try {
|
||||
|
||||
PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx));
|
||||
PackageRelationship rel = null;
|
||||
if(!noRelation) rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation());
|
||||
|
||||
PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());
|
||||
POIXMLDocumentPart doc = factory.newDocumentPart(descriptor);
|
||||
doc.packageRel = rel;
|
||||
|
@ -17,17 +17,31 @@
|
||||
package org.apache.poi.xwpf.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFFactory;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFFooter;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFHeader;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFHeaderFooter;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFRelation;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.FtrDocument;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr.Enum;
|
||||
|
||||
/**
|
||||
* A .docx file can have no headers/footers, the same header/footer
|
||||
@ -37,6 +51,12 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
|
||||
* the right headers and footers for the document.
|
||||
*/
|
||||
public class XWPFHeaderFooterPolicy {
|
||||
public static final Enum DEFAULT = STHdrFtr.DEFAULT;
|
||||
public static final Enum EVEN = STHdrFtr.EVEN;
|
||||
public static final Enum FIRST = STHdrFtr.FIRST;
|
||||
|
||||
private XWPFDocument doc;
|
||||
|
||||
private XWPFHeader firstPageHeader;
|
||||
private XWPFFooter firstPageFooter;
|
||||
|
||||
@ -57,23 +77,19 @@ 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
|
||||
this.doc = doc;
|
||||
CTSectPr sectPr = doc.getDocument().getBody().getSectPr();
|
||||
for(int i=0; i<sectPr.sizeOfHeaderReferenceArray(); i++) {
|
||||
// Get the header
|
||||
CTHdrFtrRef ref = sectPr.getHeaderReferenceArray(i);
|
||||
PackagePart hdrPart = doc.getPartById(ref.getId());
|
||||
XWPFHeader hdr = new XWPFHeader(
|
||||
HdrDocument.Factory.parse(hdrPart.getInputStream()).getHdr()
|
||||
);
|
||||
HdrDocument hdrDoc = HdrDocument.Factory.parse(hdrPart.getInputStream());
|
||||
CTHdrFtr hdrFtr = hdrDoc.getHdr();
|
||||
XWPFHeader hdr = new XWPFHeader(hdrFtr);
|
||||
|
||||
// Assign it
|
||||
if(ref.getType() == STHdrFtr.FIRST) {
|
||||
firstPageHeader = hdr;
|
||||
} else if(ref.getType() == STHdrFtr.EVEN) {
|
||||
evenPageHeader = hdr;
|
||||
} else {
|
||||
defaultHeader = hdr;
|
||||
}
|
||||
Enum type = ref.getType();
|
||||
assignHeader(hdr, type);
|
||||
}
|
||||
for(int i=0; i<sectPr.sizeOfFooterReferenceArray(); i++) {
|
||||
// Get the footer
|
||||
@ -84,16 +100,145 @@ public class XWPFHeaderFooterPolicy {
|
||||
);
|
||||
|
||||
// Assign it
|
||||
if(ref.getType() == STHdrFtr.FIRST) {
|
||||
firstPageFooter = ftr;
|
||||
} else if(ref.getType() == STHdrFtr.EVEN) {
|
||||
evenPageFooter = ftr;
|
||||
} else {
|
||||
defaultFooter = ftr;
|
||||
}
|
||||
Enum type = ref.getType();
|
||||
assignFooter(ftr, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void assignFooter(XWPFFooter ftr, Enum type) {
|
||||
if(type == STHdrFtr.FIRST) {
|
||||
firstPageFooter = ftr;
|
||||
} else if(type == STHdrFtr.EVEN) {
|
||||
evenPageFooter = ftr;
|
||||
} else {
|
||||
defaultFooter = ftr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void assignHeader(XWPFHeader hdr, Enum type) {
|
||||
if(type == STHdrFtr.FIRST) {
|
||||
firstPageHeader = hdr;
|
||||
} else if(type == STHdrFtr.EVEN) {
|
||||
evenPageHeader = hdr;
|
||||
} else {
|
||||
defaultHeader = hdr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public XWPFHeader createHeader(Enum type) 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);
|
||||
|
||||
CTHdrFtr hdr = buildHdr(type, pStyle, wrapper);
|
||||
|
||||
OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
|
||||
hdrDoc.setHdr(hdr);
|
||||
|
||||
XmlOptions xmlOptions = commit(wrapper);
|
||||
|
||||
assignHeader(wrapper, type);
|
||||
hdrDoc.save(outputStream, xmlOptions);
|
||||
outputStream.close();
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
public XWPFFooter createFooter(Enum type) 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);
|
||||
|
||||
CTHdrFtr ftr = buildFtr(type, pStyle, wrapper);
|
||||
|
||||
OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
|
||||
ftrDoc.setFtr(ftr);
|
||||
|
||||
XmlOptions xmlOptions = commit(wrapper);
|
||||
|
||||
assignFooter(wrapper, type);
|
||||
ftrDoc.save(outputStream, xmlOptions);
|
||||
outputStream.close();
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
private int getRelationIndex(XWPFRelation relation) {
|
||||
List<POIXMLDocumentPart> relations = doc.getRelations();
|
||||
int i = 1;
|
||||
for (Iterator<POIXMLDocumentPart> it = relations.iterator(); it.hasNext() ; ) {
|
||||
POIXMLDocumentPart item = it.next();
|
||||
if (item.getPackageRelationship().getRelationshipType().equals(relation.getRelation())) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
private CTHdrFtr buildFtr(Enum type, String pStyle, XWPFHeaderFooter wrapper) {
|
||||
CTHdrFtr ftr = buildHdrFtr(pStyle);
|
||||
setFooterReference(type, wrapper);
|
||||
return ftr;
|
||||
}
|
||||
|
||||
|
||||
private CTHdrFtr buildHdr(Enum type, String pStyle, XWPFHeaderFooter wrapper) {
|
||||
CTHdrFtr hdr = buildHdrFtr(pStyle);
|
||||
setHeaderReference(type, wrapper);
|
||||
return hdr;
|
||||
}
|
||||
|
||||
|
||||
private CTHdrFtr buildHdrFtr(String pStyle) {
|
||||
CTHdrFtr ftr = CTHdrFtr.Factory.newInstance();
|
||||
CTP p = ftr.addNewP();
|
||||
byte[] rsidr = doc.getDocument().getBody().getPArray()[0].getRsidR();
|
||||
byte[] rsidrdefault = doc.getDocument().getBody().getPArray()[0].getRsidRDefault();
|
||||
p.setRsidP(rsidr);
|
||||
p.setRsidRDefault(rsidrdefault);
|
||||
CTPPr pPr = p.addNewPPr();
|
||||
pPr.addNewPStyle().setVal(pStyle);
|
||||
return ftr;
|
||||
}
|
||||
|
||||
|
||||
private void setFooterReference(Enum type, XWPFHeaderFooter wrapper) {
|
||||
CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewFooterReference();
|
||||
ref.setType(type);
|
||||
ref.setId(wrapper.getPackageRelationship().getId());
|
||||
}
|
||||
|
||||
|
||||
private void setHeaderReference(Enum type, XWPFHeaderFooter wrapper) {
|
||||
CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewHeaderReference();
|
||||
ref.setType(type);
|
||||
ref.setId(wrapper.getPackageRelationship().getId());
|
||||
}
|
||||
|
||||
|
||||
private XmlOptions commit(XWPFHeaderFooter wrapper) {
|
||||
XmlOptions xmlOptions = new XmlOptions(wrapper.DEFAULT_XML_OPTIONS);
|
||||
Map map = new HashMap();
|
||||
map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
|
||||
map.put("urn:schemas-microsoft-com:office:office", "o");
|
||||
map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
|
||||
map.put("urn:schemas-microsoft-com:vml", "v");
|
||||
map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
|
||||
map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
|
||||
map.put("urn:schemas-microsoft-com:office:word", "w10");
|
||||
map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne");
|
||||
map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
|
||||
xmlOptions.setSaveSuggestedPrefixes(map);
|
||||
return xmlOptions;
|
||||
}
|
||||
|
||||
public XWPFHeader getFirstPageHeader() {
|
||||
return firstPageHeader;
|
||||
|
@ -16,6 +16,10 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.xwpf.usermodel;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
|
||||
|
||||
/**
|
||||
@ -28,5 +32,9 @@ public class XWPFFooter extends XWPFHeaderFooter {
|
||||
public XWPFFooter(CTHdrFtr hdrFtr) {
|
||||
super(hdrFtr);
|
||||
}
|
||||
|
||||
public XWPFFooter(PackagePart part, PackageRelationship rel) throws IOException {
|
||||
super(part, rel);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,10 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.xwpf.usermodel;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
|
||||
|
||||
/**
|
||||
@ -28,5 +32,9 @@ public class XWPFHeader extends XWPFHeaderFooter {
|
||||
public XWPFHeader(CTHdrFtr hdrFtr) {
|
||||
super(hdrFtr);
|
||||
}
|
||||
|
||||
public XWPFHeader(PackagePart part, PackageRelationship rel) throws IOException {
|
||||
super(part, rel);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,12 +16,17 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.xwpf.usermodel;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
|
||||
|
||||
/**
|
||||
* Parent of XWPF headers and footers
|
||||
*/
|
||||
public abstract class XWPFHeaderFooter {
|
||||
public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
|
||||
protected CTHdrFtr headerFooter;
|
||||
|
||||
protected XWPFHeaderFooter(CTHdrFtr hdrFtr) {
|
||||
@ -30,6 +35,10 @@ public abstract class XWPFHeaderFooter {
|
||||
protected XWPFHeaderFooter() {
|
||||
headerFooter = CTHdrFtr.Factory.newInstance();
|
||||
}
|
||||
|
||||
public XWPFHeaderFooter(PackagePart part, PackageRelationship rel) throws IOException {
|
||||
super(part, rel);
|
||||
}
|
||||
|
||||
public CTHdrFtr _getHdrFtr() {
|
||||
return headerFooter;
|
||||
|
@ -86,13 +86,13 @@ public final class XWPFRelation extends POIXMLRelation {
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
|
||||
"/word/header#.xml",
|
||||
null
|
||||
XWPFHeader.class
|
||||
);
|
||||
public static final XWPFRelation FOOTER = new XWPFRelation(
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
|
||||
"/word/footer#.xml",
|
||||
null
|
||||
XWPFFooter.class
|
||||
);
|
||||
public static final XWPFRelation HYPERLINK = new XWPFRelation(
|
||||
null,
|
||||
|
@ -0,0 +1,77 @@
|
||||
/* ====================================================================
|
||||
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.xwpf.usermodel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.POIXMLDocument;
|
||||
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
|
||||
|
||||
public class TestXWPFHeader extends TestCase {
|
||||
|
||||
public void testSimpleHeader() throws IOException {
|
||||
File sampleFile = new File(
|
||||
System.getProperty("HWPF.testdata.path") +
|
||||
File.separator + "headerFooter.docx"
|
||||
);
|
||||
assertTrue(sampleFile.exists());
|
||||
XWPFDocument sampleDoc;
|
||||
sampleDoc = new XWPFDocument(
|
||||
POIXMLDocument.openPackage(sampleFile.toString())
|
||||
);
|
||||
|
||||
XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
|
||||
|
||||
|
||||
XWPFHeader header = policy.getDefaultHeader();
|
||||
XWPFFooter footer = policy.getDefaultFooter();
|
||||
assertNotNull(header);
|
||||
assertNotNull(footer);
|
||||
|
||||
// TODO verify if the following is correct
|
||||
assertNull(header.toString());
|
||||
|
||||
}
|
||||
|
||||
public void testSetHeader() throws IOException {
|
||||
File sampleFile = new File(
|
||||
System.getProperty("HWPF.testdata.path") +
|
||||
File.separator + "sampleDoc.docx"
|
||||
);
|
||||
assertTrue(sampleFile.exists());
|
||||
XWPFDocument sampleDoc;
|
||||
sampleDoc = new XWPFDocument(
|
||||
POIXMLDocument.openPackage(sampleFile.toString())
|
||||
);
|
||||
// no header is set (yet)
|
||||
XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
|
||||
assertNull(policy.getDefaultHeader());
|
||||
// set a default header and test it is not null
|
||||
policy.createHeader(policy.DEFAULT);
|
||||
policy.createHeader(policy.FIRST);
|
||||
policy.createFooter(policy.DEFAULT);
|
||||
|
||||
assertNotNull(policy.getDefaultHeader());
|
||||
assertNotNull(policy.getFirstPageHeader());
|
||||
assertNotNull(policy.getDefaultFooter());
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user