diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFFootnoteEndnote.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFFootnoteEndnote.java new file mode 100644 index 0000000000..7c30725ee9 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFFootnoteEndnote.java @@ -0,0 +1,499 @@ +package org.apache.poi.xwpf.usermodel; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.poi.ooxml.POIXMLDocumentPart; +import org.apache.poi.util.Internal; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdnRef; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; + +/** + * Base class for both bottom-of-the-page footnotes {@link XWPFFootnote} and end + * notes {@link XWPFEndnote}). + *
The only significant difference between footnotes and + * end notes is which part they go on. Footnotes are managed by the Footnotes part + * {@link XWPFFootnotes} and end notes are managed by the Endnotes part {@link XWPFEndnotes}.
+ * @since 4.0.0 + */ +public abstract class AbstractXWPFFootnoteEndnote implements IterableUse {@link XWPFDocument#createFootnote()} to create new footnotes.
+ * @param footnote The CTFtnEdn object that will underly the footnote. + */ + public void setCTFtnEdn(CTFtnEdn footnote) { + ctFtnEdn = footnote; + } + + /** + * Gets the {@link XWPFTable} at the specified position from the footnote's table array. + * @param pos in table array + * @return The {@link XWPFTable} at position pos, or null if there is no table at position pos. + * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int) + */ + public XWPFTable getTableArray(int pos) { + if (pos >= 0 && pos < tables.size()) { + return tables.get(pos); + } + return null; + } + + /** + * Inserts an existing {@link XWPFTable) into the arrays bodyElements and tables. + * + * @param pos Position, in the bodyElements array, to insert the table + * @param table {@link XWPFTable) to be inserted + * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int pos, XWPFTable table) + */ + public void insertTable(int pos, XWPFTable table) { + bodyElements.add(pos, table); + int i = 0; + for (CTTbl tbl : ctFtnEdn.getTblList()) { + if (tbl == table.getCTTbl()) { + break; + } + i++; + } + tables.add(i, table); + + } + + /** + * if there is a corresponding {@link XWPFTable} of the parameter + * ctTable in the tableList of this header + * the method will return this table, or null if there is no + * corresponding {@link XWPFTable}. + * + * @param ctTable + * @see org.apache.poi.xwpf.usermodel.IBody#getTable(CTTbl ctTable) + */ + public XWPFTable getTable(CTTbl ctTable) { + for (XWPFTable table : tables) { + if (table == null) + return null; + if (table.getCTTbl().equals(ctTable)) + return table; + } + return null; + } + + /** + * if there is a corresponding {@link XWPFParagraph} of the parameter p in the paragraphList of this header or footer + * the method will return that paragraph, otherwise the method will return null. + * + * @param p The CTP paragraph to find the corresponding {@link XWPFParagraph} for. + * @return The {@link XWPFParagraph} that corresponds to the CTP paragraph in the paragraph + * list of this footnote or null if no paragraph is found. + * @see org.apache.poi.xwpf.usermodel.IBody#getParagraph(CTP p) + */ + public XWPFParagraph getParagraph(CTP p) { + for (XWPFParagraph paragraph : paragraphs) { + if (paragraph.getCTP().equals(p)) + return paragraph; + } + return null; + } + + /** + * Returns the {@link XWPFParagraph} at position pos in footnote's paragraph array. + * @param pos Array position of the paragraph to get. + * @return the {@link XWPFParagraph} at position pos, or null if there is no paragraph at that position. + * + * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int pos) + */ + public XWPFParagraph getParagraphArray(int pos) { + if(pos >=0 && pos < paragraphs.size()) { + return paragraphs.get(pos); + } + return null; + } + + /** + * get the {@link XWPFTableCell} that belongs to the CTTc cell. + * + * @param cell + * @return {@link XWPFTableCell} that corresponds to the CTTc cell, if there is one, otherwise null. + * @see org.apache.poi.xwpf.usermodel.IBody#getTableCell(CTTc cell) + */ + public XWPFTableCell getTableCell(CTTc cell) { + XmlCursor cursor = cell.newCursor(); + cursor.toParent(); + XmlObject o = cursor.getObject(); + if (!(o instanceof CTRow)) { + return null; + } + CTRow row = (CTRow) o; + cursor.toParent(); + o = cursor.getObject(); + cursor.dispose(); + if (!(o instanceof CTTbl)) { + return null; + } + CTTbl tbl = (CTTbl) o; + XWPFTable table = getTable(tbl); + if (table == null) { + return null; + } + XWPFTableRow tableRow = table.getRow(row); + if(tableRow == null){ + return null; + } + return tableRow.getTableCell(cell); + } + + /** + * Verifies that cursor is on the right position. + * + * @param cursor + * @return true if the cursor is within a CTFtnEdn element. + */ + private boolean isCursorInFtn(XmlCursor cursor) { + XmlCursor verify = cursor.newCursor(); + verify.toParent(); + if (verify.getObject() == this.ctFtnEdn) { + return true; + } + return false; + } + + /** + * The owning object for this footnote + * + * @return The {@link XWPFFootnotes} object that contains this footnote. + */ + public POIXMLDocumentPart getOwner() { + return footnotes; + } + + /** + * Insert a table constructed from OOXML table markup. + * @param cursor + * @return the inserted {@link XWPFTable} + * @see org.apache.poi.xwpf.usermodel.IBody#insertNewTbl(XmlCursor cursor) + */ + public XWPFTable insertNewTbl(XmlCursor cursor) { + if (isCursorInFtn(cursor)) { + String uri = CTTbl.type.getName().getNamespaceURI(); + String localPart = "tbl"; + cursor.beginElement(localPart, uri); + cursor.toParent(); + CTTbl t = (CTTbl) cursor.getObject(); + XWPFTable newT = new XWPFTable(t, this); + cursor.removeXmlContents(); + XmlObject o = null; + while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) { + o = cursor.getObject(); + } + if (!(o instanceof CTTbl)) { + tables.add(0, newT); + } else { + int pos = tables.indexOf(getTable((CTTbl) o)) + 1; + tables.add(pos, newT); + } + int i = 0; + cursor = t.newCursor(); + while (cursor.toPrevSibling()) { + o = cursor.getObject(); + if (o instanceof CTP || o instanceof CTTbl) + i++; + } + bodyElements.add(i, newT); + XmlCursor c2 = t.newCursor(); + cursor.toCursor(c2); + cursor.toEndToken(); + c2.dispose(); + return newT; + } + return null; + } + + /** + * Add a new {@link XWPFParagraph} at position of the cursor. + * + * @param cursor + * @return The inserted {@link XWPFParagraph} + * @see org.apache.poi.xwpf.usermodel.IBody#insertNewParagraph(XmlCursor cursor) + */ + public XWPFParagraph insertNewParagraph(final XmlCursor cursor) { + if (isCursorInFtn(cursor)) { + String uri = CTP.type.getName().getNamespaceURI(); + String localPart = "p"; + cursor.beginElement(localPart, uri); + cursor.toParent(); + CTP p = (CTP) cursor.getObject(); + XWPFParagraph newP = new XWPFParagraph(p, this); + XmlObject o = null; + while (!(o instanceof CTP) && (cursor.toPrevSibling())) { + o = cursor.getObject(); + } + if ((!(o instanceof CTP)) || o == p) { + paragraphs.add(0, newP); + } else { + int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1; + paragraphs.add(pos, newP); + } + int i = 0; + XmlCursor p2 = p.newCursor(); + cursor.toCursor(p2); + p2.dispose(); + while (cursor.toPrevSibling()) { + o = cursor.getObject(); + if (o instanceof CTP || o instanceof CTTbl) + i++; + } + bodyElements.add(i, newP); + p2 = p.newCursor(); + cursor.toCursor(p2); + cursor.toEndToken(); + p2.dispose(); + return newP; + } + return null; + } + + /** + * Add a new {@link XWPFTable} to the end of the footnote. + * + * @param table CTTbl object from which to construct the {@link XWPFTable} + * @return The added {@link XWPFTable} + */ + public XWPFTable addNewTbl(CTTbl table) { + CTTbl newTable = ctFtnEdn.addNewTbl(); + newTable.set(table); + XWPFTable xTable = new XWPFTable(newTable, this); + tables.add(xTable); + return xTable; + } + + /** + * Add a new {@link XWPFParagraph} to the end of the footnote. + * + * @param paragraph CTP paragraph from which to construct the {@link XWPFParagraph} + * @return The added {@link XWPFParagraph} + */ + public XWPFParagraph addNewParagraph(CTP paragraph) { + CTP newPara = ctFtnEdn.addNewP(); + newPara.set(paragraph); + XWPFParagraph xPara = new XWPFParagraph(newPara, this); + paragraphs.add(xPara); + return xPara; + } + + /** + * Get the {@link XWPFDocument} the footnote is part of. + * @see org.apache.poi.xwpf.usermodel.IBody#getXWPFDocument() + */ + public XWPFDocument getXWPFDocument() { + return document; + } + + /** + * Get the Part to which the footnote belongs, which you need for adding relationships to other parts + * @return {@link POIXMLDocumentPart} that contains the footnote. + * + * @see org.apache.poi.xwpf.usermodel.IBody#getPart() + */ + public POIXMLDocumentPart getPart() { + return footnotes; + } + + /** + * Get the part type {@link BodyType} of the footnote. + * @return The {@link BodyType} value. + * + * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() + */ + public BodyType getPartType() { + return BodyType.FOOTNOTE; + } + + /** + * Get the ID of the footnote. + *Footnote IDs are unique across all bottom-of-the-page and + * end note footnotes.
+ * + * @return Footnote ID + * @since 4.0.0 + */ + public BigInteger getId() { + return this.ctFtnEdn.getId(); + } + + /** + * Appends a new {@link XWPFParagraph} to this footnote. + * + * @return The new {@link XWPFParagraph} + * @since 4.0.0 + */ + public XWPFParagraph createParagraph() { + XWPFParagraph p = new XWPFParagraph(this.ctFtnEdn.addNewP(), this); + paragraphs.add(p); + bodyElements.add(p); + + // If the paragraph is the first paragraph in the footnote, + // ensure that it has a footnote reference run. + + if (p.equals(getParagraphs().get(0))) { + ensureFootnoteRef(p); + } + return p; + } + + /** + * Ensure that the specified paragraph has a reference marker for this + * footnote by adding a footnote reference if one is not found. + *This method is for the first paragraph in the footnote, not + * paragraphs that will refer to the footnote. For references to + * the footnote, use {@link XWPFParagraph#addFootnoteReference(XWPFFootnote)}. + *
+ *The first run of the first paragraph in a footnote should + * contain a {@link CTFtnEdnRef} object.
+ * + * @param p The {@link XWPFParagraph} to ensure + * @since 4.0.0 + */ + public abstract void ensureFootnoteRef(XWPFParagraph p); + + /** + * Appends a new {@link XWPFTable} to this footnote + * + * @return The new {@link XWPFTable} + * @since 4.0.0 + */ + public XWPFTable createTable() { + XWPFTable table = new XWPFTable(ctFtnEdn.addNewTbl(), this); + if (bodyElements.size() == 0) { + XWPFParagraph p = createParagraph(); + ensureFootnoteRef(p); + } + bodyElements.add(table); + tables.add(table); + return table; + } + + /** + * Appends a new {@link XWPFTable} to this footnote + * @param rows Number of rows to initialize the table with + * @param cols Number of columns to initialize the table with + * @return the new {@link XWPFTable} with the specified number of rows and columns + * @since 4.0.0 + */ + public XWPFTable createTable(int rows, int cols) { + XWPFTable table = new XWPFTable(ctFtnEdn.addNewTbl(), this, rows, cols); + bodyElements.add(table); + tables.add(table); + return table; + } + +} \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFFootnotesEndnotes.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFFootnotesEndnotes.java new file mode 100644 index 0000000000..a3560c5318 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/AbstractXWPFFootnotesEndnotes.java @@ -0,0 +1,74 @@ +package org.apache.poi.xwpf.usermodel; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.ooxml.POIXMLDocumentPart; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.PackagePart; + +/** + * Base class for the Footnotes and Endnotes part implementations. + * @since 4.0.0 + */ +public abstract class AbstractXWPFFootnotesEndnotes extends POIXMLDocumentPart { + + protected XWPFDocument document; + protected ListFootnotes and endnotes are managed in separate parts but + * represent a single namespace of IDs.
+ */ +public class FootnoteEndnoteIdManager { + + private XWPFDocument document; + + public FootnoteEndnoteIdManager(XWPFDocument document) { + this.document = document; + } + + /** + * Gets the next ID number. + * + * @return ID number to use. + */ + public BigInteger nextId() { + + ListThe new note will have one paragraph with the style "FootnoteText"
- * and one run containing the required footnote reference with the
- * style "FootnoteReference".
+ * Create a new footnote and add it to the document.
*
* @return New XWPFFootnote.
+ * @since 4.0.0
*/
public XWPFFootnote createFootnote() {
XWPFFootnotes footnotes = this.createFootnotes();
@@ -1675,8 +1689,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
/**
* Remove the specified footnote if present.
*
- * @param pos
+ * @param pos Array position of the footnote to be removed.
* @return True if the footnote was removed.
+ * @since 4.0.0
*/
public boolean removeFootnote(int pos) {
if (null != footnotes) {
@@ -1685,4 +1700,62 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
return false;
}
}
+
+ /**
+ * Create a new end note and add it to the document.
+ *
+ * @return New {@link XWPFEndnote}.
+ * @since 4.0.0
+ */
+ public XWPFEndnote createEndnote() {
+ XWPFEndnotes endnotes = this.createEndnotes();
+
+ XWPFEndnote endnote = endnotes.createEndnote();
+ return endnote;
+
+ }
+
+ public XWPFEndnotes createEndnotes() {
+ if (endnotes == null) {
+ EndnotesDocument endnotesDoc = EndnotesDocument.Factory.newInstance();
+
+ XWPFRelation relation = XWPFRelation.ENDNOTE;
+ int i = getRelationIndex(relation);
+
+ XWPFEndnotes wrapper = (XWPFEndnotes) createRelationship(relation, XWPFFactory.getInstance(), i);
+ wrapper.setEndnotes(endnotesDoc.addNewEndnotes());
+ wrapper.setIdManager(footnoteIdManager);
+ endnotes = wrapper;
+ }
+
+ return endnotes;
+
+ }
+
+ /**
+ * Gets the list of end notes for the document.
+ *
+ * @return List, possibly empty, of {@link XWPFEndnote}s.
+ */
+ public List End notes are collected at the end of a document or section rather than
+ * at the bottom of a page. Create a new footnote using {@link XWPFDocument#createEndnote()} or
+ * {@link XWPFEndnotes#createFootnote()}. The first body element of a footnote should (or possibly must) be a paragraph
+ * with the first run containing a CTFtnEdnRef object. The {@link XWPFFootnote#createParagraph()}
+ * and {@link XWPFFootnote#createTable()} methods do this for you. Footnotes have IDs that are unique across all footnotes in the document. You use
+ * the footnote ID to create a reference to a footnote from within a paragraph. To create a reference to a footnote within a paragraph you create a run
+ * with a CTFtnEdnRef that specifies the ID of the target paragraph.
+ * The {@link XWPFParagraph#addFootnoteReference(AbstractXWPFFootnoteEndnote)}
+ * method does this for you. This method is for the first paragraph in the footnote, not
+ * paragraphs that will refer to the footnote. For references to
+ * the footnote, use {@link XWPFParagraph#addFootnoteReference(AbstractXWPFFootnoteEndnote))}.
+ * The first run of the first paragraph in a footnote should
+ * contain a {@link CTFtnEdnRef} object.
To create a reference to a footnote within a paragraph you create a run * with a CTFtnEdnRef that specifies the ID of the target paragraph. - * The {@link XWPFParagraph#addFootnoteReference(XWPFFootnote)} + * The {@link XWPFParagraph#addFootnoteReference(AbstractXWPFFootnoteEndnote)} * method does this for you.
*/ -public class XWPFFootnote implements IterableUse {@link XWPFDocument#createFootnote()} to create new footnotes.
- * @param footnote The CTFtnEdn object that will underly the footnote. - */ - public void setCTFtnEdn(CTFtnEdn footnote) { - ctFtnEdn = footnote; - } - - /** - * Gets the {@link XWPFTable} at the specified position from the footnote's table array. - * @param pos in table array - * @return The {@link XWPFTable} at position pos, or null if there is no table at position pos. - * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int) - */ - public XWPFTable getTableArray(int pos) { - if (pos >= 0 && pos < tables.size()) { - return tables.get(pos); - } - return null; - } - - /** - * Inserts an existing {@link XWPFTable) into the arrays bodyElements and tables. - * - * @param pos Position, in the bodyElements array, to insert the table - * @param table {@link XWPFTable) to be inserted - * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int pos, XWPFTable table) - */ - public void insertTable(int pos, XWPFTable table) { - bodyElements.add(pos, table); - int i = 0; - for (CTTbl tbl : ctFtnEdn.getTblList()) { - if (tbl == table.getCTTbl()) { - break; - } - i++; - } - tables.add(i, table); - - } - - /** - * if there is a corresponding {@link XWPFTable} of the parameter - * ctTable in the tableList of this header - * the method will return this table, or null if there is no - * corresponding {@link XWPFTable}. - * - * @param ctTable - * @see org.apache.poi.xwpf.usermodel.IBody#getTable(CTTbl ctTable) - */ - public XWPFTable getTable(CTTbl ctTable) { - for (XWPFTable table : tables) { - if (table == null) - return null; - if (table.getCTTbl().equals(ctTable)) - return table; - } - return null; - } - - /** - * if there is a corresponding {@link XWPFParagraph} of the parameter p in the paragraphList of this header or footer - * the method will return that paragraph, otherwise the method will return null. - * - * @param p The CTP paragraph to find the corresponding {@link XWPFParagraph} for. - * @return The {@link XWPFParagraph} that corresponds to the CTP paragraph in the paragraph - * list of this footnote or null if no paragraph is found. - * @see org.apache.poi.xwpf.usermodel.IBody#getParagraph(CTP p) - */ - public XWPFParagraph getParagraph(CTP p) { - for (XWPFParagraph paragraph : paragraphs) { - if (paragraph.getCTP().equals(p)) - return paragraph; - } - return null; - } - - /** - * Returns the {@link XWPFParagraph} at position pos in footnote's paragraph array. - * @param pos Array position of the paragraph to get. - * @return the {@link XWPFParagraph} at position pos, or null if there is no paragraph at that position. - * - * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int pos) - */ - public XWPFParagraph getParagraphArray(int pos) { - if(pos >=0 && pos < paragraphs.size()) { - return paragraphs.get(pos); - } - return null; - } - - /** - * get the {@link XWPFTableCell} that belongs to the CTTc cell. - * - * @param cell - * @return {@link XWPFTableCell} that corresponds to the CTTc cell, if there is one, otherwise null. - * @see org.apache.poi.xwpf.usermodel.IBody#getTableCell(CTTc cell) - */ - public XWPFTableCell getTableCell(CTTc cell) { - XmlCursor cursor = cell.newCursor(); - cursor.toParent(); - XmlObject o = cursor.getObject(); - if (!(o instanceof CTRow)) { - return null; - } - CTRow row = (CTRow) o; - cursor.toParent(); - o = cursor.getObject(); - cursor.dispose(); - if (!(o instanceof CTTbl)) { - return null; - } - CTTbl tbl = (CTTbl) o; - XWPFTable table = getTable(tbl); - if (table == null) { - return null; - } - XWPFTableRow tableRow = table.getRow(row); - if(tableRow == null){ - return null; - } - return tableRow.getTableCell(cell); - } - - /** - * Verifies that cursor is on the right position. - * - * @param cursor - * @return true if the cursor is within a CTFtnEdn element. - */ - private boolean isCursorInFtn(XmlCursor cursor) { - XmlCursor verify = cursor.newCursor(); - verify.toParent(); - if (verify.getObject() == this.ctFtnEdn) { - return true; - } - return false; - } - - /** - * The owning object for this footnote - * - * @return The {@link XWPFFootnotes} object that contains this footnote. - */ - public POIXMLDocumentPart getOwner() { - return footnotes; - } - - /** - * Insert a table constructed from OOXML table markup. - * @param cursor - * @return the inserted {@link XWPFTable} - * @see org.apache.poi.xwpf.usermodel.IBody#insertNewTbl(XmlCursor cursor) - */ - public XWPFTable insertNewTbl(XmlCursor cursor) { - if (isCursorInFtn(cursor)) { - String uri = CTTbl.type.getName().getNamespaceURI(); - String localPart = "tbl"; - cursor.beginElement(localPart, uri); - cursor.toParent(); - CTTbl t = (CTTbl) cursor.getObject(); - XWPFTable newT = new XWPFTable(t, this); - cursor.removeXmlContents(); - XmlObject o = null; - while (!(o instanceof CTTbl) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - if (!(o instanceof CTTbl)) { - tables.add(0, newT); - } else { - int pos = tables.indexOf(getTable((CTTbl) o)) + 1; - tables.add(pos, newT); - } - int i = 0; - cursor = t.newCursor(); - while (cursor.toPrevSibling()) { - o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) - i++; - } - bodyElements.add(i, newT); - XmlCursor c2 = t.newCursor(); - cursor.toCursor(c2); - cursor.toEndToken(); - c2.dispose(); - return newT; - } - return null; - } - - /** - * Add a new {@link XWPFParagraph} at position of the cursor. - * - * @param cursor - * @return The inserted {@link XWPFParagraph} - * @see org.apache.poi.xwpf.usermodel.IBody#insertNewParagraph(XmlCursor cursor) - */ - public XWPFParagraph insertNewParagraph(final XmlCursor cursor) { - if (isCursorInFtn(cursor)) { - String uri = CTP.type.getName().getNamespaceURI(); - String localPart = "p"; - cursor.beginElement(localPart, uri); - cursor.toParent(); - CTP p = (CTP) cursor.getObject(); - XWPFParagraph newP = new XWPFParagraph(p, this); - XmlObject o = null; - while (!(o instanceof CTP) && (cursor.toPrevSibling())) { - o = cursor.getObject(); - } - if ((!(o instanceof CTP)) || o == p) { - paragraphs.add(0, newP); - } else { - int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1; - paragraphs.add(pos, newP); - } - int i = 0; - XmlCursor p2 = p.newCursor(); - cursor.toCursor(p2); - p2.dispose(); - while (cursor.toPrevSibling()) { - o = cursor.getObject(); - if (o instanceof CTP || o instanceof CTTbl) - i++; - } - bodyElements.add(i, newP); - p2 = p.newCursor(); - cursor.toCursor(p2); - cursor.toEndToken(); - p2.dispose(); - return newP; - } - return null; - } - - /** - * Add a new {@link XWPFTable} to the end of the footnote. - * - * @param table CTTbl object from which to construct the {@link XWPFTable} - * @return The added {@link XWPFTable} - */ - public XWPFTable addNewTbl(CTTbl table) { - CTTbl newTable = ctFtnEdn.addNewTbl(); - newTable.set(table); - XWPFTable xTable = new XWPFTable(newTable, this); - tables.add(xTable); - return xTable; - } - - /** - * Add a new {@link XWPFParagraph} to the end of the footnote. - * - * @param paragraph CTP paragraph from which to construct the {@link XWPFParagraph} - * @return The added {@link XWPFParagraph} - */ - public XWPFParagraph addNewParagraph(CTP paragraph) { - CTP newPara = ctFtnEdn.addNewP(); - newPara.set(paragraph); - XWPFParagraph xPara = new XWPFParagraph(newPara, this); - paragraphs.add(xPara); - return xPara; - } - - /** - * Get the {@link XWPFDocument} the footnote is part of. - * @see org.apache.poi.xwpf.usermodel.IBody#getXWPFDocument() - */ - public XWPFDocument getXWPFDocument() { - return document; - } - - /** - * Get the Part to which the footnote belongs, which you need for adding relationships to other parts - * @return {@link POIXMLDocumentPart} that contains the footnote. - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPart() - */ - public POIXMLDocumentPart getPart() { - return footnotes; - } - - /** - * Get the part type {@link BodyType} of the footnote. - * @return The {@link BodyType} value. - * - * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() - */ - public BodyType getPartType() { - return BodyType.FOOTNOTE; - } - - /** - * Get the ID of the footnote. - *Footnote IDs are unique across all bottom-of-the-page and - * end note footnotes.
- * - * @return Footnote ID - */ - public BigInteger getId() { - return this.ctFtnEdn.getId(); - } - - /** - * Appends a new {@link XWPFParagraph} to this footnote. - * - * @return The new {@link XWPFParagraph} - */ - public XWPFParagraph createParagraph() { - XWPFParagraph p = new XWPFParagraph(this.ctFtnEdn.addNewP(), this); - paragraphs.add(p); - bodyElements.add(p); - - // If the paragraph is the first paragraph in the footnote, - // ensure that it has a footnote reference run. - - if (p.equals(getParagraphs().get(0))) { - ensureFootnoteRef(p); - } - return p; - } - + /** * Ensure that the specified paragraph has a reference marker for this * footnote by adding a footnote reference if one is not found. @@ -474,7 +58,8 @@ public class XWPFFootnote implements IterableThe new note will have one paragraph with the style "FootnoteText" - * and one run containing the required footnote reference with the - * style "FootnoteReference". - *
- * @return New XWPFFootnote - */ - public XWPFFootnote createFootnote() { - CTFtnEdn newNote = CTFtnEdn.Factory.newInstance(); - newNote.setType(STFtnEdn.NORMAL); - - XWPFFootnote footnote = addFootnote(newNote); - int id = ctFootnotes.sizeOfFootnoteArray(); - footnote.getCTFtnEdn().setId(BigInteger.valueOf(id)); - return footnote; - - } - - /** - * Remove the specified footnote if present. + * Get the list of {@link XWPFFootnote} in the Footnotes part. * - * @param pos - * @return True if the footnote was removed. + * @return List, possibly empty, of footnotes. */ - public boolean removeFootnote(int pos) { - if (ctFootnotes.sizeOfFootnoteArray() >= pos - 1) { - ctFootnotes.removeFootnote(pos); - listFootnote.remove(pos); - return true; - } else { - return false; + public List