使用Open XML SDK 2.0在Excel 2007中向单元格添加超链接

时间:2010-05-25 14:35:28

标签: openxml openxml-sdk spreadsheetml

我似乎无法找到有关如何使用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?

4 个答案:

答案 0 :(得分:6)

另一种可能性(我使用过)是使用Excel的HYPERLINK公式。我需要在每个单元格中创建单独的超链接,但单元格必须显示不同的文本,(我必须在单元格中显示跟踪编号,但是每个跟踪编号都有一个超链接到运营商的网站,并且必须处理多个运营商)。 / p>

一旦我实例化了一个单独的细胞,公式就会以这种方式应用于每个细胞(无疑有很多种方式):

// ...
Cell cell1 = new Cell(){ CellReference = "A1", StyleIndex = (UInt32Value)1U, DataType = CellValues.InlineString };
CellValue cellValue1 = new CellValue();

CellFormula cellFormula1 = new CellFormula() { Space = SpaceProcessingModeValues.Preserve };
cellFormula1.Text = @"HYPERLINK(""http://www.theclash.com"", ""Radio Clash"")";
cellValue1.Text = "Radio Clash";
cell1.Append(cellFormula1);
cell1.Append(cellValue1);
// append cell, etc.

通过这种方式,我能够为每个单元格创建单独的超链接和文本。顺便说一下,除非您引用带有蓝色字体的样式,否则链接将以默认字体颜色显示。

希望这有帮助。

答案 1 :(得分:2)

我可以使用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();     
        }

答案 2 :(得分:1)

您应该将它添加到接受超链接的对象,例如单元格,而不是工作表。这样的事情对你有用:

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;
        }


    }
}

答案 3 :(得分:0)

最简单的方法是使用HyperLink公式器,但是默认情况下链接不是蓝色的,这就是为什么要设置styleIndex的原因。

 private Cell BuildHyperlinkCell(string url) =>
    new Cell
    {
      DataType = new EnumValue<CellValues>(CellValues.String),
      CellFormula = new CellFormula($"HyperLink(\"{url}\")"),
      StyleIndex = 4u
    };

在工作簿中添加样式: http://www.dispatchertimer.com/tutorial/how-to-create-an-excel-file-in-net-using-openxml-part-3-add-stylesheet-to-the-spreadsheet/