mirror of https://github.com/apache/poi.git
[github-310] Allow XWPF sections to have distinct headers and footers. Thanks to Joaquín Perez Valera. This close #310
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1898653 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c3cf4e5403
commit
ea2cc9e54c
|
@ -74,6 +74,8 @@ public class XWPFHeaderFooterPolicy {
|
||||||
|
|
||||||
private XWPFHeader defaultHeader;
|
private XWPFHeader defaultHeader;
|
||||||
private XWPFFooter defaultFooter;
|
private XWPFFooter defaultFooter;
|
||||||
|
//This variable allows to have a reference for each section, and having different headers in each of them.
|
||||||
|
private CTSectPr sectPr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Figures out the policy for the given document,
|
* Figures out the policy for the given document,
|
||||||
|
@ -101,6 +103,8 @@ public class XWPFHeaderFooterPolicy {
|
||||||
: ctBody.addNewSectPr();
|
: ctBody.addNewSectPr();
|
||||||
}
|
}
|
||||||
this.doc = doc;
|
this.doc = doc;
|
||||||
|
this.sectPr = sectPr;
|
||||||
|
|
||||||
for (int i = 0; i < sectPr.sizeOfHeaderReferenceArray(); i++) {
|
for (int i = 0; i < sectPr.sizeOfHeaderReferenceArray(); i++) {
|
||||||
// Get the header
|
// Get the header
|
||||||
CTHdrFtrRef ref = sectPr.getHeaderReferenceArray(i);
|
CTHdrFtrRef ref = sectPr.getHeaderReferenceArray(i);
|
||||||
|
@ -293,14 +297,14 @@ public class XWPFHeaderFooterPolicy {
|
||||||
|
|
||||||
|
|
||||||
private void setFooterReference(Enum type, XWPFHeaderFooter wrapper) {
|
private void setFooterReference(Enum type, XWPFHeaderFooter wrapper) {
|
||||||
CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewFooterReference();
|
CTHdrFtrRef ref = this.sectPr.addNewFooterReference();
|
||||||
ref.setType(type);
|
ref.setType(type);
|
||||||
ref.setId(doc.getRelationId(wrapper));
|
ref.setId(doc.getRelationId(wrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setHeaderReference(Enum type, XWPFHeaderFooter wrapper) {
|
private void setHeaderReference(Enum type, XWPFHeaderFooter wrapper) {
|
||||||
CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewHeaderReference();
|
CTHdrFtrRef ref = this.sectPr.addNewHeaderReference();
|
||||||
ref.setType(type);
|
ref.setType(type);
|
||||||
ref.setId(doc.getRelationId(wrapper));
|
ref.setId(doc.getRelationId(wrapper));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,213 @@
|
||||||
|
/* ====================================================================
|
||||||
|
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.model;
|
||||||
|
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFFooter;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFHeader;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
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.STHdrFtr;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
public class TestMultiSectionHeaders {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAddHeadersForTwoDistinctSections() throws IOException {
|
||||||
|
|
||||||
|
String header1Text = "Header 1 Text";
|
||||||
|
String header2Text = "Header 2 Text";
|
||||||
|
|
||||||
|
XWPFDocument doc = new XWPFDocument();
|
||||||
|
|
||||||
|
// Add first body/section paragraph
|
||||||
|
XWPFParagraph par1 = doc.createParagraph();
|
||||||
|
|
||||||
|
CTP ctp1 = par1.getCTP();
|
||||||
|
ctp1.addNewR().addNewT().setStringValue("Text for first body paragraph");
|
||||||
|
|
||||||
|
CTPPr ppr1 = null;
|
||||||
|
if (!ctp1.isSetPPr()) {
|
||||||
|
ctp1.addNewPPr();
|
||||||
|
}
|
||||||
|
ppr1 = ctp1.getPPr();
|
||||||
|
|
||||||
|
CTSectPr sec1 = null;
|
||||||
|
if (!ppr1.isSetSectPr()) {
|
||||||
|
ppr1.addNewSectPr();
|
||||||
|
}
|
||||||
|
|
||||||
|
sec1 = ppr1.getSectPr();
|
||||||
|
|
||||||
|
// Create paragraph of the first header
|
||||||
|
CTP parCTP = CTP.Factory.newInstance();
|
||||||
|
parCTP.addNewR().addNewT().setStringValue(header1Text);
|
||||||
|
XWPFParagraph headerPar1 = new XWPFParagraph(parCTP, doc);
|
||||||
|
|
||||||
|
XWPFParagraph[] headerPars1 = { headerPar1 };
|
||||||
|
|
||||||
|
XWPFHeaderFooterPolicy pol1 = new XWPFHeaderFooterPolicy(doc, sec1);
|
||||||
|
XWPFHeader header1 = pol1.createHeader(STHdrFtr.DEFAULT, headerPars1);
|
||||||
|
|
||||||
|
// Add second body/section paragraph
|
||||||
|
XWPFParagraph par2 = doc.createParagraph();
|
||||||
|
|
||||||
|
CTP ctp2 = par2.getCTP();
|
||||||
|
ctp2.addNewR().addNewT().setStringValue("Text for second body paragraph");
|
||||||
|
|
||||||
|
CTPPr ppr2 = null;
|
||||||
|
if (!ctp2.isSetPPr()) {
|
||||||
|
ctp2.addNewPPr();
|
||||||
|
}
|
||||||
|
ppr2 = ctp2.getPPr();
|
||||||
|
|
||||||
|
CTSectPr sec2 = null;
|
||||||
|
if (!ppr2.isSetSectPr()) {
|
||||||
|
ppr2.addNewSectPr();
|
||||||
|
}
|
||||||
|
|
||||||
|
sec2 = ppr2.getSectPr();
|
||||||
|
|
||||||
|
// Create paragraph of the second header
|
||||||
|
CTP parCTP2 = CTP.Factory.newInstance();
|
||||||
|
parCTP2.addNewR().addNewT().setStringValue(header2Text);
|
||||||
|
XWPFParagraph headerPar2 = new XWPFParagraph(parCTP2, doc);
|
||||||
|
|
||||||
|
XWPFParagraph[] headerPars2 = { headerPar2 };
|
||||||
|
|
||||||
|
XWPFHeaderFooterPolicy pol2 = new XWPFHeaderFooterPolicy(doc, sec2);
|
||||||
|
XWPFHeader header2 = pol2.createHeader(STHdrFtr.DEFAULT, headerPars2);
|
||||||
|
|
||||||
|
// Validate the headers are not null
|
||||||
|
assertNotNull(header1.getListParagraph().get(0));
|
||||||
|
assertNotNull(header2.getListParagraph().get(0));
|
||||||
|
|
||||||
|
// Validate the headers are not equal
|
||||||
|
assertNotEquals(header1, header2);
|
||||||
|
|
||||||
|
String textFromHeader1 = header1.getListParagraph().get(0).getCTP().getRArray()[0].getTArray()[0]
|
||||||
|
.getStringValue();
|
||||||
|
// Validate the text is equal to the text we assigned
|
||||||
|
assertEquals(header1Text, textFromHeader1);
|
||||||
|
|
||||||
|
String textFromHeader2 = header2.getListParagraph().get(0).getCTP().getRArray()[0].getTArray()[0]
|
||||||
|
.getStringValue();
|
||||||
|
// Validate the text is equal to the text we assigned
|
||||||
|
assertEquals(header2Text, textFromHeader2);
|
||||||
|
|
||||||
|
// Validate the headers text are not equal
|
||||||
|
assertNotEquals(header1Text, header2Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAddFootersForTwoDistinctSections() throws IOException {
|
||||||
|
|
||||||
|
String footer1Text = "Footer 1 Text";
|
||||||
|
String footer2Text = "Footer 2 Text";
|
||||||
|
|
||||||
|
XWPFDocument doc = new XWPFDocument();
|
||||||
|
|
||||||
|
// Add first body/section paragraph
|
||||||
|
XWPFParagraph par1 = doc.createParagraph();
|
||||||
|
|
||||||
|
CTP ctp1 = par1.getCTP();
|
||||||
|
ctp1.addNewR().addNewT().setStringValue("Text for first body paragraph");
|
||||||
|
|
||||||
|
CTPPr ppr1 = null;
|
||||||
|
if (!ctp1.isSetPPr()) {
|
||||||
|
ctp1.addNewPPr();
|
||||||
|
}
|
||||||
|
ppr1 = ctp1.getPPr();
|
||||||
|
|
||||||
|
CTSectPr sec1 = null;
|
||||||
|
if (!ppr1.isSetSectPr()) {
|
||||||
|
ppr1.addNewSectPr();
|
||||||
|
}
|
||||||
|
|
||||||
|
sec1 = ppr1.getSectPr();
|
||||||
|
|
||||||
|
// Create paragraph of the first footer
|
||||||
|
CTP parCTP = CTP.Factory.newInstance();
|
||||||
|
parCTP.addNewR().addNewT().setStringValue(footer1Text);
|
||||||
|
XWPFParagraph footerPar1 = new XWPFParagraph(parCTP, doc);
|
||||||
|
|
||||||
|
XWPFParagraph[] footerPars1 = { footerPar1 };
|
||||||
|
|
||||||
|
XWPFHeaderFooterPolicy pol1 = new XWPFHeaderFooterPolicy(doc, sec1);
|
||||||
|
XWPFFooter footer1 = pol1.createFooter(STHdrFtr.DEFAULT, footerPars1);
|
||||||
|
|
||||||
|
// Add second body/section paragraph
|
||||||
|
XWPFParagraph par2 = doc.createParagraph();
|
||||||
|
|
||||||
|
CTP ctp2 = par2.getCTP();
|
||||||
|
ctp2.addNewR().addNewT().setStringValue("Text for second body paragraph");
|
||||||
|
|
||||||
|
CTPPr ppr2 = null;
|
||||||
|
if (!ctp2.isSetPPr()) {
|
||||||
|
ctp2.addNewPPr();
|
||||||
|
}
|
||||||
|
ppr2 = ctp2.getPPr();
|
||||||
|
|
||||||
|
CTSectPr sec2 = null;
|
||||||
|
if (!ppr2.isSetSectPr()) {
|
||||||
|
ppr2.addNewSectPr();
|
||||||
|
}
|
||||||
|
|
||||||
|
sec2 = ppr2.getSectPr();
|
||||||
|
|
||||||
|
// Create paragraph of the second footer
|
||||||
|
CTP parCTP2 = CTP.Factory.newInstance();
|
||||||
|
parCTP2.addNewR().addNewT().setStringValue(footer2Text);
|
||||||
|
XWPFParagraph footerPar2 = new XWPFParagraph(parCTP2, doc);
|
||||||
|
|
||||||
|
XWPFParagraph[] footerPars2 = { footerPar2 };
|
||||||
|
|
||||||
|
XWPFHeaderFooterPolicy pol2 = new XWPFHeaderFooterPolicy(doc, sec2);
|
||||||
|
XWPFFooter footer2 = pol2.createFooter(STHdrFtr.DEFAULT, footerPars2);
|
||||||
|
|
||||||
|
// Validate the footers are not null
|
||||||
|
assertNotNull(footer1.getListParagraph().get(0));
|
||||||
|
assertNotNull(footer2.getListParagraph().get(0));
|
||||||
|
|
||||||
|
// Validate the footers are not equal, as objects
|
||||||
|
assertNotEquals(footer1, footer2);
|
||||||
|
|
||||||
|
String textFromHeader1 = footer1.getListParagraph().get(0).getCTP().getRArray()[0].getTArray()[0]
|
||||||
|
.getStringValue();
|
||||||
|
// Validate the text is equal to the text we assigned
|
||||||
|
assertEquals(footer1Text, textFromHeader1);
|
||||||
|
|
||||||
|
String textFromHeader2 = footer2.getListParagraph().get(0).getCTP().getRArray()[0].getTArray()[0]
|
||||||
|
.getStringValue();
|
||||||
|
// Validate the text is equal to the text we assigned
|
||||||
|
assertEquals(footer2Text, textFromHeader2);
|
||||||
|
|
||||||
|
// Validate the footers text are not equal
|
||||||
|
assertNotEquals(footer1Text, footer2Text);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue