]> source.dussan.org Git - poi.git/commitdiff
[github-310] Allow XWPF sections to have distinct headers and footers. Thanks to...
authorPJ Fanning <fanningpj@apache.org>
Sun, 6 Mar 2022 13:27:16 +0000 (13:27 +0000)
committerPJ Fanning <fanningpj@apache.org>
Sun, 6 Mar 2022 13:27:16 +0000 (13:27 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1898653 13f79535-47bb-0310-9956-ffa450edef68

poi-ooxml/src/main/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
poi-ooxml/src/test/java/org/apache/poi/xwpf/model/TestMultiSectionHeaders.java [new file with mode: 0644]

index f45728f0afc8b1bc4c07298728c9b9e1ad10b0fc..368f813b474347ef375a8d636a84df87f62387ee 100644 (file)
@@ -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 (file)
index 0000000..6a0d4c2
--- /dev/null
@@ -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);
+
+    }
+
+}