【问题标题】:Add Hyperlink to Cell in Excel 2007 Using Open XML SDK 2.0使用 Open XML SDK 2.0 在 Excel 2007 中向单元格添加超链接
【发布时间】:2010-05-25 14:35:28
【问题描述】:

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

【问题讨论】:

    标签: openxml openxml-sdk spreadsheetml


    【解决方案1】:

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

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

    // ...
    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.
    

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

    希望这会有所帮助。

    【讨论】:

    • 不错的选择。为我工作。
    【解决方案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();     
            }
    

    【讨论】:

      【解决方案3】:

      您应该将其添加到接受超链接的对象,例如单元格,而不是工作表。像这样的东西应该适合你:

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

      【讨论】:

      • 我没有看到直接从工作表访问 Cell 对象的方法。我正在使用 open xml sdk 2.0,据我所知,Cell 对象上没有 .Hyperlink 属性
      • 抱歉,随着 2.0 的 RTM,有些事情发生了变化。有关反映的示例,请参见上文。
      • 是的,该代码可以工作,但我已经有一个现有的工作表,并且想添加一个超链接到一个已经存在的单元格。
      • 只需将worksheet1的初始化更改为您的工作表,并更改其他初始化项,例如创建新单元格。将引用设置为您已有的内容。
      【解决方案4】:

      最简单的方法是使用超链接公式,但链接默认不是蓝色的,这就是设置 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/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-03
        • 1970-01-01
        • 2015-02-11
        • 2011-01-17
        • 2018-07-22
        • 1970-01-01
        • 2017-05-02
        相关资源
        最近更新 更多