I was able to add a hyperlink to a cell using System.IO.Packaging
code:
private void HyperlinkCreate(PackagePart part, XmlNamespaceManager nsm, XmlNode _cellElement, string CellAddress)
{
Uri _hyperlink = new Uri("http://www.yahoo.com");
XmlNode linkParent = _cellElement.OwnerDocument.SelectSingleNode("//d:hyperlinks", nsm);
if (linkParent == null)
{
// create the hyperlinks node
linkParent = _cellElement.OwnerDocument.CreateElement("hyperlinks", @"http://schemas.openxmlformats.org/spreadsheetml/2006/main");
XmlNode prevNode = _cellElement.OwnerDocument.SelectSingleNode("//d:conditionalFormatting", nsm);
if (prevNode == null)
{
prevNode = _cellElement.OwnerDocument.SelectSingleNode("//d:mergeCells", nsm);
if (prevNode == null)
{
prevNode = _cellElement.OwnerDocument.SelectSingleNode("//d:sheetData", nsm);
}
}
_cellElement.OwnerDocument.DocumentElement.InsertAfter(linkParent, prevNode);
}
string searchString = string.Format("./d:hyperlink[@ref = '{0}']", CellAddress);
XmlElement linkNode = (XmlElement)linkParent.SelectSingleNode(searchString, nsm);
XmlAttribute attr;
if (linkNode == null)
{
linkNode = _cellElement.OwnerDocument.CreateElement("hyperlink", @"http://schemas.openxmlformats.org/spreadsheetml/2006/main");
// now add cell address attribute
linkNode.SetAttribute("ref", CellAddress);
linkParent.AppendChild(linkNode);
}
attr = (XmlAttribute)linkNode.Attributes.GetNamedItem("id", @"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
if (attr == null)
{
attr = _cellElement.OwnerDocument.CreateAttribute("r", "id", @"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
linkNode.Attributes.Append(attr);
}
PackageRelationship relationship = null;
string relID = attr.Value;
if (relID == "")
relationship = part.CreateRelationship(_hyperlink, TargetMode.External, @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink");
else
{
relationship = part.GetRelationship(relID);
if (relationship.TargetUri != _hyperlink)
relationship = part.CreateRelationship(_hyperlink, TargetMode.External, @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink");
}
attr.Value = relationship.Id;
}
I then translated this code using the Open XML SDK 2.0 and it doesn't work. It seems the AddHyperlinkRelationship
method doesn't actually add the relationship to the .rels file. I'm not sure why, but it sure seems like a bug to me.
private void HyperlinkCreate(PackagePart part, XmlNamespaceManager nsm, XmlNode _cellElement, string CellAddress)
{
WorksheetPart workSheetPart = ExcelUtilities.GetWorkSheetPart(mWorkBookPart, "Program");
Uri hyperlinkUri = new Uri("http://www.yahoo.com", UriKind.Absolute);
Hyperlinks hyperlinks = workSheetPart.Worksheet.Descendants<Hyperlinks>().FirstOrDefault();
// Check to see if the <x:hyperlinks> element exists; if not figure out
// where to insert it depending on which elements are present in the Worksheet
if (hyperlinks == null)
{
// Create the hyperlinks node
hyperlinks = new Hyperlinks();
OpenXmlCompositeElement prevElement = workSheetPart.Worksheet.Descendants<ConditionalFormatting>().FirstOrDefault();
if (prevElement == null)
{
prevElement = workSheetPart.Worksheet.Descendants<MergeCells>().FirstOrDefault();
if (prevElement == null)
{
// No FirstOrDefault needed since a Worksheet requires SheetData or the excel doc will be corrupt
prevElement = workSheetPart.Worksheet.Descendants<SheetData>().First();
}
}
workSheetPart.Worksheet.InsertAfter(hyperlinks, prevElement);
}
Hyperlink hyperlink = hyperlinks.Descendants<Hyperlink>().Where(r => r.Reference.Equals(CellAddress)).FirstOrDefault();
if (hyperlink == null)
{
hyperlink = new Hyperlink() { Reference = CellAddress, Id = string.Empty };
}
HyperlinkRelationship hyperlinkRelationship = null;
string relId = hyperlink.Id;
if (relId.Equals(string.Empty))
{
hyperlinkRelationship = workSheetPart.AddHyperlinkRelationship(hyperlinkUri, true);
}
else
{
hyperlinkRelationship = workSheetPart.GetReferenceRelationship(relId) as HyperlinkRelationship;
if (!hyperlinkRelationship.Uri.Equals(hyperlinkUri))
{
hyperlinkRelationship = workSheetPart.AddHyperlinkRelationship(hyperlinkUri, true);
}
}
hyperlink.Id = hyperlinkRelationship.Id;
hyperlinks.AppendChild<Hyperlink>(hyperlink);
workSheetPart.Worksheet.Save();
}