Skip to content

Commit

Permalink
POI Github 114
Browse files Browse the repository at this point in the history
apache/poi#114
Enhancement to XWPFFootnote and related APIs
  • Loading branch information
tonyqus committed Apr 30, 2022
1 parent dfbfb09 commit a534937
Show file tree
Hide file tree
Showing 8 changed files with 383 additions and 17 deletions.
17 changes: 14 additions & 3 deletions OpenXmlFormats/Wordprocessing/HdrFtr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,17 @@ public CT_FtnEdn AddNewFootnote()
footnoteField.Add(f);
return f;
}
public void RemoveFootnote(int pos)
{
this.footnoteField.RemoveAt(pos);
}
public int SizeOfFootnoteArray
{
get
{
return this.footnoteField.Count;
}
}
}


Expand All @@ -849,7 +860,7 @@ public class CT_FtnEdn

private bool typeFieldSpecified;

private string idField = string.Empty;
private int idField = -1;

public static CT_FtnEdn Parse(XmlNode node, XmlNamespaceManager namespaceManager)
{
Expand All @@ -858,7 +869,7 @@ public static CT_FtnEdn Parse(XmlNode node, XmlNamespaceManager namespaceManager
CT_FtnEdn ctObj = new CT_FtnEdn();
if (node.Attributes["w:type"] != null)
ctObj.type = (ST_FtnEdn)Enum.Parse(typeof(ST_FtnEdn), node.Attributes["w:type"].Value);
ctObj.id = XmlHelper.ReadString(node.Attributes["w:id"]);
ctObj.id = XmlHelper.ReadInt(node.Attributes["w:id"]);

foreach (XmlNode childNode in node.ChildNodes)
{
Expand Down Expand Up @@ -1175,7 +1186,7 @@ public bool typeSpecified
}

[XmlAttribute(Form = XmlSchemaForm.Qualified, DataType = "integer", Namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main")]
public string id
public int id
{
get
{
Expand Down
28 changes: 25 additions & 3 deletions OpenXmlFormats/Wordprocessing/Run.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public class CT_R
{

private CT_RPr rPrField;

private ArrayList itemsField;

private List<RunItemsChoiceType> itemsElementNameField;
Expand Down Expand Up @@ -178,6 +177,23 @@ public CT_RPr AddNewRPr()
return this.rPrField;
}


public CT_Empty AddNewFootnoteRef()
{
return AddNewObject<CT_Empty>(RunItemsChoiceType.footnoteRef);
}
public IList<CT_Empty> GetFootnoteRefList()
{
return GetObjectList<CT_Empty>(RunItemsChoiceType.footnoteRef);
}
public CT_Empty GetFootnoteRefArray(int pos)
{
return GetObjectArray<CT_Empty>(pos, RunItemsChoiceType.footnoteRef);
}
public CT_FtnEdnRef AddNewFootnoteReference()
{
return AddNewObject<CT_FtnEdnRef>(RunItemsChoiceType.footnoteReference);
}
public CT_Empty AddNewTab()
{
return AddNewObject<CT_Empty>(RunItemsChoiceType.tab);
Expand Down Expand Up @@ -390,7 +406,9 @@ public static CT_R Parse(XmlNode node, XmlNamespaceManager namespaceManager)
foreach (XmlNode childNode in node.ChildNodes)
{
if (childNode.LocalName == "rPr")
{
ctObj.rPr = CT_RPr.Parse(childNode, namespaceManager);
}
else if (childNode.LocalName == "instrText")
{
ctObj.Items.Add(CT_Text.Parse(childNode, namespaceManager));
Expand Down Expand Up @@ -568,9 +586,8 @@ internal void Write(StreamWriter sw, string nodeName)
sw.Write(">");
if (this.rPr != null)
this.rPr.Write(sw, "rPr");
int i = 0;


int i = 0;
foreach (object o in this.Items)
{
if ((o is CT_Text) && this.ItemsElementName[i] == RunItemsChoiceType.instrText)
Expand Down Expand Up @@ -656,6 +673,11 @@ public IList<CT_Empty> GetTabList()
{
return GetObjectList<CT_Empty>(RunItemsChoiceType.tab);
}

public IList<CT_FtnEdnRef> GetFootnoteReferenceList()
{
return GetObjectList<CT_FtnEdnRef>(RunItemsChoiceType.footnoteReference);
}
}


Expand Down
37 changes: 35 additions & 2 deletions ooxml/XWPF/Usermodel/XWPFDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ private void InitFootnotes()
EndnotesDocument endnotesDocument = EndnotesDocument.Parse(xmldoc, NamespaceManager);
foreach (CT_FtnEdn ctFtnEdn in endnotesDocument.Endnotes.endnote)
{
endnotes.Add(Int32.Parse(ctFtnEdn.id), new XWPFFootnote(this, ctFtnEdn));
endnotes.Add(ctFtnEdn.id, new XWPFFootnote(this, ctFtnEdn));
}
}
}
Expand Down Expand Up @@ -966,10 +966,43 @@ public XWPFFootnote AddFootnote(CT_FtnEdn note)
public XWPFFootnote AddEndnote(CT_FtnEdn note)
{
XWPFFootnote endnote = new XWPFFootnote(this, note);
endnotes.Add(int.Parse(note.id), endnote);
endnotes.Add(note.id, endnote);
return endnote;
}

/// <summary>
/// Create a new footnote and add it to the document.
/// </summary>
/// <remarks>
/// The new note will have one paragraph with the style "FootnoteText"
/// and one run containing the required footnote reference with the
/// style "FootnoteReference".
/// </remarks>
/// <returns>New XWPFFootnote.</returns>
public XWPFFootnote CreateFootnote()
{
XWPFFootnotes footnotes = this.CreateFootnotes();

XWPFFootnote footnote = footnotes.CreateFootnote();
return footnote;
}
/// <summary>
/// Remove the specified footnote if present.
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
public bool RemoveFootnote(int pos)
{
if (null != footnotes)
{
return footnotes.RemoveFootnote(pos);
}
else
{
return false;
}
}

/**
* remove a BodyElement from bodyElements array list
* @param pos
Expand Down
103 changes: 103 additions & 0 deletions ooxml/XWPF/Usermodel/XWPFFootnote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,110 @@ public POIXMLDocumentPart Owner
return footnotes;
}
}
public int Id
{
get
{
return this.ctFtnEdn.id;
}
}
public List<XWPFParagraph> GetParagraphs()
{
return paragraphs;
}
/**
* 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()[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.
* <p>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)}.
* </p>
* <p>The first run of the first paragraph in a footnote should
* contain a {@link CTFtnEdnRef} object.</p>
*
* @param p The {@link XWPFParagraph} to ensure
*/
public void EnsureFootnoteRef(XWPFParagraph p)
{

XWPFRun r = null;
if (p.Runs.Count > 0)
{
r = p.Runs[0];
}
if (r == null)
{
r = p.CreateRun();
}
CT_R ctr = r.GetCTR();
bool foundRef = false;
foreach (CT_FtnEdnRef reference in ctr.GetFootnoteReferenceList())
{
if (Id.ToString().Equals(reference.id))
{
foundRef = true;
break;
}
}
if (!foundRef)
{
ctr.AddNewRPr().AddNewRStyle().val="FootnoteReference";
ctr.AddNewFootnoteRef();
}
}

/**
* Appends a new {@link XWPFTable} to this footnote
*
* @return The new {@link XWPFTable}
*/
public XWPFTable CreateTable()
{
XWPFTable table = new XWPFTable(ctFtnEdn.AddNewTbl(), this);
if (bodyElements.Count == 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
*/
public XWPFTable CreateTable(int rows, int cols)
{
XWPFTable table = new XWPFTable(ctFtnEdn.AddNewTbl(), this, rows, cols);
bodyElements.Add(table);
tables.Add(table);
return table;
}
/**
*
* @param cursor
Expand Down
41 changes: 40 additions & 1 deletion ooxml/XWPF/Usermodel/XWPFFootnotes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public List<XWPFFootnote> GetFootnotesList()
public XWPFFootnote GetFootnoteById(int id)
{
foreach(XWPFFootnote note in listFootnote) {
if(note.GetCTFtnEdn().id == id.ToString())
if(note.GetCTFtnEdn().id == id)
return note;
}
return null;
Expand Down Expand Up @@ -167,7 +167,44 @@ public void SetXWPFDocument(XWPFDocument doc)
{
document = doc;
}
/// <summary>
/// Create a new footnote and add it to the document.
/// </summary>
/// <remarks>
/// The new note will have one paragraph with the style "FootnoteText"
/// and one run containing the required footnote reference with the
/// style "FootnoteReference".
/// </remarks>
/// <returns>New XWPFFootnote</returns>
public XWPFFootnote CreateFootnote()
{
CT_FtnEdn newNote = new CT_FtnEdn();
newNote.type = ST_FtnEdn.normal;

XWPFFootnote footnote = AddFootnote(newNote);
int id = ctFootnotes.SizeOfFootnoteArray;
footnote.GetCTFtnEdn().id = id;
return footnote;
}

/// <summary>
/// Remove the specified footnote if present.
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
public bool RemoveFootnote(int pos)
{
if (ctFootnotes.SizeOfFootnoteArray >= pos - 1)
{
ctFootnotes.RemoveFootnote(pos);
listFootnote.RemoveAt(pos);
return true;
}
else
{
return false;
}
}
/**
* @see NPOI.XWPF.UserModel.IBody#getPart()
*/
Expand All @@ -182,6 +219,8 @@ public XWPFDocument GetXWPFDocument()
return (XWPFDocument)GetParent();
}
}


}//end class


Expand Down
13 changes: 13 additions & 0 deletions ooxml/XWPF/Usermodel/XWPFParagraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1647,6 +1647,19 @@ public XWPFHyperlinkRun CreateHyperlinkRun(string rId)
iRuns.Add(xwpfRun);
return xwpfRun;
}
/// <summary>
/// Add a new run with a reference to the specified footnote. The footnote reference run will have the style name "FootnoteReference".
/// </summary>
/// <param name="footnote">Footnote to which to add a reference.</param>
public void AddFootnoteReference(XWPFFootnote footnote)
{
XWPFRun run = CreateRun();
CT_R ctRun = run.GetCTR();
var rstyle=ctRun.AddNewRPr().AddNewRStyle();
rstyle.val="FootnoteReference";
var footnoteRef = ctRun.AddNewFootnoteReference();
footnoteRef.id= footnote.Id.ToString();
}
}

}
Loading

0 comments on commit a534937

Please sign in to comment.