// create header/footer functions insert an empty paragraph
XWPFHeader head = doc.createHeader(HeaderFooterType.DEFAULT);
- p = head.getParagraphArray(0);
- r = p.createRun();
- r.setText("header");
+ head.createParagraph().createRun().setText("header");
XWPFFooter foot = doc.createFooter(HeaderFooterType.DEFAULT);
- p = foot.getParagraphArray(0);
- r = p.createRun();
- r.setText("footer");
+ foot.createParagraph().createRun().setText("footer");
try {
OutputStream os = new FileOutputStream(new File("header2.docx"));
--- /dev/null
+/* ====================================================================
+ 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.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+
+import org.apache.poi.wp.usermodel.HeaderFooterType;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblLayoutType;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblLayoutType;
+
+public class HeaderFooterTable {
+
+ public static void main(String[] args) throws IOException {
+ XWPFDocument doc = new XWPFDocument();
+
+ // Create a header with a 1 row, 3 column table
+ // changes made for issue 57366 allow a new header or footer
+ // to be created empty. This is a change. You will have to add
+ // either a paragraph or a table to the header or footer for
+ // the document to be considered valid.
+ XWPFHeader hdr = doc.createHeader(HeaderFooterType.DEFAULT);
+ XWPFTable tbl = hdr.createTable(1, 3);
+
+ // Set the padding around text in the cells to 1/10th of an inch
+ int pad = (int) (.1 * 1440);
+ tbl.setCellMargins(pad, pad, pad, pad);
+
+ // Set table width to 6.5 inches in 1440ths of a point
+ tbl.setWidth((int)(6.5 * 1440));
+ // Can not yet set table or cell width properly, tables default to
+ // autofit layout, and this requires fixed layout
+ CTTbl ctTbl = tbl.getCTTbl();
+ CTTblPr ctTblPr = ctTbl.addNewTblPr();
+ CTTblLayoutType layoutType = ctTblPr.addNewTblLayout();
+ layoutType.setType(STTblLayoutType.FIXED);
+
+ // Now set up a grid for the table, cells will fit into the grid
+ // Each cell width is 3120 in 1440ths of an inch, or 1/3rd of 6.5"
+ BigInteger w = new BigInteger("3120");
+ CTTblGrid grid = ctTbl.addNewTblGrid();
+ for (int i = 0; i < 3; i++) {
+ CTTblGridCol gridCol = grid.addNewGridCol();
+ gridCol.setW(w);
+ }
+
+ // Add paragraphs to the cells
+ XWPFTableRow row = tbl.getRow(0);
+ XWPFTableCell cell = row.getCell(0);
+ XWPFParagraph p = cell.getParagraphArray(0);
+ XWPFRun r = p.createRun();
+ r.setText("header left cell");
+
+ cell = row.getCell(1);
+ p = cell.getParagraphArray(0);
+ r = p.createRun();
+ r.setText("header center cell");
+
+ cell = row.getCell(2);
+ p = cell.getParagraphArray(0);
+ r = p.createRun();
+ r.setText("header right cell");
+
+ // Create a footer with a Paragraph
+ XWPFFooter ftr = doc.createFooter(HeaderFooterType.DEFAULT);
+ p = ftr.createParagraph();
+
+ r = p.createRun();
+ r.setText("footer text");
+
+ OutputStream os = new FileOutputStream(new File("headertable.docx"));
+ doc.write(os);
+ doc.close();
+ }
+
+}
ftr.setPArray(i, paragraphs[i].getCTP());
}
} else {
- CTP p = ftr.addNewP();
- CTBody body = doc.getDocument().getBody();
- if (body.sizeOfPArray() > 0) {
- CTP p0 = body.getPArray(0);
- if (p0.isSetRsidR()) {
- byte[] rsidr = p0.getRsidR();
- byte[] rsidrdefault = p0.getRsidRDefault();
- p.setRsidP(rsidr);
- p.setRsidRDefault(rsidrdefault);
- }
- }
- CTPPr pPr = p.addNewPPr();
- pPr.addNewPStyle().setVal(pStyle);
+// CTP p = ftr.addNewP();
+// CTBody body = doc.getDocument().getBody();
+// if (body.sizeOfPArray() > 0) {
+// CTP p0 = body.getPArray(0);
+// if (p0.isSetRsidR()) {
+// byte[] rsidr = p0.getRsidR();
+// byte[] rsidrdefault = p0.getRsidRDefault();
+// p.setRsidP(rsidr);
+// p.setRsidRDefault(rsidrdefault);
+// }
+// }
+// CTPPr pPr = p.addNewPPr();
+// pPr.addNewPStyle().setVal(pStyle);
}
return ftr;
}
* Parent of XWPF headers and footers
*/
public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBody {
- List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>(1);
- List<XWPFTable> tables = new ArrayList<XWPFTable>(1);
+ List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
+ List<XWPFTable> tables = new ArrayList<XWPFTable>();
List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
- List<IBodyElement> bodyElements = new ArrayList<IBodyElement>(1);
+ List<IBodyElement> bodyElements = new ArrayList<IBodyElement>();
CTHdrFtr headerFooter;
XWPFDocument document;
/**
* Adds a new paragraph at the end of the header or footer
+ *
+ * @return new {@link XWPFParagraph} object
*/
public XWPFParagraph createParagraph() {
XWPFParagraph paragraph = new XWPFParagraph(headerFooter.addNewP(), this);
paragraphs.add(paragraph);
+ bodyElements.add(paragraph);
return paragraph;
}
+ /**
+ * Adds a new table at the end of the header or footer
+ *
+ * @param rows - number of rows in the table
+ * @param cols - number of columns in the table
+ * @return new {@link XWPFTable} object
+ */
+ public XWPFTable createTable(int rows, int cols) {
+ XWPFTable table = new XWPFTable(headerFooter.addNewTbl(), this, rows, cols);
+ tables.add(table);
+ bodyElements.add(table);
+ return table;
+ }
+
+ /**
+ * Removes a specific paragraph from this header / footer
+ *
+ * @param paragraph - {@link XWPFParagraph} object to remove
+ */
+ public void removeParagraph(XWPFParagraph paragraph) {
+ if (paragraphs.contains(paragraph)) {
+ CTP ctP = paragraph.getCTP();
+ XmlCursor c = ctP.newCursor();
+ c.removeXml();
+ c.dispose();
+ paragraphs.remove(paragraph);
+ bodyElements.remove(paragraph);
+ }
+ }
+
+ /**
+ * Removes a specific table from this header / footer
+ *
+ * @param table - {@link XWPFTable} object to remove
+ */
+ public void removeTable(XWPFTable table) {
+ if (tables.contains(table)) {
+ CTTbl ctTbl = table.getCTTbl();
+ XmlCursor c = ctTbl.newCursor();
+ c.removeXml();
+ c.dispose();
+ tables.remove(table);
+ bodyElements.remove(table);
+ }
+ }
+
+ /**
+ * Clears all paragraphs and tables from this header / footer
+ */
+ public void clearHeaderFooter() {
+ XmlCursor c = headerFooter.newCursor();
+ c.removeXmlContents();
+ c.dispose();
+ paragraphs.clear();
+ tables.clear();
+ bodyElements.clear();
+ CTP ctp = CTP.Factory.newInstance();
+ }
+
/**
* add a new paragraph at position of the cursor
*
public POIXMLDocumentPart getPart() {
return this;
}
+
+ @Override
+ protected void prepareForCommit() {
+ // must contain at least an empty paragraph
+ if (bodyElements.size() == 0) {
+ createParagraph();
+ }
+
+ // Cells must contain at least an empty paragraph
+ for (XWPFTable tbl : tables) {
+ for (XWPFTableRow row : tbl.tableRows) {
+ for (XWPFTableCell cell : row.getTableCells()) {
+ if (cell.getBodyElements().size() == 0) {
+ cell.addParagraph();
+ }
+ }
+ }
+ }
+ super.prepareForCommit();
+
+ }
}
package org.apache.poi.xwpf.usermodel;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
import java.io.IOException;
-import junit.framework.TestCase;
import org.apache.poi.xwpf.XWPFTestDataSamples;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
+import org.junit.Test;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
-public final class TestXWPFHeader extends TestCase {
+public final class TestXWPFHeader {
+
+ @Test
public void testSimpleHeader() throws IOException {
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerFooter.docx");
assertNotNull(footer);
}
+ @Test
public void testImageInHeader() throws IOException {
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("headerPic.docx");
assertEquals(1, header.getRelations().size());
}
+ @Test
public void testSetHeader() throws IOException {
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");
// no header is set (yet)
assertNull(policy.getDefaultHeader());
assertNull(policy.getFirstPageHeader());
assertNull(policy.getDefaultFooter());
+ assertNull(policy.getFirstPageFooter());
CTP ctP1 = CTP.Factory.newInstance();
CTR ctR1 = ctP1.addNewR();
XWPFHeader headerD = policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT, pars);
XWPFHeader headerF = policy.createHeader(XWPFHeaderFooterPolicy.FIRST);
// Set a default footer and capture the returned XWPFFooter object.
- XWPFFooter footer = policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, pars2);
+ XWPFFooter footerD = policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, pars2);
+ XWPFFooter footerF = policy.createFooter(XWPFHeaderFooterPolicy.FIRST);
// Ensure the headers and footer were set correctly....
assertNotNull(policy.getDefaultHeader());
assertNotNull(policy.getFirstPageHeader());
assertNotNull(policy.getDefaultFooter());
+ assertNotNull(policy.getFirstPageFooter());
// ....and that the footer object captured above contains two
// paragraphs of text.
- assertEquals(2, footer.getParagraphs().size());
+ assertEquals(2, footerD.getParagraphs().size());
+ assertEquals(0, footerF.getParagraphs().size());
// Check the header created with the paragraph got them, and the one
- // created without got an empty one
+ // created without got none
assertEquals(1, headerD.getParagraphs().size());
- assertEquals(1, headerF.getParagraphs().size());
-
assertEquals(tText, headerD.getParagraphs().get(0).getText());
- assertEquals("", headerF.getParagraphs().get(0).getText());
+
+ assertEquals(0, headerF.getParagraphs().size());
// As an additional check, recover the defauls footer and
// make sure that it contains two paragraphs of text and that
// both do hold what is expected.
- footer = policy.getDefaultFooter();
- XWPFParagraph[] paras = footer.getParagraphs().toArray(new XWPFParagraph[0]);
+ footerD = policy.getDefaultFooter();
+ XWPFParagraph[] paras = footerD.getParagraphs().toArray(new XWPFParagraph[0]);
assertEquals(2, paras.length);
assertEquals("First paragraph for the footer", paras[0].getText());
// Add some text to the empty header
String fText1 = "New Text!";
- headerF.getParagraphs().get(0).insertNewRun(0).setText(fText1);
- // TODO Add another paragraph and check
-
+ String fText2 = "More Text!";
+ headerF.createParagraph().insertNewRun(0).setText(fText1);
+ headerF.createParagraph().insertNewRun(0).setText(fText2);
+// headerF.getParagraphs().get(0).insertNewRun(0).setText(fText1);
+
// Check it
assertEquals(tText, headerD.getParagraphs().get(0).getText());
assertEquals(fText1, headerF.getParagraphs().get(0).getText());
+ assertEquals(fText2, headerF.getParagraphs().get(1).getText());
// Save, re-open, ensure it's all still there
assertNotNull(policy.getFirstPageHeader());
assertNull(policy.getEvenPageHeader());
assertNotNull(policy.getDefaultFooter());
- assertNull(policy.getFirstPageFooter());
+ assertNotNull(policy.getFirstPageFooter());
assertNull(policy.getEvenPageFooter());
// Check the new headers still have their text
headerF = policy.getFirstPageHeader();
assertEquals(tText, headerD.getParagraphs().get(0).getText());
assertEquals(fText1, headerF.getParagraphs().get(0).getText());
+ assertEquals(fText2, headerF.getParagraphs().get(1).getText());
// Check the new footers have their new text too
- footer = policy.getDefaultFooter();
- paras = footer.getParagraphs().toArray(new XWPFParagraph[0]);
+ footerD = policy.getDefaultFooter();
+ paras = footerD.getParagraphs().toArray(new XWPFParagraph[0]);
+ footerF = policy.getFirstPageFooter();
assertEquals(2, paras.length);
assertEquals("First paragraph for the footer", paras[0].getText());
assertEquals("Second paragraph for the footer", paras[1].getText());
+ assertEquals(1, footerF.getParagraphs().size());
}
+ @Test
public void testSetWatermark() throws IOException {
XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");
assertNotNull(policy.getEvenPageHeader());
}
+ @Test
public void testAddPictureData() {
// TODO
}
+ @Test
public void testGetAllPictures() {
// TODO
}
+ @Test
public void testGetAllPackagePictures() {
// TODO
}
+ @Test
public void testGetPictureDataById() {
// TODO
}
// Add a default header
policy = doc.createHeaderFooterPolicy();
XWPFHeader header = policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);
- header.getParagraphs().get(0).createRun().setText("Hello, Header World!");
+ header.createParagraph().createRun().setText("Hello, Header World!");
header.createParagraph().createRun().setText("Paragraph 2");
assertEquals(0, header.getAllPictures().size());
assertEquals(2, header.getParagraphs().size());