使用 Open XML SDK 2.0 将超链接添加到 Excel 2007 中的单元格

问题描述 投票:0回答:5

我似乎找不到任何有关如何使用 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
5个回答
11
投票

另一种可能性(我使用过)是使用 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();     
        }

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


    }
}

0
投票

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


0
投票

我成功地用这个函数创建了一个超链接

/// <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);
}
© www.soinside.com 2019 - 2024. All rights reserved.