使用 Open XML SDK 2.0 将超链接添加到 Excel 2007 中的单元格
我似乎找不到任何有关如何使用 Open XML SDK 2.0 将超链接添加到 Excel 2007 中的单元格的文档或代码示例。我正在使用以下代码,但是我缺少一个步骤吗?
WorksheetPart workSheetPart = ExcelUtilities.GetWorkSheetPart(mWorkBookPart, "Program");
workSheetPart.AddHyperlinkRelationship(new Uri("http://www.google.com", UriKind.Absolute), true);
workSheetPart.Worksheet.Save();
mWorkBookPart.Workbook.Save();
然后,当我尝试打开 Excel 文档时,它说文件已损坏,因为找不到超链接的关系 ID。如何设置或创建该关系 ID?
I can't seem to find any documentation or code samples on how to add a hyperlink to a cell in Excel 2007 using the Open XML SDK 2.0. I am using the following code, but is there a step I am missing?
WorksheetPart workSheetPart = ExcelUtilities.GetWorkSheetPart(mWorkBookPart, "Program");
workSheetPart.AddHyperlinkRelationship(new Uri("http://www.google.com", UriKind.Absolute), true);
workSheetPart.Worksheet.Save();
mWorkBookPart.Workbook.Save();
Then when I try and open the Excel document it says the file is corrupted because the Relationship Id for the hyperlink cannot be found. How do you setup or create that Relationship Id?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(5)
我能够使用 System.IO.Packaging 代码向单元格添加超链接:
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;
}
然后我使用 Open XML SDK 2.0 转换此代码,但它不起作用。看来 AddHyperlinkRelationship
方法实际上并未将关系添加到 .rels 文件中。我不知道为什么,但对我来说这确实是一个错误。
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();
}
您应该将其添加到接受超链接的对象(例如单元格)而不是工作表中。像这样的东西应该适合你:
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
namespace GeneratedCode
{
public class GeneratedClass
{
// Creates an Worksheet instance and adds its children.
public Worksheet GenerateWorksheet()
{
Worksheet worksheet1 = new Worksheet(){ MCAttributes = new MarkupCompatibilityAttributes(){ Ignorable = "x14ac" } };
worksheet1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
worksheet1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
worksheet1.AddNamespaceDeclaration("x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
SheetDimension sheetDimension1 = new SheetDimension(){ Reference = "A1" };
SheetViews sheetViews1 = new SheetViews();
SheetView sheetView1 = new SheetView(){ TabSelected = true, WorkbookViewId = (UInt32Value)0U };
sheetViews1.Append(sheetView1);
SheetFormatProperties sheetFormatProperties1 = new SheetFormatProperties(){ DefaultRowHeight = 14.4D, DyDescent = 0.3D };
SheetData sheetData1 = new SheetData();
Row row1 = new Row(){ RowIndex = (UInt32Value)1U, Spans = new ListValue<StringValue>() { InnerText = "1:1" }, DyDescent = 0.3D };
Cell cell1 = new Cell(){ CellReference = "A1", StyleIndex = (UInt32Value)1U, DataType = CellValues.SharedString };
CellValue cellValue1 = new CellValue();
cellValue1.Text = "0";
cell1.Append(cellValue1);
row1.Append(cell1);
sheetData1.Append(row1);
Hyperlinks hyperlinks1 = new Hyperlinks();
Hyperlink hyperlink1 = new Hyperlink(){ Reference = "A1", Id = "rId1" };
hyperlinks1.Append(hyperlink1);
PageMargins pageMargins1 = new PageMargins(){ Left = 0.7D, Right = 0.7D, Top = 0.75D, Bottom = 0.75D, Header = 0.3D, Footer = 0.3D };
worksheet1.Append(sheetDimension1);
worksheet1.Append(sheetViews1);
worksheet1.Append(sheetFormatProperties1);
worksheet1.Append(sheetData1);
worksheet1.Append(hyperlinks1);
worksheet1.Append(pageMargins1);
return worksheet1;
}
}
}
最简单的方法是使用超链接公式,但默认情况下链接不是蓝色的,这就是设置 styleIndex 的原因。
private Cell BuildHyperlinkCell(string url) =>
new Cell
{
DataType = new EnumValue<CellValues>(CellValues.String),
CellFormula = new CellFormula($"HyperLink(\"{url}\")"),
StyleIndex = 4u
};
我设法用这个函数创建一个超链接
/// <summary>
/// Add Hyperlink to Excel Worksheet
/// </summary>
/// <param name="worksheetDoc">Worksheet</param>
/// <param name="colName">Column name (A, B, C..)</param>
/// <param name="rowIndex">Row index (start from 1)</param>
/// <param name="link">a URI</param>
public static void AddHyperlik(WorksheetPart worksheetDoc, string colName, int rowIndex,System.Uri link)
{
DocumentFormat.OpenXml.Spreadsheet.Hyperlinks ls1 = worksheetDoc.Worksheet.Descendants<DocumentFormat.OpenXml.Spreadsheet.Hyperlinks>().FirstOrDefault();
if (ls1 == null)
{
ls1 = new DocumentFormat.OpenXml.Spreadsheet.Hyperlinks();
DocumentFormat.OpenXml.Spreadsheet.PageMargins pm = worksheetDoc.Worksheet.Descendants<DocumentFormat.OpenXml.Spreadsheet.PageMargins>().First();
worksheetDoc.Worksheet.InsertBefore(ls1, pm);
}
int idIdx = 1;
var list1 = ls1.Descendants<DocumentFormat.OpenXml.Spreadsheet.Hyperlink>().ToList().Select(x => x.Id.Value);
if (list1.Count() > 0 && list1.Where(y => y.Contains("IdLink")).Any())
{
idIdx = 1 + list1.Where(y => y.Contains("IdLink")).Select(x => int.Parse(x.Replace("IdLink", ""))).Max();
}
string id = "IdLink" + idIdx.ToString();
DocumentFormat.OpenXml.Spreadsheet.Hyperlink l1 = new DocumentFormat.OpenXml.Spreadsheet.Hyperlink() { Reference = (colName + rowIndex), Id = id };
ls1.Append(l1);
worksheetDoc.Worksheet.Save();
worksheetDoc.AddHyperlinkRelationship(link, true, id);
}
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
另一种可能性(我使用过)是使用 HYPERLINK< /a> Excel 公式。我需要在每个单元格中创建单独的超链接,但单元格必须显示不同的文本(我必须在单元格中显示跟踪号码,但每个跟踪号码都有一个到运营商站点的超链接,并且必须处理多个运营商)。
一旦我实例化了一个单独的单元格,公式就会以这种方式应用于每个单元格(无疑有多种方式):
通过这种方式,我能够为每个单元格创建单独的超链接和文本。顺便说一句,链接将以默认字体颜色显示,除非您引用蓝色字体的样式。
希望这有帮助。
Another possibility, (which I used), is to use the HYPERLINK formula for Excel. I needed to create individual hyperlinks in each cell, yet the cells had to display different text, (I had to display tracking numbers in the cells yet have a hyperlink for each tracking number to the carrier's site and had to handle multiple carriers).
Once I instantiated an individual cell, the formula was applied in this manner to each cell (there are undoubtedly numerous way):
In this way, I was able to create individual hyperlinks and text for each cell. By the way, the links will appear with the default font color unless you reference a style with blue font.
Hope this helps.