HI there,
I have a document which has the following text in it {{MAP}}
I wish to replace that text with a hyperlink rather than static text.
I have tried the following line of code;
doc.Range.Replace("{{MAP}}", New Aspose.Words.DocumentBuilder().InsertHyperlink("MAP", "https://www.google.co.uk/maps/place/" & myRecord.PostCode, False).GetFieldCode)
But it always gives me the actual hyperlink full description not just the word MAP as a hyperlink.
I have tried it without the GetFieldCode option on the end but the replace function then reports that it does not have an overload with that option.
Can anyone help, this should be a fairly simple operation but I must be doing something silly.
Many thanks
@matthewsimpson You can achieve this using IReplacingCallback
. For example see ReplaceTextWithField in the code examples on GitHub
@matthewsimpson I have create a VB.NET
code example for you how to use IReplacingCallback
to insert hyperlink:
Dim doc As New Document("C:\Temp\in.docx")
Dim opt As New FindReplaceOptions()
opt.ReplacingCallback = New ReplaceTextWithFieldHandler()
Dim regex As New Regex("\{\{(MAP)\}\}")
doc.Range.Replace(regex, "https://www.google.co.uk/maps/place/", opt)
doc.Save("C:\Temp\out.docx")
Here is an implementation of IReplacingCallback
Imports Aspose.Words
Imports Aspose.Words.Replacing
Public Class ReplaceTextWithFieldHandler
Implements IReplacingCallback
Public Function Replacing(args As ReplacingArgs) As ReplaceAction Implements IReplacingCallback.Replacing
Dim runs As List(Of Run) = FindAndSplitMatchRuns(args)
Dim builder As New DocumentBuilder(DirectCast(args.MatchNode.Document, Document))
builder.MoveTo(runs(runs.Count - 1))
' Insert hyperlink, where the displayed value is the name of placeholder
' and the link is the replacement value.
builder.Font.StyleIdentifier = StyleIdentifier.Hyperlink
builder.InsertHyperlink(args.Match.Groups(1).Value, args.Replacement, False)
For Each run As Run In runs
run.Remove()
Next
Return ReplaceAction.Skip
End Function
''' <summary>
''' Finds And splits the match runs And returns them in an List.
''' </summary>
Public Function FindAndSplitMatchRuns(args As ReplacingArgs) As List(Of Run)
' This Is a Run node that contains either the beginning Or the complete match.
Dim currentNode As Node = args.MatchNode
' The first (And may be the only) run can contain text before the match,
' In this case it Is necessary to split the run.
If (args.MatchOffset > 0) Then
currentNode = SplitRun(DirectCast(currentNode, Run), args.MatchOffset)
End If
' This array Is used to store all nodes of the match for further removing.
Dim runs As New List(Of Run)()
' Find all runs that contain parts of the match string.
Dim remainingLength As Integer = args.Match.Value.Length
While (remainingLength > 0) AndAlso (currentNode IsNot Nothing) AndAlso (currentNode.GetText().Length <= remainingLength)
runs.Add(DirectCast(currentNode, Run))
remainingLength -= currentNode.GetText().Length
Do
currentNode = currentNode.NextSibling
Loop While (currentNode IsNot Nothing) AndAlso Not (currentNode.NodeType = NodeType.Run)
End While
' Split the last run that contains the match if there Is any text left.
If (currentNode IsNot Nothing) And (remainingLength > 0) Then
SplitRun(DirectCast(currentNode, Run), remainingLength)
runs.Add(DirectCast(currentNode, Run))
End If
Return runs
End Function
''' <summary>
''' Splits text of the specified run into two runs.
''' Inserts the New run just after the specified run.
''' </summary>
Private Function SplitRun(run As Run, position As Integer) As Run
Dim afterRun As Run = DirectCast(run.Clone(True), Run)
afterRun.Text = run.Text.Substring(position)
run.Text = run.Text.Substring(0, position)
run.ParentNode.InsertAfter(afterRun, run)
Return afterRun
End Function
End Class