2010-05-25 6 views
0

Je n'arrive pas à trouver de documentation ou d'exemples de code sur la façon d'ajouter un lien hypertexte à une cellule dans Excel 2007 à l'aide d'Open XML SDK 2.0. J'utilise le code suivant, mais y a-t-il un pas qui me manque?Ajouter un lien hypertexte à la cellule dans Excel 2007 à l'aide d'Open XML SDK 2.0

WorksheetPart workSheetPart = ExcelUtilities.GetWorkSheetPart(mWorkBookPart, "Program"); 

workSheetPart.AddHyperlinkRelationship(new Uri("http://www.google.com", UriKind.Absolute), true); 

workSheetPart.Worksheet.Save(); 

mWorkBookPart.Workbook.Save(); 

Alors quand je tente d'ouvrir le document Excel, il dit que le fichier est corrompu, car l'ID relation l'hyperlien ne peut pas être trouvé. Comment configurez-vous ou créez-vous cet ID de relation?

Répondre

2

j'ai pu ajouter un lien hypertexte à une cellule en utilisant 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; 
} 

Je puis traduit ce code à l'aide du SDK Open XML 2.0 et doesn ne fonctionne pas. Il semble que la méthode AddHyperlinkRelationship n'ajoute pas réellement la relation au fichier .rels. Je ne sais pas pourquoi, mais ça a l'air d'être un bug pour moi.

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

Vous devez l'ajouter à un objet qui accepte les liens hypertexte, tels qu'une cellule, au lieu de la feuille de calcul. Quelque chose comme cela devrait fonctionner pour vous:

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

Je ne vois pas un moyen d'accéder à un objet Cell directement à partir d'une feuille de calcul. J'utilise l'open xml sdk 2.0 et pour autant que je peux dire il n'y a pas de propriété .Hyperlink sur l'objet cellulaire – amurra

+0

excuses, certaines choses ont changé avec le RTM de 2.0. Voir ci-dessus pour l'exemple réfléchi. –

+0

ouais ce code fonctionnera, mais j'ai déjà une feuille existante et je veux ajouter un lien hypertexte à une cellule qui existe déjà. – amurra

5

Une autre possibilité (que je), est d'utiliser la formule HYPERLINK pour Excel. J'avais besoin de créer des hyperliens individuels dans chaque cellule, mais les cellules devaient afficher un texte différent, (j'ai dû afficher des numéros de suivi dans les cellules mais avoir un lien hypertexte pour chaque numéro de suivi vers le site du transporteur).

Une fois que j'instancié une cellule individuelle, la formule a été appliquée de cette manière à chaque cellule (il y a sans doute de nombreux chemin):

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

De cette façon, je suis en mesure de créer des liens individuels et texte chaque cellule. En passant, les liens apparaîtront avec la couleur de police par défaut sauf si vous faites référence à un style avec une police bleue.

Espérons que cela aide.

+0

Belle option. A travaillé pour moi. – Jeff

Questions connexes