How to remove hyperlink from a Word document using C#, VB.NET
Syncfusion® Essential® DocIO is a .NET Word library used to create, read, and edit Word documents programmatically without Microsoft Word or interop dependencies. Using this library, you can remove hyperlink from a Word document in C# and VB.NET. Below steps need to be followed,
- Open a Word document with hyperlink
- Find the hyperlink field in the Word document
- Get the text from hyperlink field
- Replace a hyperlink field with a text value
Steps to remove hyperlink from a Word document using C#:
- Create a new C# console application project.
- Install Syncfusion.DocIO.WinForms NuGet package as a reference to your .NET Framework applications from the NuGet.org.
- Include the following namespace in the Program.cs file.
C#
using Syncfusion.DocIO.DLS;
VB
Imports Syncfusion.DocIO.DLS
- Use the following code to remove hyperlink from a Word document.
C#
//Opens the Word template document
using (WordDocument document = new WordDocument("Template.docx"))
{
//Finds all hyperlink fields in the Word document
FindAllHyperlinks(document);
//Removes hyperlink fields and replace with text
foreach (WField link in hyperlinks)
RemoveHyperlink(link);
//Clears the temporary hyperlink collection
hyperlinks.Clear();
//Saves the Word document
document.Save("Result.docx");
}
VB
'Opens the Word template document
Using document As WordDocument = New WordDocument("Template.docx")
Dim hyperlinks As List(Of WField) = FindAllHyperlinks(document)
'Removes hyperlink fields and replace with text
For Each link As WField In hyperlinks
RemoveHyperlink(link)
Next
‘Clears the temporary hyperlink collection
hyperlinks.Clear()
'Saves the Word document
document.Save("Result.docx")
End Using
- Use the following helper method to iterate throughout the Word document and find all the hyperlink fields in the Word document.
C#
private static void FindAllHyperlinks(WordDocument document)
{
//Processes the body contents for each section in the Word document
foreach (WSection section in document.Sections)
{
//Accesses the Body of section where all the contents in document are apart
WTextBody sectionBody = section.Body;
IterateTextBody(sectionBody);
WHeadersFooters headersFooters = section.HeadersFooters;
//consider that OddHeader & OddFooter are applied to this document
//Iterates through the TextBody of OddHeader and OddFooter
IterateTextBody(headersFooters.OddHeader);
IterateTextBody(headersFooters.OddFooter);
}
}
VB
Private Sub FindAllHyperlinks(ByVal document As WordDocument)
'Processes the body contents for each section in the Word document
For Each section As WSection In document.Sections
'Accesses the Body of section where all the contents in document are apart
Dim sectionBody As WTextBody = section.Body
IterateTextBody(sectionBody)
Dim headersFooters As WHeadersFooters = section.HeadersFooters
'Consider that OddHeader and OddFooter are applied to this document
'Iterates through the text body of OddHeader and OddFooter
IterateTextBody(headersFooters.OddHeader)
IterateTextBody(headersFooters.OddFooter)
Next
End Sub
- The following code example provides supporting methods for the above code.
C#
private static List<WField> hyperlinks = new List<WField>();
private static void IterateTextBody(WTextBody textBody)
{
//Iterates through each of the child items of WTextBody
for (int i = 0; i < textBody.ChildEntities.Count; i++)
{
//IEntity is the basic unit in DocIO DOM.
//Accesses the body items (should be either paragraph or table) as IEntity
IEntity bodyItemEntity = textBody.ChildEntities[i];
//A Text body has 3 types of elements - Paragraph, Table and Block Content Control
//Decides the element type by using EntityType
switch (bodyItemEntity.EntityType)
{
case EntityType.Paragraph:
WParagraph paragraph = bodyItemEntity as WParagraph;
//Processes the paragraph contents
//Iterates through the paragraph's DOM
IterateParagraph(paragraph);
break;
case EntityType.Table:
//Table is a collection of rows and cells
//Iterates through table's DOM
IterateTable(bodyItemEntity as WTable);
break;
case EntityType.BlockContentControl:
//Iterates to the body items of Block Content Control
IterateTextBody((bodyItemEntity as BlockContentControl).TextBody);
break;
}
}
}
private static void IterateParagraph(WParagraph paragraph)
{
for (int i = 0; i < paragraph.ChildEntities.Count; i++)
{
Entity entity = paragraph.ChildEntities[i];
//A paragraph can have child elements such as text, image, hyperlink, symbols, etc.,
//Decides the element type by using EntityType
switch (entity.EntityType)
{
case EntityType.Field:
WField field = entity as WField;
if (field.FieldType == FieldType.FieldHyperlink)
hyperlinks.Add(field);
break;
}
}
}
private static void IterateTable(WTable table)
{
//Iterates the row collection in a table
foreach (WTableRow row in table.Rows)
{
//Iterates the cell collection in a table row
foreach (WTableCell cell in row.Cells)
{
//Table cell is derived from (also a) TextBody
//Reusing the code meant for iterating TextBody
IterateTextBody(cell);
}
}
}
VB
Dim hyperlinks As List(Of WField) = New List(Of WField)
Private Sub IterateTextBody(textBody As WTextBody)
'Iterates through each of the child items of WTextBody
For i As Integer = 0 To textBody.ChildEntities.Count - 1
'IEntity is the basic unit in DocIO DOM.
'Accesses the body items (should be either paragraph or table) as IEntity
Dim bodyItemEntity As IEntity = textBody.ChildEntities(i)
'A Text body has 3 types of elements - Paragraph, Table and Block Content Control
'Decides the element type by using EntityType
Select Case bodyItemEntity.EntityType
Case EntityType.Paragraph
Dim paragraph As WParagraph = TryCast(bodyItemEntity, WParagraph)
'Processes the paragraph contents
'Iterates through the paragraph's DOM
IterateParagraph(paragraph)
Exit Select
Case EntityType.Table
'Table is a collection of rows and cells
'Iterates through table's DOM
IterateTable(TryCast(bodyItemEntity, WTable))
Exit Select
Case EntityType.BlockContentControl
'Iterates to the body items of Block Content Control
IterateTextBody(TryCast(bodyItemEntity, BlockContentControl).TextBody)
Exit Select
End Select
Next
End Sub
Private Sub IterateParagraph(paragraph As WParagraph)
For i As Integer = 0 To paragraph.ChildEntities.Count - 1
Dim entity As Entity = paragraph.ChildEntities(i)
'A Paragraph has child elements such as text, image, hyperlink, symbols, etc.,
'Decides the element type by using EntityType
Select Case entity.EntityType
Case EntityType.Field
Dim field As WField = TryCast(entity, WField)
If (field.FieldType = FieldType.FieldHyperlink) Then
hyperlinks.Add(field)
End If
Exit Select
End Select
Next
End Sub
Private Sub IterateTable(table As WTable)
'Iterates the row collection in a table
For Each row As WTableRow In table.Rows
'Iterates the cell collection in a table row
For Each cell As WTableCell In row.Cells
'Table cell is derived from (also a) TextBody
'Reusing the code meant for iterating TextBody
IterateTextBody(cell)
Next
Next
End Sub
- Use the following helper method to get the text from hyperlink field.
C#
private static string GetHyperlinkText(int hyperlinkIndex, WParagraph paragraph)
{
string text = string.Empty;
//Add the hyperlink field in stack to get the textrange from nested fields.
Stack<Entity> fieldStack = new Stack<Entity>();
fieldStack.Push(paragraph.ChildEntities[hyperlinkIndex]);
//Flag to get the text from textrange between field separator and end.
bool isFieldCode = true;
int i = (hyperlinkIndex + 1);
while (i < paragraph.Items.Count)
{
Entity item = paragraph.ChildEntities[i];
//If it is nested field, maintain in stack.
if ((item is WField))
{
fieldStack.Push(item);
//Set flag to skip getting text from textrange.
isFieldCode = true;
}
else if ((item is WFieldMark) && (((WFieldMark)(item)).Type == FieldMarkType.FieldSeparator))
//If separator is reached, set flag to read text from textrange.
isFieldCode = false;
else if ((item is WFieldMark) && (((WFieldMark)(item)).Type == FieldMarkType.FieldEnd))
{
//If field end is reached, check whether it is end of hyperlink field and skip the iteration.
if (fieldStack.Count == 1)
{
fieldStack.Clear();
return text;
}
else
fieldStack.Pop();
}
else if (!isFieldCode && (item is WTextRange))
text = (text + ((WTextRange)(item)).Text);
i = (i + 1);
}
return text;
}
VB
Private Function GetHyperlinkText(ByVal hyperlinkIndex As Integer, ByVal paragraph As WParagraph) As String
Dim text As String = String.Empty
'Add the hyperlink field in stack to get the textrange from nested fields.
Dim fieldStack As Stack(Of Entity) = New Stack(Of Entity)
fieldStack.Push(paragraph.ChildEntities(hyperlinkIndex))
'Flag to get the text from textrange between field separator and end.
Dim isFieldCode As Boolean = True
Dim i As Integer = (hyperlinkIndex + 1)
While (i < paragraph.Items.Count)
Dim item As Entity = paragraph.ChildEntities(i)
'If it is nested field, maintain in stack.
If (TypeOf item Is WField) Then
fieldStack.Push(item)
'Set flag to skip getting text from textrange.
isFieldCode = True
ElseIf ((TypeOf item Is WFieldMark) AndAlso (CType(item, WFieldMark).Type = FieldMarkType.FieldSeparator)) Then
isFieldCode = False
ElseIf ((TypeOf item Is WFieldMark) AndAlso (CType(item, WFieldMark).Type = FieldMarkType.FieldEnd)) Then
'If field end is reached, check whether it is end of hyperlink field and skip the iteration.
If (fieldStack.Count = 1) Then
fieldStack.Clear()
Return text
Else
fieldStack.Pop()
End If
ElseIf (Not isFieldCode AndAlso (TypeOf item Is WTextRange)) Then
text = (text + CType(item, WTextRange).Text)
End If
i = (i + 1)
End While
Return text
End Function
- Use the following helper method to replace a hyperlink field with a text value.
C#
private static void RemoveHyperlink(WField field)
{
WParagraph paragraph = field.OwnerParagraph;
int itemIndex = paragraph.ChildEntities.IndexOf(field);
WTextRange textRange = new WTextRange(paragraph.Document);
//Gets the text from hyperlink field.
textRange.Text = GetHyperlinkText(itemIndex, paragraph);
//Removes the hyperlink field
paragraph.ChildEntities.RemoveAt(itemIndex);
//Inserts the hyperlink text
paragraph.ChildEntities.Insert(itemIndex, textRange);
}
VB
Private Sub RemoveHyperlink(ByVal field As WField)
Dim paragraph As WParagraph = field.OwnerParagraph
Dim itemIndex As Integer = paragraph.ChildEntities.IndexOf(field)
Dim textRange As WTextRange = New WTextRange(paragraph.Document)
'Gets the text from hyperlink field.
textRange.Text = GetHyperlinkText(itemIndex, paragraph)
'Removes the hyperlink field
paragraph.ChildEntities.RemoveAt(itemIndex)
'Inserts the hyperlink text
paragraph.ChildEntities.Insert(itemIndex, textRange)
End Sub
A complete working example to remove hyperlink from a Word document using C# can be downloaded from remove hyperlink from a Word document.zip
Input Word document as follows.
By executing the program, you will get the output Word document as follows.
Take a moment to peruse the documentation, where you can find basic Word document processing options along with features like mail merge, merge and split documents, find and replace text in the Word document, protect the Word documents, and most importantly PDF and Image conversions with code examples.
Explore more about the rich set of Syncfusion® Word Framework features.
Starting with v16.2.0.x, if you reference Syncfusion® assemblies from trial setup or from the NuGet feed, include a license key in your projects. Refer to link to learn about generating and registering Syncfusion® license key in your application to use the components without trail message.