diff options
author | PJ Fanning <fanningpj@apache.org> | 2022-03-06 13:27:16 +0000 |
---|---|---|
committer | PJ Fanning <fanningpj@apache.org> | 2022-03-06 13:27:16 +0000 |
commit | ea2cc9e54c8ca02ac62785582c204df3355f9d2b (patch) | |
tree | a5e8e3e211fd02a8452cce0719109786cebeb820 /poi-ooxml/src | |
parent | c3cf4e5403fdc61dd14044e9688ed9e654b9e2af (diff) | |
download | poi-ea2cc9e54c8ca02ac62785582c204df3355f9d2b.tar.gz poi-ea2cc9e54c8ca02ac62785582c204df3355f9d2b.zip |
[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
Diffstat (limited to 'poi-ooxml/src')
-rw-r--r-- | poi-ooxml/src/main/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java | 10 | ||||
-rw-r--r-- | poi-ooxml/src/test/java/org/apache/poi/xwpf/model/TestMultiSectionHeaders.java | 213 |
2 files changed, 220 insertions, 3 deletions
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java b/poi-ooxml/src/main/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java index f45728f0af..368f813b47 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java @@ -74,6 +74,8 @@ public class XWPFHeaderFooterPolicy { private XWPFHeader defaultHeader; 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, @@ -101,6 +103,8 @@ public class XWPFHeaderFooterPolicy { : ctBody.addNewSectPr(); } this.doc = doc; + this.sectPr = sectPr; + for (int i = 0; i < sectPr.sizeOfHeaderReferenceArray(); i++) { // Get the header CTHdrFtrRef ref = sectPr.getHeaderReferenceArray(i); @@ -293,14 +297,14 @@ public class XWPFHeaderFooterPolicy { private void setFooterReference(Enum type, XWPFHeaderFooter wrapper) { - CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewFooterReference(); + CTHdrFtrRef ref = this.sectPr.addNewFooterReference(); ref.setType(type); ref.setId(doc.getRelationId(wrapper)); } private void setHeaderReference(Enum type, XWPFHeaderFooter wrapper) { - CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewHeaderReference(); + CTHdrFtrRef ref = this.sectPr.addNewHeaderReference(); ref.setType(type); ref.setId(doc.getRelationId(wrapper)); } @@ -494,4 +498,4 @@ public class XWPFHeaderFooterPolicy { // end watermark paragraph return new XWPFParagraph(p, doc); } -} +}
\ No newline at end of file diff --git a/poi-ooxml/src/test/java/org/apache/poi/xwpf/model/TestMultiSectionHeaders.java b/poi-ooxml/src/test/java/org/apache/poi/xwpf/model/TestMultiSectionHeaders.java new file mode 100644 index 0000000000..6a0d4c2475 --- /dev/null +++ b/poi-ooxml/src/test/java/org/apache/poi/xwpf/model/TestMultiSectionHeaders.java @@ -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); + + } + +} |