Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: Get hyperlinks from footer and footnotes #1074

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ooxml/XWPF/Usermodel/XWPFDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace NPOI.XWPF.UserModel
using System.Xml.Serialization;
using System.Diagnostics;
using NPOI.OOXML.XWPF.Util;
using System.Linq;

/**
* <p>High(ish) level class for working with .docx files.</p>
Expand Down Expand Up @@ -217,6 +218,11 @@ private void InitHyperlinks()
{
throw new POIXMLException(e);
}
hyperlinks.AddRange(footers.SelectMany(footer => footer.GetHyperlinks()));
if (footnotes != null)
{
hyperlinks.AddRange(footnotes.GetHyperlinks());
}
}

private void InitFootnotes()
Expand Down
47 changes: 45 additions & 2 deletions ooxml/XWPF/Usermodel/XWPFFooter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ namespace NPOI.XWPF.UserModel
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;

/**
* Sketch of XWPF footer class
*/
public class XWPFFooter : XWPFHeaderFooter
{
protected List<XWPFHyperlink> hyperlinks = new List<XWPFHyperlink>();
public XWPFFooter()
//: base()
{
Expand Down Expand Up @@ -68,6 +70,7 @@ public XWPFFooter(XWPFDocument doc, CT_HdrFtr hdrFtr)
tables.Add(t);
}
}

}

public XWPFFooter(POIXMLDocumentPart parent, PackagePart part)
Expand Down Expand Up @@ -112,7 +115,8 @@ internal override void OnDocumentRead()
{
base.OnDocumentRead();
FtrDocument ftrDocument = null;
try {
try
{
XmlDocument xmldoc = ConvertStreamToXml(GetPackagePart().GetInputStream());
ftrDocument = FtrDocument.Parse(xmldoc, NamespaceManager);
headerFooter = ftrDocument.Ftr;
Expand All @@ -138,9 +142,48 @@ internal override void OnDocumentRead()
bodyElements.Add(c);
}
}
} catch (Exception e) {
}
catch (Exception e)
{
throw new POIXMLException(e);
}
InitHyperlinks();
}

private void InitHyperlinks()
{
try
{
IEnumerator<PackageRelationship> relIter =
GetPackagePart().GetRelationshipsByType(XWPFRelation.HYPERLINK.Relation).GetEnumerator();
while (relIter.MoveNext())
{
PackageRelationship rel = relIter.Current;
hyperlinks.Add(new XWPFHyperlink(rel.Id, rel.TargetUri.OriginalString));
}
}
catch (InvalidDataException e)
{
throw new POIXMLException(e);
}
}

public List<XWPFHyperlink> GetHyperlinks()
{
return hyperlinks;
}

public XWPFHyperlink GetHyperlinkByID(string id)
{
IEnumerator<XWPFHyperlink> iter = hyperlinks.GetEnumerator();
while (iter.MoveNext())
{
XWPFHyperlink link = iter.Current;
if (link.Id.Equals(id))
return link;
}

return null;
}

/**
Expand Down
36 changes: 36 additions & 0 deletions ooxml/XWPF/Usermodel/XWPFFootnotes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class XWPFFootnotes : POIXMLDocumentPart
{
private List<XWPFFootnote> listFootnote = new List<XWPFFootnote>();
private CT_Footnotes ctFootnotes;
private List<XWPFHyperlink> hyperlinks = new List<XWPFHyperlink>();

protected XWPFDocument document;

Expand Down Expand Up @@ -96,8 +97,26 @@ internal override void OnDocumentRead()
listFootnote.Add(new XWPFFootnote(note, this));
}
}
InitHyperlinks();
}

private void InitHyperlinks()
{
try
{
IEnumerator<PackageRelationship> relIter =
GetPackagePart().GetRelationshipsByType(XWPFRelation.HYPERLINK.Relation).GetEnumerator();
while (relIter.MoveNext())
{
PackageRelationship rel = relIter.Current;
hyperlinks.Add(new XWPFHyperlink(rel.Id, rel.TargetUri.OriginalString));
}
}
catch (InvalidDataException e)
{
throw new POIXMLException(e);
}
}

protected internal override void Commit()
{
Expand Down Expand Up @@ -220,6 +239,23 @@ public XWPFDocument GetXWPFDocument()
}
}

public XWPFHyperlink GetHyperlinkByID(String id)
{
IEnumerator<XWPFHyperlink> iter = hyperlinks.GetEnumerator();
while (iter.MoveNext())
{
XWPFHyperlink link = iter.Current;
if (link.Id.Equals(id))
return link;
}

return null;
}

public List<XWPFHyperlink> GetHyperlinks()
{
return hyperlinks;
}

}//end class

Expand Down
50 changes: 50 additions & 0 deletions testcases/ooxml/XWPF/Model/TestXWPFDecorators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace TestCases.XWPF.Model
using NPOI.XWPF.Model;
using NPOI.XWPF.UserModel;
using NUnit.Framework;
using System.Linq;

/**
* Tests for the various XWPF decorators
Expand All @@ -30,12 +31,17 @@ public class TestXWPFDecorators
private XWPFDocument simple;
private XWPFDocument hyperlink;
private XWPFDocument comments;
private XWPFDocument footerhyperlink;
private XWPFDocument footnotehyperlink;

[SetUp]
public void SetUp()
{
simple = XWPFTestDataSamples.OpenSampleDocument("SampleDoc.docx");
hyperlink = XWPFTestDataSamples.OpenSampleDocument("TestDocument.docx");
comments = XWPFTestDataSamples.OpenSampleDocument("WordWithAttachments.docx");
footerhyperlink = XWPFTestDataSamples.OpenSampleDocument("TestHyperlinkInFooterDocument.docx");
footnotehyperlink = XWPFTestDataSamples.OpenSampleDocument("TestHyperlinkInFootnotes.docx");
}

[Test]
Expand Down Expand Up @@ -66,6 +72,50 @@ public void TestHyperlink()
Assert.AreEqual("http://poi.apache.org/", link.GetHyperlink(hyperlink).URL);
}

[Test]
public void TestHyperlinkInFooter()
{
Assert.AreEqual(1, footerhyperlink.Paragraphs.Count);

// Simple text
XWPFParagraph paragraph = footerhyperlink.Paragraphs[(0)];
Assert.AreEqual("This is a test document.", paragraph.ParagraphText);
Assert.AreEqual(2, paragraph.Runs.Count);

Assert.AreEqual(3, footerhyperlink.FooterList.Count);

Assert.AreEqual(1, footerhyperlink.GetHyperlinks().Length);

XWPFHyperlinkRun run = (XWPFHyperlinkRun)((XWPFParagraph)footerhyperlink.FooterList[2].BodyElements[0]).Runs[1];
Assert.AreEqual("http://poi.apache.org/", run.GetHyperlink(footerhyperlink).URL);

Assert.AreEqual(1, footerhyperlink.FooterList[2].GetHyperlinks().Count);

XWPFHyperlink link = footerhyperlink.GetHyperlinks().First();
Assert.AreEqual("http://poi.apache.org/", link.URL);
}

[Test]
public void TestHyperlinkInFootnotes()
{
Assert.AreEqual(1, footerhyperlink.Paragraphs.Count);

// Simple text
XWPFParagraph paragraph = footnotehyperlink.Paragraphs[(0)];
Assert.AreEqual("This is a test document.[footnoteRef:1]", paragraph.ParagraphText);
Assert.AreEqual(3, paragraph.Runs.Count);

Assert.AreEqual(3, footnotehyperlink.GetFootnotes().Count);

Assert.AreEqual(1, footnotehyperlink.GetHyperlinks().Length);

XWPFHyperlinkRun run = (XWPFHyperlinkRun)footnotehyperlink.GetFootnotes()[2].Paragraphs[0].Runs[3];
Assert.AreEqual("http://poi.apache.org/", run.GetHyperlink(footerhyperlink).URL);

XWPFHyperlink link = footnotehyperlink.GetHyperlinks().First();
Assert.AreEqual("http://poi.apache.org/", link.URL);
}

[Test]
public void TestComments()
{
Expand Down
Binary file not shown.
Binary file not shown.