
Syncfusion Dotnet Word
- 290 installs
- 2 repo stars
- Updated July 14, 2026
- syncfusion/document-sdk-skills
Helps with ai & agent building tasks.
About
syncfusion-dotnet-word is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- syncfusion-dotnet-word
- AI & Agent Building
- AI-coding skill
Syncfusion Dotnet Word by the numbers
- 290 all-time installs (skills.sh)
- +10 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #2,366 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/document-sdk-skills --skill syncfusion-dotnet-wordAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 290 |
|---|---|
| repo stars | ★ 2 |
| Last updated | July 14, 2026 |
| Repository | syncfusion/document-sdk-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Word (DOCX) Document Processing
Overview
Create, edit, and convert Word (.docx, .doc) files using the Syncfusion Word Library. This skill supports two operational modes — generating C# code for the user's project or executing tasks directly through a CSX script.
Key Capabilities
- Create & Edit: Documents (.docx, .doc, .rtf, .txt, .xml), paragraphs, headings, styles, lists, tables, charts, shapes, images, hyperlinks, bookmarks, watermarks, headers/footers, form fields, content controls, SmartArt, OLE objects
- Advanced Features: Mail merge (DataTable, JSON, XML, custom objects), track changes, comments, mathematical equations (LaTeX), compare/split/merge documents, table of contents
- Conversion: Word to PDF (font embedding, PDF/A, accessibility), Word to Image (PNG, JPEG, BMP, TIFF), HTML ↔ DOCX, RTF ↔ DOCX, Text ↔ DOCX, XML ↔ DOCX
- Security: Password encryption/decryption, document protection with editable ranges, macro management
Prerequisites
- .NET SDK 8+ and
dotnet-script:dotnet tool install -g dotnet-script - Syncfusion License: https://www.syncfusion.com/products/communitylicense
Quick Start Examples
Example 1: Generate Code (Mode 1)
User: "Show me how to create a Word document with a table"
Result: C# code snippet displayed (no files created)
Example 2: Execute Task (Mode 2)
User: "Create a Word document with a table at output/report.docx"
Result: Physical file created at specified path
Two Modes — Choose Based on User Intent
Before choosing a mode, infer what the user wants to accomplish:
Mode 1: Generate C# Code for the User's Project (default)
Use this mode when the user wants to view, write, review, refactor, or modify C# code related to Word processing.
Trigger keywords: "show me how", "how to", "how can I", "how do I", "provide code", "provide an example", "give an example", "demonstrate", "code snippet", "sample code", "example", "sample", "give me", "show me", "Program.cs", "example code", "generate code for", "codesnippet"
Workflow:
Step 1 — Detect the Application Type and Suggest the Correct NuGet Package(s)
- Inspect the workspace project files (
.csproj,web.config,App.config,Startup.cs,Program.cs, etc.) and use the detection signals table inreferences/nuget-packages.mdto identify the application type. - Look up the correct package(s) from
references/nuget-packages.mdbased on the detected app type and tell the user to install them before generating any code.
Step 2 — Generate Code from Reference Files Only
Do NOT invent, guess, or suggest any API, method, property, class, or namespace not explicitly present in the reference files.
- Read the relevant
references/*.mdfile(s) for the requested feature - Build C# code strictly from the APIs and snippets found in those files
- Select the correct snippet variant based on the app type detected in Step 1:
- Windows-specific apps (WinForms, WPF, .NET Framework Console, ASP.NET MVC5) → use Windows-specific snippets
- Cross-platform apps (ASP.NET Core, .NET Core/.NET 5+ Console, Blazor, MAUI) → use cross-platform /
.Net.Coresnippets - Do not create or run any
.csxscript
---
Mode 2: Execute via CSX Script (does not touch project files)
Use this mode only when the user explicitly requests execution, file generation, or a fully produced output (such as a completed Docx file).
Trigger keywords: "create a word document", "make a document", "generate a document", "open", "edit", "modify", "change" a .docx file, "without modifying my project", "run a csx script", or when the user provides a file path (e.g., output/report.docx).
Workflow:
Step 1 — Create Temp CSX Script
- Start with
references/template.csxas the base - Create at:
{skill-root}/syncfusion-dotnet-word/scripts/temp-{uniqueId}.csx(e.g.,skill-root=.codestudio/skills) - Use random GUID for unique filename (e.g.,
temp-a3f7b2c1.csx); never create in workspace root
Step 2 — Build Script from Reference Files
- Do NOT invent APIs/methods not in reference files
- Read relevant
references/*.mdfile(s) and extract code snippets - Replace all placeholders: file paths, document properties, data values, field names, etc.
Step 3 — Execute Script
- Run:
dotnet script {skill-root}/syncfusion-dotnet-word/scripts/temp-{uniqueId}.csx - Verify successful execution and capture any errors
Step 4 — Clean Up and Report
- Delete the temp
.csxfile after execution - Report SUCCESS/ERROR with output file path(s) and any error messages with fixes
---
Code References
All templates and snippets are in the references/ folder:
| File | Contents |
|---|---|
| template.csx | Base CSX script structure (Mode 2 only) |
| document-structure.md | Create/load document, add sections, page setup, save to file or stream, supported formats |
| styles-and-formats.md | Paragraphs, headings, bullet & numbered lists |
| paragraph-and-styles.md | Add paragraphs, paragraph formatting, styles (built-in/custom), text formatting, tab stops, breaks, symbols, text boxes |
| tables.md | Create tables, cell formatting, merge cells |
| bookmarks.md | Create bookmarks, navigate, retrieve, insert, replace, delete content |
| charts.md | Create charts from scratch/Excel, modify data, refresh, customize elements, 3D formatting, convert to image |
| shapes.md | Add shapes, format, rotate, group, ungroup shapes |
| mail-merge.md | Simple field merge, merge with regions (groups), nested merge, DataTable, dynamic objects, business objects, DataView, XML, JSON, image merge fields, merge events (MergeField, MergeImageField, BeforeClearField, BeforeClearGroupField), field mapping, retrieve merge field names, remove empty paragraphs, clear fields option |
| form-fields.md | Add checkboxes, dropdowns, text input fields, modify properties |
| macros.md | Load/save macro-enabled documents (DOTM, DOCM), check for macros, remove macros, preserve macros through conversion |
| mathematical-equation.md | Create equations (fraction, radical, matrix, N-array, etc.), modify existing equations, LaTeX support, equation formatting |
| split-word-documents.md | Split documents by sections, headings, bookmarks, placeholder text |
| merge-word-documents.md | Merge documents in new page, same page, maintain imported list styles |
| table-of-contents.md | Add TOC, update, apply switches, custom styles, table of figures, remove TOC |
| compare-word-documents.md | Compare two Word documents, set author and date, comparison options, ignore format changes |
| html-conversions.md | Convert HTML to DOCX, convert DOCX to HTML, XHTML validation, customize images (import/export), CSS selectors, export options, headers/footers export |
| rtf-conversions.md | Convert RTF to DOCX, convert DOCX to RTF, preserve formatting and content |
| markdown-conversion.md | Convert Markdown to DOCX, convert DOCX to Markdown, customize images, CommonMark and GitHub-flavored syntax support |
| text-conversions.md | Convert Text to DOCX, convert DOCX to Text, extract plain text, preserve text content |
| xml-conversions.md | Convert Word to XML (WordML), convert XML to Word, Word Processing XML format (2007+) |
| word-to-pdf.md | Convert DOCX to PDF, embed fonts, PDF/A conformance, accessible PDF, preserve form fields, font substitution, fallback fonts by script type and Unicode ranges |
| word-to-image.md | Convert DOCX to Image |
| word-to-odt.md | Convert Word to ODT, preserve formatting and content, supported document elements, text formatting |
| encryption.md | Encrypt with password, open encrypted doc, remove encryption, protect from editing, editable ranges |
| watermark.md | Text and picture watermarks, watermark layout, scaling, washout effect, remove watermark |
| find-and-replace.md | Find/FindAll/FindNext, Replace (string/regex), ReplaceSingleLine, and FindItem* APIs |
| footnotes-and-endnotes.md | Add footnotes and endnotes, set positions (bottom of page/end of section), numbering formats, separators, modify content, remove notes |
| track-changes.md | Enable/disable track changes, accept/reject changes, filter by reviewer, revision information |
| comments.md | Add/modify/remove comments, insert on specific text, access parent comments, retrieve commented items |
| content-controls.md | Block and inline content controls, types (rich text, plain text, checkbox, date, dropdown, picture), properties, protection, form filling, XML mapping |
| header-footer.md | Add/remove headers and footers, page numbers with fields (date, time), odd/even pages, first page different, borders, images, link to previous |
| hyperlinks.md | Web hyperlink, email hyperlink, file hyperlink, bookmark hyperlink, image hyperlink, modify hyperlink |
| ole-object.md | Add embedded OLE objects, extract OLE objects to file, remove OLE objects, object types |
| smartarts.md | Create SmartArt layouts, add/modify nodes, change appearance, assistant nodes, remove SmartArt |
---
Rules
- Output files go in
./output/directory - Temp
.csxscripts must be created inside{skill-root}/syncfusion-dotnet-word/scripts/— never in the workspace root or customerscripts/folder - Never use Python libraries (e.g., python-docx)
- Never leave temp
.csxfiles after execution
Syncfusion .NET Word Library Skill
Overview
Create, edit, and convert Word (.docx, .doc) files using the Syncfusion Word Library. This skill supports two operational modes — generating C# code for the user's project or executing tasks directly through a CSX script.
See [SKILL.md](SKILL.md) for the full intent-routing guide and rules.
---
Key Capabilities
- Create & Edit: Documents (.docx, .doc, .rtf, .txt, .xml), paragraphs, headings, styles, lists, tables, charts, shapes, images, hyperlinks, bookmarks, watermarks, headers/footers, form fields, content controls, SmartArt, OLE objects
- Advanced Features: Mail merge (DataTable, JSON, XML, custom objects), track changes, comments, mathematical equations (LaTeX), compare/split/merge documents, table of contents
- Conversion: Word to PDF (font embedding, PDF/A, accessibility), Word to Image (PNG, JPEG, BMP, TIFF), HTML ↔ DOCX, RTF ↔ DOCX, Text ↔ DOCX, XML ↔ DOCX
- Security: Password encryption/decryption, document protection with editable ranges, macro management
Getting Started
How to Integrate Skills
Step 1: Checkout and copy the required skills
Clone or download the Document-SDK-Skills repository and copy the syncfusion-dotnet-word skill from the skills/ directory.
Step 2: Install the skill
Place the copied skill folders in your workspace following this structure:
your-workspace/
├── .github/skills/ # or .claude/skills/ or .codestudio/skills/
│ └── syncfusion-dotnet-word/
│ └── SKILL.md
├── your-project-files...
└── Program.csStep 3: Verify and manage your skills
Type /skills in the GitHub Copilot or Code Studio chat to quickly access the Configure Skills menu and manage your installed skills.
Step 4: Use skills in VS Code
There are two ways to use skills:
1. Slash commands - Type / in the GitHub Copilot chat to see available skills. For example:
/syncfusion-dotnet-word Create a report with a table of contents2. Automatic loading - Simply describe your task naturally, and your AI Agent automatically loads the relevant skill:
Create a Word document with company letterhead and a data tableWhen a skill is loaded, AI Agent gains specialized knowledge of Syncfusion .NET libraries and can help you generate code or execute document operations efficiently.
Prerequisites
# .NET SDK 8+
dotnet --version
# dotnet-script (required for Mode 2)
dotnet tool install -g dotnet-scriptSyncfusion License
Get a free license: Syncfusion Community License
NuGet Packages Used in Mode 2
Install the package for the format you need:
# Word
dotnet add package Syncfusion.DocIO.Net.Core
dotnet add package Syncfusion.DocIORenderer.Net.Core # For PDF conversion---
Example Prompts
Mode 1 — Code Generation
Use these when you want C# code snippets for your own project.
- "Show me DocIO code to create a Word document with a title, heading, and a paragraph."
- "Generate a C# snippet to add a 3×4 table to a Word document using Syncfusion DocIO."
- "Write Program.cs code using DocIO to perform a mail merge with a DataTable."
- "How do I add a header and footer with page numbers using Syncfusion DocIO?"
Mode 2 — Document Generation
Use these when you want a `.docx` file created right now in the workspace.
- "Create a Word document about the top 5 programming languages in 2025."
- "Generate a meeting agenda document and save it to
output/agenda.docx." - "Open
output/report.docxand change its page orientation to Landscape." - "Convert
output/report.docxto PDF."
---
Troubleshooting
| Issue | Solution |
|---|---|
dotnet script not found | dotnet tool install -g dotnet-script |
| Missing NuGet package | dotnet add package Syncfusion.DocIO.Net.Core |
| File access error | Ensure the file isn't open in another application |
---
Resources
---
License
Syncfusion .NET Word library requires a commercial license for production use. A free community license is available for qualifying organizations.
Bookmarks
All bookmark operations — creating bookmarks, navigating to bookmarks, retrieving content, inserting content, replacing content, and deleting bookmarks.
---
Required Common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Add Bookmark
Minimal Code
var para = section.AddParagraph();
para.AppendBookmarkStart("BookmarkName");
para.AppendText("Content inside bookmark");
para.AppendBookmarkEnd("BookmarkName");With Formatted Content
var para = section.AddParagraph();
para.AppendBookmarkStart("Northwind");
var text = para.AppendText("The Northwind sample database provides data you can experiment with and database objects that demonstrate features you might want to implement in your own databases.");
text.CharacterFormat.Bold = true;
text.CharacterFormat.FontSize = 12f;
para.AppendBookmarkEnd("Northwind");
para.AppendText(" Using Northwind, you can become familiar with how a relational database is structured.");Placeholders
"BookmarkName"→ Replace with"{bookmark-name}""Content inside bookmark"→ Replace with"{bookmark-content}"
---
Get Bookmark Instance
Minimal Code
// Access a bookmark by name
var bookmark = doc.Bookmarks.FindByName("BookmarkName");Access Bookmark Properties
Common code for Cross-Platform and Windows-Specific
var bookmark = doc.Bookmarks.FindByName("Northwind");
// Access the paragraph containing bookmark start
var ownerPara = bookmark.BookmarkStart.OwnerParagraph;Cross-Platform
ownerPara.ParagraphFormat.BackColor = Syncfusion.Drawing.Color.AliceBlue;Windows-Specific
ownerPara.ParagraphFormat.BackColor = System.Drawing.Color.AliceBlue;Placeholders
"BookmarkName"→ Replace with"{bookmark-name}"
---
Remove Bookmark
Minimal Code
// Find and remove a bookmark
var bookmark = doc.Bookmarks.FindByName("BookmarkName");
doc.Bookmarks.Remove(bookmark);Remove by Name
// Remove bookmark directly by name
var bookmark = doc.Bookmarks.FindByName("Northwind");
if (bookmark != null)
doc.Bookmarks.Remove(bookmark);Remove all Bookmarks
// Remove all the bookmarks from Word document
doc.Bookmarks.Clear();Placeholders
"BookmarkName"→ Replace with"{bookmark-name}"
---
Navigate to Bookmark
Minimal Code
// Create bookmark navigator and move to bookmark
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName");Navigate with Position Control
var bookmarkNavigator = new BookmarksNavigator(doc);
// Move to bookmark end
bookmarkNavigator.MoveToBookmark("BookmarkName", false, true);
// Move to bookmark start
bookmarkNavigator.MoveToBookmark("BookmarkName", true, false);Placeholders
"BookmarkName"→ Replace with"{bookmark-name}"
---
Retrieve Bookmark Content
Get Content as TextBodyPart (Single Section)
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName");
// Get bookmark content as TextBodyPart
TextBodyPart part = bookmarkNavigator.GetBookmarkContent();
// Add retrieved content to another section
doc.AddSection();
for (int i = 0; i < part.BodyItems.Count; i++)
doc.LastSection.Body.ChildEntities.Add(part.BodyItems[i]);Get Content as WordDocumentPart (Multi-Section)
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName");
// Get bookmark content as WordDocumentPart
WordDocumentPart wordDocumentPart = bookmarkNavigator.GetContent();
// Save as separate Word document
WordDocument newDocument = wordDocumentPart.GetAsWordDocument();
newDocument.Save(outputPath);
newDocument.Close();
wordDocumentPart.Close();Placeholders
"BookmarkName"→ Replace with"{bookmark-name}"
---
Retrieve Word Document Content
Get Entire Word Document Content as WordDocumentPart
var fileStream = new FileStream("Template.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(fileStream, FormatType.Docx);
// Get Word document content as WordDocumentPart
WordDocumentPart wordDocumentPart = new WordDocumentPart(doc);Placeholders
"Template.docx"→ Replace with"{filename}.docx"
---
Retrieve Bookmark Content Within Table
Minimal Code
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BkmkInTable");
// Set column range for rectangular selection
bookmarkNavigator.CurrentBookmark.FirstColumn = 1;
bookmarkNavigator.CurrentBookmark.LastColumn = 3;
// Get the selected content
TextBodyPart part = bookmarkNavigator.GetBookmarkContent();Full Example with Table
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BkmkInTable");
// Select from column index 1 to 4
bookmarkNavigator.CurrentBookmark.FirstColumn = 1;
bookmarkNavigator.CurrentBookmark.LastColumn = 4;
// Retrieve content
TextBodyPart part = bookmarkNavigator.GetBookmarkContent();
// Add to new section
doc.AddSection();
for (int i = 0; i < part.BodyItems.Count; i++)
doc.LastSection.Body.ChildEntities.Add(part.BodyItems[i]);Placeholders
"BkmkInTable"→ Replace with"{bookmark-name}"1,3→ Replace with{start-column},{end-column}
---
Insert Content into Bookmark
Insert Simple Text
Insert with Formatting
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName");
// Insert text before bookmark end and preserve existing formatting.
bookmarkNavigator.InsertText("New text content here.", true);Insert without Formatting
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName");
// Insert text before bookmark end and discard existing formatting.
bookmarkNavigator.InsertText("New text content here.", false);Insert Paragraph
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName", false, true);
// Create new paragraph
IWParagraph paragraph = new WParagraph(doc);
paragraph.AppendText("This is a new paragraph inserted at the bookmark location.");
// Insert paragraph after bookmark start
bookmarkNavigator.InsertParagraph(paragraph);Insert Paragraph Item (Image)
Common code for Cross-Platform and Windows-Specific
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName", false, true);
// Insert picture after bookmark end
WPicture picture = bookmarkNavigator.InsertParagraphItem(ParagraphItemType.Picture) as WPicture;Cross-Platform
FileStream imageStream = new FileStream("image.png", FileMode.Open, FileAccess.Read);
picture.LoadImage(imageStream);Windows-Specific
picture.LoadImage(Image.FromFile("Northwind.png"));Common code for Cross-Platform and Windows-Specific
picture.WidthScale = 50;
picture.HeightScale = 50;Insert Table
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName", false, false);
// Create and insert table
WTable table = new WTable(doc);
table.ResetCells(3, 2);
table[0, 0].AddParagraph().AppendText("Column 1");
table[0, 1].AddParagraph().AppendText("Column 2");
table[1, 0].AddParagraph().AppendText("Data 1");
table[1, 1].AddParagraph().AppendText("Data 2");
table[2, 0].AddParagraph().AppendText("Data 3");
table[2, 1].AddParagraph().AppendText("Data 4");
bookmarkNavigator.InsertTable(table);Insert TextBodyPart
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("SourceBookmark");
// Get content from source bookmark
TextBodyPart textBodyPart = bookmarkNavigator.GetBookmarkContent();
// Move to destination bookmark
bookmarkNavigator.MoveToBookmark("DestinationBookmark", true, true);
// Insert the text body part
bookmarkNavigator.InsertTextBodyPart(textBodyPart);Placeholders
"BookmarkName"→ Replace with"{bookmark-name}""New text content here."→ Replace with"{text-content}"
---
Delete Bookmark Content
Minimal Code
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName");
// Delete content but preserve formatting
bookmarkNavigator.DeleteBookmarkContent(false);Delete with Formatting
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("BookmarkName");
// Delete content including formatting
bookmarkNavigator.DeleteBookmarkContent(true);Placeholders
"BookmarkName"→ Replace with"{bookmark-name}"
---
Replace Bookmark Content
Replace with TextBodyPart
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("SourceBookmark");
// Get content from source
TextBodyPart textBodyPart = bookmarkNavigator.GetBookmarkContent();
// Move to target bookmark
bookmarkNavigator.MoveToBookmark("TargetBookmark");
// Replace content
bookmarkNavigator.ReplaceBookmarkContent(textBodyPart);Replace with Plain Text
Replace with Formatting
// Bookmark "BookmarkName" already exists and contains formatted text
BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(doc);
// Move to the virtual cursor before the end location of the bookmark "BookmarkName"
bookmarkNavigator.MoveToBookmark("BookmarkName");
// Replace the bookmark content with simple text and preserve existing formatting.
bookmarkNavigator.ReplaceBookmarkContent(" Northwind Database is a set of tables containing data fitted into predefined categories.", true);Replace without Formatting
// Bookmark "BookmarkName" already exists and contains formatted text
BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(doc);
// Move to the virtual cursor before the end location of the bookmark "BookmarkName"
bookmarkNavigator.MoveToBookmark("BookmarkName");
// Replace the bookmark content with simple text and discard existing formatting.
bookmarkNavigator.ReplaceBookmarkContent(" Northwind Database is a set of tables containing data fitted into predefined categories.", false);Placeholders
"BookmarkName"→ Replace with"{bookmark-name}"
Replace with WordDocumentPart
Common for Cross-Platform and Windows-Specific
// Load template document
FileStream templateStream = new FileStream("Template.docx", FileMode.Open, FileAccess.Read);
WordDocument templateDoc = new WordDocument(templateStream, FormatType.Docx);
var bookmarkNavigator = new BookmarksNavigator(templateDoc);
bookmarkNavigator.MoveToBookmark("SourceBookmark");
// Get content as WordDocumentPart
WordDocumentPart wordDocumentPart = bookmarkNavigator.GetContent();
// Load target document
FileStream targetStream = new FileStream("Target.docx", FileMode.Open, FileAccess.Read);
WordDocument targetDoc = new WordDocument(targetStream, FormatType.Docx);
bookmarkNavigator = new BookmarksNavigator(targetDoc);
bookmarkNavigator.MoveToBookmark("TargetBookmark");
// Replace content
bookmarkNavigator.ReplaceContent(wordDocumentPart);
wordDocumentPart.Close();
templateDoc.Close();Placeholders
"SourceBookmark","TargetBookmark"→ Replace with"{source-bookmark-name}","{target-bookmark-name}"
---
Complete Example: Bookmark Operations
Full Example
Common for Cross-Platform and Windows-Specific
var outputPath = Path.Combine(Directory.GetCurrentDirectory(), "output", "BookmarkOperations.docx");
var doc = new WordDocument();
var section = doc.AddSection();
section.PageSetup.Margins.All = 72f;
// Add title
var title = section.AddParagraph();
title.AppendText("Bookmark Operations Demo");
title.ApplyStyle(BuiltinStyle.Heading1);
section.AddParagraph();
// Add first paragraph with bookmark
var para1 = section.AddParagraph();
para1.AppendText("Before bookmark. ");
para1.AppendBookmarkStart("ContentBookmark");
para1.AppendText("This content is inside the bookmark and can be retrieved, replaced, or deleted.");
para1.AppendBookmarkEnd("ContentBookmark");
para1.AppendText(" After bookmark.");
section.AddParagraph();
// Navigate to bookmark and insert content
var bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("ContentBookmark", false, true);
bookmarkNavigator.InsertText(" [Inserted text after bookmark start]", false);
// Add another section with bookmark
doc.AddSection();
var para2 = doc.LastSection.AddParagraph();
para2.AppendText("Target section with empty bookmark: ");
para2.AppendBookmarkStart("EmptyBookmark");
para2.AppendBookmarkEnd("EmptyBookmark");
// Copy content from first bookmark to second
bookmarkNavigator.MoveToBookmark("ContentBookmark");
TextBodyPart contentPart = bookmarkNavigator.GetBookmarkContent();
bookmarkNavigator.MoveToBookmark("EmptyBookmark");
bookmarkNavigator.ReplaceBookmarkContent(contentPart);
doc.Save(outputPath);
doc.Close();
Console.WriteLine($"SUCCESS: {outputPath}");Charts
Create and manage charts — pie, bar, line, column, area, scatter, surface, stock, radar, and more with customizable elements and formatting.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;
using Syncfusion.OfficeChart;Required usings for Cross-Platform
using Syncfusion.DocIORenderer;Required usings for Windows-Specific
using Syncfusion.OfficeChartToImageConverter;
using System;
using System.IO;Create Chart from Scratch
var doc = new WordDocument();
IWParagraph paragraph = doc.AddSection().AddParagraph();
WChart chart = paragraph.AppendChart(446, 270);
chart.ChartType = OfficeChartType.Pie;
chart.ChartTitle = "Best Selling Products";
chart.ChartTitleArea.FontName = "Calibri";
chart.ChartTitleArea.Size = 14;
chart.ChartData.SetValue(1, 1, "");
chart.ChartData.SetValue(1, 2, "Sales");
chart.ChartData.SetValue(2, 1, "Product A"); chart.ChartData.SetValue(2, 2, 141.396);
chart.ChartData.SetValue(3, 1, "Product B"); chart.ChartData.SetValue(3, 2, 80.368);
chart.ChartData.SetValue(4, 1, "Product C"); chart.ChartData.SetValue(4, 2, 71.155);
IOfficeChartSerie series = chart.Series.Add("Sales");
series.Values = chart.ChartData[2, 2, 4, 2];
chart.PrimaryCategoryAxis.CategoryLabels = chart.ChartData[2, 1, 4, 1];
series.DataPoints.DefaultDataPoint.DataLabels.IsValue = true;
series.DataPoints.DefaultDataPoint.DataLabels.Position = OfficeDataLabelPosition.Outside;Common code for Cross-Platform and Windows-Specific
Cross-Platform
chart.ChartArea.Fill.ForeColor = Syncfusion.Drawing.Color.FromArgb(242, 242, 242);Windows-Specific
chart.ChartArea.Fill.ForeColor = System.Drawing.Color.FromArgb(242, 242, 242);Common code for Cross-Platform and Windows-Specific
chart.ChartArea.Border.LinePattern = OfficeChartLinePattern.None;
doc.Save(outputPath);
doc.Close();Placeholders
{width}, {height}→ Chart dimensionsOfficeChartType.Pie→ Column_Clustered, Line, Bar_Clustered, Area, Scatter, Surface, Stock, Radar, Bubble, etc.
---
Create Chart from Excel
Common code for Cross-Platform and Windows-Specific
var doc = new WordDocument();
Stream excelStream = File.OpenRead("Excel_Template.xlsx");
WChart chart = doc.AddSection().AddParagraph().AppendChart(excelStream, 1, "B2:C6", 470, 300);
chart.ChartType = OfficeChartType.Column_Clustered;
chart.ChartTitle = "Purchase Details";
chart.Series[0].Name = "Sum of Purchases";
chart.Series[1].Name = "Sum of Future Expenses";
chart.PrimaryCategoryAxis.Title = "Products";
chart.PrimaryValueAxis.Title = "In Dollars";
chart.Legend.Position = OfficeLegendPosition.Bottom;
doc.Save(outputPath);
doc.Close();Placeholders
1→ Sheet index (1-based)"B2:C6"→ Data range
---
Create Custom Chart (Multiple Series Types)
Common code for Cross-Platform and Windows-Specific
var doc = new WordDocument();
object[][] data = new object[6][];
for (int i = 0; i < 6; i++) data[i] = new object[3];
data[0][0] = ""; data[0][1] = "Purchases"; data[0][2] = "Expenses";
data[1][0] = "Product A"; data[1][1] = 286; data[1][2] = 1300;
data[2][0] = "Product B"; data[2][1] = 680; data[2][2] = 700;
WChart chart = doc.AddSection().AddParagraph().AppendChart(data, 470, 300);
chart.ChartTitle = "Purchase Details";
chart.Series[0].SerieType = OfficeChartType.Line_Markers;
chart.Series[1].SerieType = OfficeChartType.Bar_Clustered;
chart.PrimaryCategoryAxis.Title = "Products";
chart.Legend.Position = OfficeLegendPosition.Bottom;
doc.Save(outputPath);
doc.Close();Placeholders
data→ Replace with your custom data array470, 300→ Chart dimensions (width, height)"Purchase Details"→ Replace with"{chart-title}"OfficeChartType.Line_Markers,OfficeChartType.Bar_Clustered→ Different chart types for each series
---
Modify Chart Data
Common code for Cross-Platform and Windows-Specific
FileStream fileStream = new FileStream("Template.docx", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var doc = new WordDocument(fileStream, FormatType.Docx);
WChart chart = doc.LastParagraph.ChildEntities[0] as WChart;
chart.ChartData.SetValue(2, 2, 120);
chart.ChartData.SetValue(3, 2, 60);
chart.Refresh();
doc.Save(outputPath);
doc.Close();Placeholders
"Template.docx"→ Replace with"{template-filename}"SetValue(2, 2, 120)→ Row, column, and new value to update
---
Refresh Chart
Common code for Cross-Platform and Windows-Specific
FileStream fileStream = new FileStream("Template.docx", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var doc = new WordDocument(fileStream, FormatType.Docx);
WChart chart = doc.LastParagraph.ChildEntities[0] as WChart;
chart.Refresh(false); // true evaluates Excel formulas, false refreshes data only
doc.Save(outputPath);
doc.Close();Placeholders
"Template.docx"→ Replace with"{template-filename}"Refresh(false)→trueevaluates Excel formulas,falserefreshes data only
---
Customize Chart Elements
// Title
chart.ChartTitle = "Sales Report";
chart.ChartTitleArea.FontName = "Calibri";
chart.ChartTitleArea.Size = 14;
// Chart Area and Plot AreaCross-Platform
chart.ChartArea.Fill.ForeColor = Syncfusion.Drawing.Color.WhiteSmoke;
chart.PlotArea.Fill.ForeColor = Syncfusion.Drawing.Color.WhiteSmoke;Windows-Specific
chart.ChartArea.Fill.ForeColor = System.Drawing.Color.WhiteSmoke;
chart.PlotArea.Fill.ForeColor = System.Drawing.Color.WhiteSmoke;Common code for Cross-Platform and Windows-Specific
chart.ChartArea.Border.LinePattern = OfficeChartLinePattern.Solid;
chart.PlotArea.Border.LinePattern = OfficeChartLinePattern.Solid;
// Legend
chart.HasLegend = true;
chart.Legend.Position = OfficeLegendPosition.Bottom; // Top, Right, Left
// Data Labels
IOfficeChartSerie series = chart.Series[0];
series.DataPoints.DefaultDataPoint.DataLabels.IsValue = true;
series.DataPoints.DefaultDataPoint.DataLabels.IsCategoryName = true;
series.DataPoints.DefaultDataPoint.DataLabels.Position = OfficeDataLabelPosition.Outside;
// Axes
chart.PrimaryCategoryAxis.Title = "Categories";
chart.PrimaryValueAxis.Title = "Values";
chart.PrimaryValueAxis.MinimumValue = 0;
chart.PrimaryValueAxis.MaximumValue = 1000;
chart.PrimaryValueAxis.MajorUnit = 100;Placeholders
"Sales Report"→ Replace with"{chart-title}""Calibri"→ Replace with"{font-name}"14→ Font size (in points)OfficeLegendPosition.Bottom→ Top, Right, Left, or BottomOfficeDataLabelPosition.Outside→ Inside, Center, or Outside"Categories","Values"→ Replace with axis titles0, 1000, 100→ Min value, max value, major unit
---
Format Chart Series
IOfficeChartSerie series = chart.Series[0];
series.Name = "Sales";
// Customize series borderCross-Platform
series.SerieFormat.LineProperties.LineColor = Syncfusion.Drawing.Color.Red;Windows-Specific
series.SerieFormat.LineProperties.LineColor = System.Drawing.Color.Red;Common code for Cross-Platform and Windows-Specific
series.SerieFormat.LineProperties.LinePattern = OfficeChartLinePattern.Dot;
series.SerieFormat.LineProperties.LineWeight = OfficeChartLineWeight.Hairline;
// Customize series fillCross-Platform
series.SerieFormat.Fill.ForeColor = Syncfusion.Drawing.Color.Blue;Windows-Specific
series.SerieFormat.Fill.ForeColor = System.Drawing.Color.Blue;Common code for Cross-Platform and Windows-Specific
series.SerieFormat.Fill.Transparency = 0.2;Placeholders
Series[0]→ Replace with series index (0-based)"Sales"→ Replace with"{series-name}"LineColor→ Use desired color (Syncfusion.Drawing.Color or System.Drawing.Color)OfficeChartLinePattern.Dot→ Solid, Dash, DashDot, DashDotDot, etc.OfficeChartLineWeight.Hairline→ Thin, Medium, Thick, etc.0.2→ Transparency value (0.0 to 1.0)
---
Add Data Table to Chart
WChart chart = doc.AddSection().AddParagraph().AppendChart(446, 270);
chart.ChartType = OfficeChartType.Column_Clustered;
chart.ChartData.SetValue(2, 1, "Item A"); chart.ChartData.SetValue(2, 2, 50);
chart.ChartData.SetValue(3, 1, "Item B"); chart.ChartData.SetValue(3, 2, 75);
chart.DataRange = chart.ChartData[1, 1, 3, 2];
chart.IsSeriesInRows = false; // Data is in columns (default)
chart.HasDataTable = true;
IOfficeChartDataTable dataTable = chart.DataTable;
dataTable.ShowSeriesKeys = true;
dataTable.HasBorders = true;Placeholders
446, 270→ Chart dimensions (width, height)OfficeChartType.Column_Clustered→ Chart type (Pie, Line, Bar_Clustered, etc.)"Item A","Item B"→ Replace with"{item-name}"50, 75→ Replace with numeric valuesShowSeriesKeys→ true to show series names, false to hideHasBorders→ true to display borders, false to hide
---
Create a Combo Chart (Two Chart Types)
Minimal Code
WChart chart = paragraph.AppendChart(446, 270);
chart.ChartType = OfficeChartType.Combination_Chart;
// Category labels
chart.ChartData.SetValue(1, 1, "Month");
chart.ChartData.SetValue(2, 1, "Jan");
chart.ChartData.SetValue(3, 1, "Feb");
// Primary axis
chart.ChartData.SetValue(1, 2, "Revenue");
chart.ChartData.SetValue(2, 2, 500);
chart.ChartData.SetValue(3, 2, 650);
// Secondary axis
chart.ChartData.SetValue(1, 3, "Growth %");
chart.ChartData.SetValue(2, 3, 0.1);
chart.ChartData.SetValue(3, 3, 0.15);
// Series 1 Clustered Column
IOfficeChartSerie serie1 = chart.Series.Add("Revenue");
serie1.Values = chart.ChartData[2, 2, 3, 2];
serie1.SerieType = OfficeChartType.Column_Clustered;
// Series 2 Line on secondary axis
IOfficeChartSerie serie2 = chart.Series.Add("Growth %");
serie2.Values = chart.ChartData[2, 3, 3, 3];
serie2.SerieType = OfficeChartType.Line;
serie2.UsePrimaryAxis = false; // Use secondary Y axisEnable Secondary Axis
chart.SecondaryCategoryAxis.Visible = true;
chart.SecondaryValueAxis.Visible = true;
chart.SecondaryValueAxis.Title = "Growth (%)";
chart.SecondaryValueAxis.NumberFormat = "0.0%";Placeholders
446, 270→ Chart dimensions (width, height)"Revenue","Growth %"→ Replace with"{series-name}"500, 0.1→ Replace with numeric valuesUsePrimaryAxis→ Set to false to plot the series on the secondary Y axisOfficeChartType.Column_ClusteredandOfficeChartType.Line→ Chart types used for each series (Column, Line, Bar_Clustered, etc.)
---
Apply 3D Formatting
Stream excelStream = File.OpenRead("Excel_Template.xlsx");
WChart chart = doc.AddSection().AddParagraph().AppendChart(excelStream, 1, "B2:C6", 470, 300);
chart.ChartType = OfficeChartType.Column_Clustered_3D;
chart.Rotation = 20;
chart.Elevation = 15;
// Side wallCommon code for Cross-Platform and Windows-Specific
chart.SideWall.Fill.FillType = OfficeFillType.SolidColor;Cross-Platform
chart.SideWall.Fill.ForeColor = Syncfusion.Drawing.Color.White;Windows-Specific
chart.SideWall.Fill.ForeColor = System.Drawing.Color.White;Common code for Cross-Platform and Windows-Specific
// Floor
chart.Floor.Fill.FillType = OfficeFillType.Pattern;
chart.Floor.Fill.Pattern = OfficeGradientPattern.Pat_Divot;Cross-Platform
chart.Floor.Fill.ForeColor = Syncfusion.Drawing.Color.Blue;Windows-Specific
chart.Floor.Fill.ForeColor = System.Drawing.Color.Blue;Common code for Cross-Platform and Windows-Specific
chart.Floor.Thickness = 3;
// Back wall
chart.BackWall.Fill.FillType = OfficeFillType.Gradient;
chart.BackWall.Fill.GradientColorType = OfficeGradientColor.TwoColor;Cross-Platform
chart.BackWall.Fill.ForeColor = Syncfusion.Drawing.Color.WhiteSmoke;Windows-Specific
chart.BackWall.Fill.ForeColor = System.Drawing.Color.WhiteSmoke;Cross-Platform
chart.BackWall.Fill.BackColor = Syncfusion.Drawing.Color.LightBlue;Windows-Specific
chart.BackWall.Fill.BackColor = System.Drawing.Color.LightBlue;Common code for Cross-Platform and Windows-Specific
chart.BackWall.Thickness = 10;
doc.Save(outputPath);
doc.Close();Placeholders
"Excel_Template.xlsx"→ Replace with"{excel-filename}"1→ Sheet index (1-based)"B2:C6"→ Data range470, 300→ Chart dimensions (width, height)OfficeChartType.Column_Clustered_3D→ 3D chart type (Pie_Exploded_3D, Bar_Clustered_3D, etc.)20, 15→ Rotation and elevation angles (in degrees)OfficeFillType.SolidColor,OfficeFillType.Pattern,OfficeFillType.Gradient→ Fill types3, 10→ Wall thickness values
---
Remove Chart
FileStream fileStream = new FileStream("Template.docx", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var doc = new WordDocument(fileStream, FormatType.Docx);
WParagraph paragraph = doc.LastParagraph;
foreach (ParagraphItem item in paragraph.ChildEntities)
{
if (item is WChart) { paragraph.ChildEntities.Remove(item); break; }
}
doc.Save(outputPath);
doc.Close();Placeholders
"Template.docx"→ Replace with"{template-filename}"doc.LastParagraph→ Replace with specific paragraph containing the chart
---
Convert Chart to Image
Cross-Platform
using (FileStream docStream = new FileStream("TemplateWithChart.docx", FileMode.Open))
{
using (WordDocument doc = new WordDocument(docStream, FormatType.Automatic))
{
WChart chart = doc.LastSection.Paragraphs[0].ChildEntities[0] as WChart;
using (DocIORenderer renderer = new DocIORenderer())
{
using (Stream imageStream = chart.SaveAsImage())
{
using (FileStream fileOutput = File.Create("ChartImage.jpeg"))
{
imageStream.CopyTo(fileOutput);
}
}
}
}
}Windows-Specific
//Loads an existing Word document.
WordDocument wordDocument = new WordDocument("TemplateWithChart.docx", FormatType.Docx);
//Initializes the ChartToImageConverter for converting charts during Word to image conversion.
wordDocument.ChartToImageConverter = new ChartToImageConverter();
//Sets the scaling mode for charts. (Normal mode reduces the file size)
wordDocument.ChartToImageConverter.ScalingMode = ScalingMode.Normal;
//Gets the first paragraph from section.
WParagraph paragraph = wordDocument.LastSection.Paragraphs[0];
//Gets the chart element in the paragarph item.
WChart chart = paragraph.ChildEntities[0] as WChart;
//Creating the memory stream for chart image.
MemoryStream stream = new MemoryStream();
//Converts chart to image.
wordDocument.ChartToImageConverter.SaveAsImage(chart.OfficeChart, stream);
Image image = Image.FromStream(stream);
//Dispose the stream.
stream.Close();
//Saving image stream to file.
image.Save("ChartToImage.jpeg", ImageFormat.Jpeg);
//Closes the document.
wordDocument.Close();Placeholders (Both Approaches)
"TemplateWithChart.docx"→ Replace with"{template-filename}"ScalingMode.Normal→ Normal or Best (Best quality increases file size)[0]→ Paragraph/chart index to retrieve"ChartImage.jpeg","ChartToImage.jpeg"→ Replace with"{output-image-filename}"ImageFormat.Jpeg→ Jpeg, Png, Bmp, or other formats- Cross-Platform approach uses
DocIORenderer(requires rendering dependencies) - Windows-Specific approach uses
ChartToImageConverter(Windows-only)
---
Comments
Add, modify, remove, and manage comments — insert comments on specific text, access parent comments, retrieve commented items.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Add Comment
Add a new comment to a paragraph with author information and timestamp.
Minimal Code
Common for Cross-Platform and Windows-Specific
var doc = new WordDocument();
doc.EnsureMinimal();
var para = doc.LastParagraph;
para.AppendText("This is sample text for comment.");
// Add comment to paragraph
WComment comment = para.AppendComment("This needs review");
// Set comment metadata
comment.Format.User = "Peter";
comment.Format.UserInitials = "PT";
comment.Format.DateTime = DateTime.Now;
// Save document
stream = new FileStream("output.docx", FileMode.Create, FileAccess.Write);
doc.Save(stream, FormatType.Docx);
stream.Dispose();
doc.Close();Placeholders
"This needs review"→ Replace with"{comment-text}""Peter"→ Replace with"{author-name}""PT"→ Replace with"{author-initials}""output.docx"→ Replace with"{output-file-path}"
---
Modify Comment
Change the text content of an existing comment.
Minimal Code
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
// Iterate through all comments
foreach (WComment comment in doc.Comments)
{
// Modify comment by author
if (comment.Format.User == "Peter")
{
comment.TextBody.LastParagraph.Text = "Updated comment text";
}
}
// Save modified document
var outputStream = new FileStream("output.docx", FileMode.Create, FileAccess.Write);
doc.Save(outputStream, FormatType.Docx);
outputStream.Dispose();
stream.Dispose();
doc.Close();Placeholders
"document.docx"→ Replace with"{input-file-path}""Peter"→ Replace with"{author-name}""Updated comment text"→ Replace with"{new-comment-text}""output.docx"→ Replace with"{output-file-path}"
---
Insert Comment on Specific Text
Find specific text and insert comments using regex pattern matching.
Minimal Code
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.ReadWrite);
var doc = new WordDocument(stream, FormatType.Docx);
// Find all text patterns ending with comma
TextSelection[] textSelections = doc.FindAll(new Regex("\\w+,"));
if (textSelections != null)
{
for (int i = 0; i < textSelections.Length; i++)
{
WTextRange textRange = textSelections[i].GetAsOneRange();
WParagraph paragraph = textRange.OwnerParagraph;
int textIndex = paragraph.ChildEntities.IndexOf(textRange);
// Add comment to paragraph
WComment comment = paragraph.AppendComment($"Review item {i + 1}");
comment.Format.User = "Peter";
comment.Format.UserInitials = "PT";
comment.Format.DateTime = DateTime.Now;
// Insert comment next to text
paragraph.ChildEntities.Insert(textIndex + 1, comment);
// Add text to commented items
comment.AddCommentedItem(textRange);
}
}
// Save document
var outputStream = new FileStream("output.docx", FileMode.Create, FileAccess.Write);
doc.Save(outputStream, FormatType.Docx);
outputStream.Dispose();
stream.Dispose();
doc.Close();Placeholders
"document.docx"→ Replace with"{input-file-path}""\\w+,"→ Replace with"{regex-pattern}""Peter"→ Replace with"{author-name}""Review item"→ Replace with"{comment-prefix}""output.docx"→ Replace with"{output-file-path}"
---
Remove All Comments
Remove all comments from a document.
Minimal Code
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
// Remove all comments from document
doc.Comments.Clear();
// Save modified document
var outputStream = new FileStream("output.docx", FileMode.Create, FileAccess.Write);
doc.Save(outputStream,FormatType.Docx);
outputStream.Dispose();
stream.Dispose();
doc.Close();Placeholders
"document.docx"→ Replace with"{input-file-path}""output.docx"→ Replace with"{output-file-path}"
---
Remove Specific Comment
Remove a particular comment by index.
Minimal Code
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
// Remove comment at index 1 (second comment)
if (doc.Comments.Count > 1)
{
doc.Comments.RemoveAt(1);
}
WComment comment = doc.Comments[3];
// Remove by instance
doc.Comments.Remove(comment);
// Save modified document
var outputStream = new FileStream("output.docx", FileMode.Create, FileAccess.Write);
doc.Save(outputStream, FormatType.Docx);
outputStream.Dispose();
stream.Dispose();
doc.Close();Placeholders
"document.docx"→ Replace with"{input-file-path}"1,3→ Replace with"{comment-index}""output.docx"→ Replace with"{output-file-path}"
---
Access Parent Comment
Get the parent comment of a reply comment using the Ancestor property.
Minimal Code
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
// Iterate through comments
foreach (WComment comment in doc.Comments)
{
// Get parent comment (ancestor)
WComment parentComment = comment.Ancestor;
if (parentComment != null)
{
Console.WriteLine($"Parent comment: {parentComment.TextBody.LastParagraph.Text}");
Console.WriteLine($"Reply: {comment.TextBody.LastParagraph.Text}");
}
else
{
Console.WriteLine($"This is a parent comment: {comment.TextBody.LastParagraph.Text}");
}
}
stream.Dispose();
doc.Close();Placeholders
"document.docx"→ Replace with"{input-file-path}"
---
Retrieve Commented Items
Get the paragraph items (text, images, etc.) that are within a comment.
Minimal Code
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
// Iterate through all comments
foreach (WComment comment in doc.Comments)
{
// Get the text of the comment
string commentText = comment.TextBody.LastParagraph.Text;
// Get paragraph items within comment
ParagraphItemCollection commentedItems = comment.CommentedItems;
if (commentedItems.Count > 0)
{
Console.WriteLine($"Comment: {commentText}");
Console.WriteLine($"Commented items count: {commentedItems.Count}");
// Access individual items
foreach (IParagraphItem item in commentedItems)
{
if (item is WTextRange textRange)
{
Console.WriteLine($"Commented text: {textRange.Text}");
}
}
}
}
stream.Dispose();
doc.Close();Placeholders
"document.docx"→ Replace with"{input-file-path}"
---
Remove or Replace Commented Items
Remove or replace the paragraph items (text, images, etc.) that are within a comment.
Remove Commented Items
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
// Iterate through comments
foreach (WComment comment in doc.Comments)
{
// Remove all items associated with the comment
comment.RemoveCommentedItems();
}
// Save document
var outputStream = new FileStream("output.docx", FileMode.Create, FileAccess.Write);
doc.Save(outputStream, FormatType.Docx);
outputStream.Dispose();
stream.Dispose();
doc.Close();Replace Commented Items using TextBodyPart
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
// Create replacement content
TextBodyPart replacementPart = new TextBodyPart(doc);
WParagraph para = replacementPart.AddParagraph();
para.AppendText("Updated content for the comment.");
// Replace commented items
foreach (WComment comment in doc.Comments)
{
comment.ReplaceCommentedItems(replacementPart);
}
// Save document
var outputStream = new FileStream("output.docx", FileMode.Create, FileAccess.Write);
doc.Save(outputStream, FormatType.Docx);
outputStream.Dispose();
stream.Dispose();
doc.Close();Replace Commented Items using String
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
// Replace commented items with plain text
foreach (WComment comment in doc.Comments)
{
comment.ReplaceCommentedItems("This content has been replaced.");
}
// Save document
var outputStream = new FileStream("output.docx", FileMode.Create, FileAccess.Write);
doc.Save(outputStream, FormatType.Docx);
outputStream.Dispose();
stream.Dispose();
doc.Close();Placeholders
document.docx→ Replace with{input-file-path}Updated content for the comment.andThis content has been replaced.→ Replace with{replacement-text}output.docx→ Replace with{output-file-path}
---
List All Comments
Retrieve and display all comments in a document with metadata.
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
Console.WriteLine($"Total comments: {doc.Comments.Count}");
// Iterate through all comments
for (int i = 0; i < doc.Comments.Count; i++)
{
WComment comment = doc.Comments[i];
Console.WriteLine($"\n--- Comment {i + 1} ---");
Console.WriteLine($"Author: {comment.Format.User}");
Console.WriteLine($"Initials: {comment.Format.UserInitials}");
Console.WriteLine($"Date: {comment.Format.DateTime}");
Console.WriteLine($"Text: {comment.TextBody.LastParagraph.Text}");
Console.WriteLine($"Resolved: {comment.Done}");
// Check if it's a reply
WComment parent = comment.Ancestor;
if (parent != null)
{
Console.WriteLine($"Reply to: {parent.TextBody.LastParagraph.Text}");
}
}
stream.Dispose();
doc.Close();Placeholders
"document.docx"→ Replace with"{input-file-path}"
---
Edit Comment by Author
Find and modify all comments by a specific author.
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("document.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
string targetAuthor = "Peter";
string newText = "Action required";
// Find and modify comments by author
foreach (WComment comment in doc.Comments)
{
if (comment.Format.User == targetAuthor)
{
comment.TextBody.LastParagraph.Text = newText;
comment.Format.DateTime = DateTime.Now;
}
}
// Save modified document
var outputStream = new FileStream("output.docx", FileMode.Create, FileAccess.Write);
doc.Save(outputStream, FormatType.Docx);
outputStream.Dispose();
stream.Dispose();
doc.Close();Placeholders
"document.docx"→ Replace with"{input-file-path}""Peter"→ Replace with"{target-author}""Action required"→ Replace with"{new-comment-text}""output.docx"→ Replace with"{output-file-path}"
Compare Word Documents
Word document comparison — comparing two Word documents, tracking insertions and deletions, setting author and date information, and customizing comparison options to ignore format changes.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Compare Two Word Documents
Minimal Code
Cross-Platform
// Load the original document
using (FileStream originalStream = new FileStream("OriginalDocument.docx", FileMode.Open, FileAccess.Read))
{
using (WordDocument originalDocument = new WordDocument(originalStream, FormatType.Docx))
{
// Load the revised document
using (FileStream revisedStream = new FileStream("RevisedDocument.docx", FileMode.Open, FileAccess.Read))
{
using (WordDocument revisedDocument = new WordDocument(revisedStream, FormatType.Docx))
{
// Compare the original and revised documents
originalDocument.Compare(revisedDocument);
// Save the result
var outputPath = Path.Combine(Directory.GetCurrentDirectory(), "output", "Comparison.docx");
using (FileStream outStream = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite))
{
originalDocument.Save(outStream, FormatType.Docx);
}
}
}
}
}Windows-Specific
//Load the original document.
using (WordDocument originalDocument = new WordDocument("Data/OriginalDocument.docx", FormatType.Docx))
{
//Load the revised document.
using (WordDocument revisedDocument = new WordDocument("Data/RevisedDocument.docx", FormatType.Docx))
{
// Compare the original and revised Word documents.
originalDocument.Compare(revisedDocument);
//Save the Word document.
originalDocument.Save("Comparison.docx");
}
}Changes Tracked
- Insertions: Content added in the revised document
- Deletions: Content removed from the original document
- Formatting: Style and formatting modifications
Notes
- DocIO performs word-level comparison—if a single character in a word is changed, the entire word is highlighted as changed
- Comparison is supported in DOCX format only
- Default author:
"Author" - Default date: Current system time
Placeholders
"OriginalDocument.docx"→ Replace with"{original-file-path}""RevisedDocument.docx"→ Replace with"{revised-file-path}""Comparison.docx"→ Replace with"{output-file-path}"
---
Set Author and Date
Minimal
Common for Cross-Platform and Windows-Specific
// Load the original document
using (FileStream originalStream = new FileStream("OriginalDocument.docx", FileMode.Open, FileAccess.Read))
{
using (WordDocument originalDocument = new WordDocument(originalStream, FormatType.Docx))
{
// Load the revised document
using (FileStream revisedStream = new FileStream("RevisedDocument.docx", FileMode.Open, FileAccess.Read))
{
using (WordDocument revisedDocument = new WordDocument(revisedStream, FormatType.Docx))
{
// Compare with custom author and date
originalDocument.Compare(revisedDocument, "Nancy Davolio", DateTime.Now.AddDays(-1));
// Save the result
var outputPath = Path.Combine(Directory.GetCurrentDirectory(), "output", "Comparison.docx");
using (FileStream outStream = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite))
{
originalDocument.Save(outStream, FormatType.Docx);
}
}
}
}
}Method Signature
Common for Cross-Platform and Windows-Specific
public void Compare(WordDocument revisedDocument, string author, DateTime dateTime)Parameters
revisedDocument: The document to compare against the originalauthor: Name of the person making the revision (default:"Author")dateTime: Timestamp of the revision (default: current time)
Placeholders
"Nancy Davolio"→ Replace with"{author-name}"DateTime.Now.AddDays(-1)→ Replace with"{revision-date}"
---
Comparison Options
Overview
Customize word comparison behavior using the ComparisonOptions class to control how DocIO identifies and tracks changes between documents.
Available Options
| Option | Type | Default | Description |
|---|---|---|---|
DetectFormatChanges | bool | true | Track formatting changes (font, color, size, style, etc.) |
---
Ignore Format Changes
Minimal Code
Common for Cross-Platform and Windows-Specific
// Load the original document
using (FileStream originalStream = new FileStream("OriginalDocument.docx", FileMode.Open, FileAccess.Read))
{
using (WordDocument originalDocument = new WordDocument(originalStream, FormatType.Docx))
{
// Load the revised document
using (FileStream revisedStream = new FileStream("RevisedDocument.docx", FileMode.Open, FileAccess.Read))
{
using (WordDocument revisedDocument = new WordDocument(revisedStream, FormatType.Docx))
{
// Create comparison options to ignore formatting changes
ComparisonOptions compareOptions = new ComparisonOptions();
compareOptions.DetectFormatChanges = false;
// Compare with options
originalDocument.Compare(revisedDocument, "Syncfusion", DateTime.Now, compareOptions);
// Save the result
var outputPath = Path.Combine(Directory.GetCurrentDirectory(), "output", "Comparison.docx");
using (FileStream outStream = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite))
{
originalDocument.Save(outStream, FormatType.Docx);
}
}
}
}
}When to Use
- Compare documents where only content changes matter
- Ignore style, color, font, and formatting modifications
- Focus on substantive content edits (insertions, deletions)
Behavior
- With
DetectFormatChanges = true(default): All formatting differences are tracked - With
DetectFormatChanges = false: Only content changes are tracked
Placeholders
compareOptions.DetectFormatChanges = false→ Set totrueto track format changes
---
Complete Example
Full Workflow
Common for Cross-Platform and Windows-Specific
// Load original document
using (FileStream originalStream = new FileStream("OriginalDocument.docx", FileMode.Open, FileAccess.Read))
{
using (WordDocument originalDocument = new WordDocument(originalStream, FormatType.Docx))
{
// Load revised document
using (FileStream revisedStream = new FileStream("RevisedDocument.docx", FileMode.Open, FileAccess.Read))
{
using (WordDocument revisedDocument = new WordDocument(revisedStream, FormatType.Docx))
{
// Set comparison options
ComparisonOptions compareOptions = new ComparisonOptions();
compareOptions.DetectFormatChanges = true; // Track all changes
// Compare with author, date, and options
originalDocument.Compare(
revisedDocument,
"John Smith",
DateTime.Now,
compareOptions
);
// Save comparison result
var outputPath = Path.Combine(Directory.GetCurrentDirectory(), "output", "ComparisonResult.docx");
using (FileStream outStream = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite))
{
originalDocument.Save(outStream, FormatType.Docx);
}
Console.WriteLine($"Comparison complete. Result saved to {outputPath}");
}
}
}
}---
Common Properties
| Property | Type | Description |
|---|---|---|
Compare() | Method | Compares two Word documents and tracks changes |
ComparisonOptions | Class | Encapsulates customization options for document comparison |
DetectFormatChanges | bool | Controls whether formatting changes are detected and tracked |
---
Content Controls
Content controls — block and inline content controls, types (rich text, plain text, checkbox, date picker, dropdown, picture), properties, protection, form filling, XML mapping.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Block Content Control
Add Block Content Control
WordDocument document = new WordDocument();
IWSection section = document.AddSection();
WTextBody textBody = section.Body;
// Add block content control
BlockContentControl blockControl = textBody.AddBlockContentControl(ContentControlType.RichText) as BlockContentControl;
//Sets title of the block content control.
blockControl.ContentControlProperties.Title = "Rich text content control";
// Add paragraph
WParagraph para = blockControl.TextBody.AddParagraph() as WParagraph;
para.AppendText("Block content control content");
// Add table
WTable table = blockControl.TextBody.AddTable() as WTable;
table.ResetCells(2, 3);
// Add image
// Cross-Platform
FileStream imageStream = new FileStream("image.png", FileMode.Open, FileAccess.Read);
// Common for Cross-Platform and Windows-Specific
WParagraph imagePara = blockControl.TextBody.AddParagraph() as WParagraph;
// Cross-Platform
imagePara.AppendPicture(imageStream);
// Windows-Specific
imagePara.AppendPicture(Image.FromFile("Image.png"));Find and Replace Content inside Block Content Control
Find first occurrence using string
// Add block content control
BlockContentControl blockControl = textBody.AddBlockContentControl(ContentControlType.RichText) as BlockContentControl;
// Add paragraph
WParagraph para = blockControl.TextBody.AddParagraph() as WParagraph;
para.AppendText("{Block-content-control-content}");
TextSelection sel = blockControl.Find("{find-text}", caseSensitive: false, wholeWord: true);
if (sel != null)
{
WTextRange r = sel.GetAsOneRange();
r.Text = "{new-text}"; // optional inline replace
}Find first occurrence using Regex
var sel = blockControl.Find(new System.Text.RegularExpressions.Regex(@"{pattern}"));Replace all occurrences (string → string)
blockControl.Replace("{find-text}", "{replace-text}", caseSensitive: false, wholeWord: false);Replace all occurrences (Regex → string)
blockControl.Replace(new System.Text.RegularExpressions.Regex(@"{pattern}"), "{replace-text}");Replace using selected content (keeps formatting)
TextSelection replacement = blockControl.Find(new System.Text.RegularExpressions.Regex(@"{replacement-pattern}"));
if (replacement != null)
blockControl.Replace("{find-text}", replacement, caseSensitive: false, wholeWord: false, saveFormatting: true);---
Inline Content Control
Add Inline Content Control
WordDocument document = new WordDocument();
document.EnsureMinimal();
WParagraph paragraph = document.LastParagraph;
paragraph.AppendText("Text before control ");
// Add inline content control
InlineContentControl inlineControl = paragraph.AppendInlineContentControl(ContentControlType.RichText) as InlineContentControl;
WTextRange textRange = new WTextRange(document);
textRange.Text = "Inline content control text";
inlineControl.ParagraphItems.Add(textRange);---
Content Control Types
Rich Text
InlineContentControl richText = para.AppendInlineContentControl(ContentControlType.RichText) as InlineContentControl;
WTextRange text = new WTextRange(document);
text.Text = "Rich text content";
richText.ParagraphItems.Add(text);
// Can contain text, images, tables
WPicture picture = new WPicture(document);
// Cross-Platform
picture.LoadImage(new FileStream("image.png", FileMode.Open));
// Windows-Specific
picture.LoadImage(Image.FromFile("Image.png"));
richText.ParagraphItems.Add(picture);Plain Text
InlineContentControl plainText = para.AppendInlineContentControl(ContentControlType.Text) as InlineContentControl;
WTextRange text = new WTextRange(document);
text.Text = "Plain text only";
plainText.ParagraphItems.Add(text);
//Enables multiline for plain text control.
plainText.ContentControlProperties.Multiline = true;Check Box
InlineContentControl checkbox = para.AppendInlineContentControl(ContentControlType.CheckBox) as InlineContentControl;
checkbox.ContentControlProperties.IsChecked = true;Apply checkbox state properties
InlineContentControl checkbox = para.AppendInlineContentControl(ContentControlType.CheckBox) as InlineContentControl;
//Get checked state of checkbox
CheckBoxState checkBoxCheckedState = checkBox.ContentControlProperties.CheckedState;
//Set font for checked state value
checkBoxCheckedState.Font = "Calibri";
//Set symbol for checked state value
checkBoxCheckedState.Value = "C";
//Get unchecked state of checkbox
CheckBoxState checkBoxUncheckedState = checkBox.ContentControlProperties.UncheckedState;
//Set font for unchecked state value
checkBoxUncheckedState.Font = "Calibri";
//Set symbol for unchecked state value
checkBoxUncheckedState.Value = "U";
//Set the state for checkbox
checkBox.ContentControlProperties.IsChecked = true;Placeholders
"Calibri"→ Replace with{font-name}CandU→ Replace with{checked-state-value}and{unchecked-state-value}
Date Picker
InlineContentControl datePicker = para.AppendInlineContentControl(ContentControlType.Date) as InlineContentControl;
WTextRange text = new WTextRange(document);
text.Text = DateTime.Now.ToString();
datePicker.ParagraphItems.Add(text);
datePicker.ContentControlProperties.DateCalendarType = CalendarType.Gregorian;
datePicker.ContentControlProperties.DateDisplayFormat = "M/d/yyyy";
datePicker.ContentControlProperties.DateDisplayLocale = LocaleIDs.en_US;
//Sets the storage format used in document XML.
datePicker.ContentControlProperties.DateStorageFormat = ContentControlDateStorageFormat.DateStorageDate;DateStorageFormat Options
- DateStorageDate — Stores only the date value in the document XML
- DateStorageDateTime — Stores both the date and time value in the document XML
- DateStorageText — Stores the value as plain text in the document XML
Dropdown List
InlineContentControl dropdown = para.AppendInlineContentControl(ContentControlType.DropDownList) as InlineContentControl;
WTextRange text = new WTextRange(document);
text.Text = "Choose an item";
dropdown.ParagraphItems.Add(text);
ContentControlListItem item = new ContentControlListItem();
item.DisplayText = "Option 1";
item.Value = "1";
dropdown.ContentControlProperties.ContentControlListItems.Add(item);
item = new ContentControlListItem();
item.DisplayText = "Option 2";
item.Value = "2";
dropdown.ContentControlProperties.ContentControlListItems.Add(item);Combo Box
InlineContentControl comboBox = para.AppendInlineContentControl(ContentControlType.ComboBox) as InlineContentControl;
// Similar to dropdown but allows custom values
ContentControlListItem item = new ContentControlListItem();
item.DisplayText = "Predefined 1";
item.Value = "1";
comboBox.ContentControlProperties.ContentControlListItems.Add(item);Picture
InlineContentControl pictureControl = para.AppendInlineContentControl(ContentControlType.Picture) as InlineContentControl;
WPicture picture = new WPicture(document);
// Cross-Platform
picture.LoadImage(new FileStream("image.png", FileMode.Open));
// Windows-Specific
picture.LoadImage(Image.FromFile("Image.png"));
pictureControl.ParagraphItems.Add(picture);---
Content Control Properties
Set Common Properties
InlineContentControl control = para.AppendInlineContentControl(ContentControlType.RichText) as InlineContentControl;
// Set appearance
control.ContentControlProperties.Appearance = ContentControlAppearance.BoundingBox;
// Set title and tag
control.ContentControlProperties.Title = "MyControl";
control.ContentControlProperties.Tag = "ControlTag";
// Set color
// Cross-Platform
control.ContentControlProperties.Color = Syncfusion.Drawing.Color.Blue;
// Cross-Platform
control.ContentControlProperties.Color = System.Drawing.Color.Blue;
// Lock/protect
control.ContentControlProperties.LockContentControl = true; // Prevent deletion
control.ContentControlProperties.LockContents = true; // Prevent editing
control.ContentControlProperties.IsTemporary = false; // Remove on edit
// Get control type
ContentControlType type = control.ContentControlProperties.Type;
// Check whether the placeholder text for the content control is displayed or not
bool hasPlaceholder = control.ContentControlProperties.HasPlaceHolderText;Appearance Options
- BoundingBox — Display within a box
- Tags — Display within tags
- Hidden — Display without box or tags
---
Protect Content Control
Lock Content for Protection
Common for Cross-Platform and Windows-Specific
InlineContentControl control = para.AppendInlineContentControl(ContentControlType.RichText) as InlineContentControl;
WTextRange text = new WTextRange(document);
text.Text = "Protected content";
control.ParagraphItems.Add(text);
// Prevent editing
control.ContentControlProperties.LockContents = true;
// Prevent deletion
control.ContentControlProperties.LockContentControl = true;
control.ContentControlProperties.Title = "Protected";
control.ContentControlProperties.Tag = "ReadOnly";---
XML Mapping (Data Binding)
Map Content Control to XML
WordDocument document = new WordDocument();
IWSection section = document.AddSection();
IWParagraph para = section.AddParagraph();
// Add custom XML part
CustomXMLPart xmlPart = new CustomXMLPart(document);
xmlPart.LoadXML(@"<data><name>John Doe</name><email>john@example.com</email></data>");
// Add content control with XML mapping
para.AppendText("Name: ");
InlineContentControl control = para.AppendInlineContentControl(ContentControlType.Text) as InlineContentControl;
control.ContentControlProperties.XmlMapping.SetMapping("/data/name", "", xmlPart);
// Map by node
para = section.AddParagraph();
para.AppendText("Email: ");
control = para.AppendInlineContentControl(ContentControlType.Text) as InlineContentControl;
CustomXMLNode node = xmlPart.SelectSingleNode("/data/email");
control.ContentControlProperties.XmlMapping.SetMappingByNode(node);---
Edit Content Control
Modify Inline Content Control Text
// Iterate paragraphs to find and edit content control
foreach (WSection section in document.Sections)
{
IterateTextBody(section.Body);
}
private static void IterateTextBody(WTextBody textBody)
{
for (int i = 0; i < textBody.ChildEntities.Count; i++)
{
IEntity entity = textBody.ChildEntities[i];
if (entity.EntityType == EntityType.Paragraph)
{
WParagraph para = entity as WParagraph;
IterateParagraph(para.Items);
}
else if (entity.EntityType == EntityType.Table)
IterateTable(entity as WTable);
else if (entity.EntityType == EntityType.BlockContentControl)
IterateTextBody((entity as BlockContentControl).TextBody);
}
}
private static void IterateParagraph(ParagraphItemCollection items)
{
for (int i = 0; i < items.Count; i++)
{
Entity item = items[i];
if (item.EntityType == EntityType.InlineContentControl)
{
InlineContentControl control = item as InlineContentControl;
if (control.ContentControlProperties.Title == "TargetControl")
EditContentControl(control, "New Text");
}
}
}
private static void EditContentControl(InlineContentControl control, string newText)
{
WCharacterFormat charFormat = null;
foreach (ParagraphItem item in control.ParagraphItems)
{
if (item is WTextRange)
{
charFormat = (item as WTextRange).CharacterFormat;
break;
}
}
control.ParagraphItems.Clear();
WTextRange textRange = new WTextRange(control.Document);
textRange.Text = newText;
if (charFormat != null)
textRange.ApplyCharacterFormat(charFormat);
control.ParagraphItems.Add(textRange);
}
private static void IterateTable(WTable table)
{
foreach (WTableRow row in table.Rows)
foreach (WTableCell cell in row.Cells)
IterateTextBody(cell);
}---
Placeholders
"input.docx"→ Replace with actual document path"output.docx"→ Replace with desired output file name"image.png"→ Replace with actual image file path"/data/name"→ Replace with actual XPath for XML mapping"TargetControl"→ Replace with actual content control title to find/edit- Content control properties depend on control type (some only available for specific types)
---
Important Notes
- Content controls only work in Open XML format (DOCX, not DOC)
- Block content controls exist at body level; inline at paragraph level
- Protect document properties before saving to enforce lock
- XML mapping enables two-way data binding
- RowContentControl and CellContentControl not currently supported
Document Structure
Document lifecycle & page layout — creating, loading, saving, closing documents and configuring sections.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Create Document
Minimal Code
Common for Cross-Platform and Windows-Specific
var outputPath = Path.Combine(Directory.GetCurrentDirectory(), "output", "document.docx");
var doc = new WordDocument();
var section = doc.AddSection();
section.PageSetup.Margins.All = 72f; // 1 inch margins
// Add content here
doc.Save(outputPath);
doc.Close();
Console.WriteLine($"SUCCESS: {outputPath}");Placeholders
"document.docx"→ Replace with"{filename}.docx"- Add content operations between section creation and save
---
Add Section
Minimal Code
Common for Cross-Platform and Windows-Specific
var section = doc.AddSection();
section.PageSetup.Margins.All = 72f; // 1 inch marginsOptions
Common for Cross-Platform and Windows-Specific
// Custom margins
section.PageSetup.Margins.Top = 72f;
section.PageSetup.Margins.Bottom = 72f;
section.PageSetup.Margins.Left = 72f;
section.PageSetup.Margins.Right = 72f;
// Page orientation
section.PageSetup.Orientation = PageOrientation.Portrait; // or Landscape---
Load Document
From File Path
Common for Cross-Platform and Windows-Specific (Using Constructor)
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "input", "template.docx");
var doc = new WordDocument(filePath);Common for Cross-Platform and Windows-Specific (Using Open Method)
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "input", "template.docx");
var doc = new WordDocument();
doc.Open(filePath);From Stream
Common for Cross-Platform and Windows-Specific (Using Constructor)
var fileStream = new FileStream("template.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(fileStream, FormatType.Automatic);Common for Cross-Platform and Windows-Specific (Using Open Method)
var fileStream = new FileStream("template.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument();
doc.Open(fileStream, FormatType.Automatic);Encrypted Document
Common for Cross-Platform and Windows-Specific (From File Path)
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "input", "encrypted.docx");
var doc = new WordDocument(filePath, FormatType.Automatic, "password");Common for Cross-Platform and Windows-Specific (From Stream)
var fileStream = new FileStream("encrypted.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(fileStream, FormatType.Automatic, "password");Read-Only Document
Common for Cross-Platform and Windows-Specific (From File Path)
var doc = new WordDocument();
doc.OpenReadOnly("template.docx", FormatType.Docx);Common for Cross-Platform and Windows-Specific (Encrypted Read-Only Document)
var doc = new WordDocument();
doc.OpenReadOnly("template.docx", FormatType.Docx, "password");Placeholders
"template.docx"→ Replace with"{filename}.docx""password"→ Replace with actual passwordFormatType.Automatic→ Auto-detects format; or useFormatType.Docx,FormatType.Doc,FormatType.Rtf, etc.
---
Save Document
To File Path
Common for Cross-Platform and Windows-Specific
var outputPath = Path.Combine(Directory.GetCurrentDirectory(), "output", "document.docx");
doc.Save(outputPath, FormatType.Docx);
doc.Close();To Stream
Common for Cross-Platform and Windows-Specific
var stream = new MemoryStream();
doc.Save(stream, FormatType.Docx);
stream.Position = 0;Supported Formats
Common for Cross-Platform and Windows-Specific
FormatType.Docx // Word 2007+ (.docx) - recommended
FormatType.Doc // Word 97-2003 (.doc)
FormatType.Rtf // Rich Text Format (.rtf)
FormatType.Html // HTML format
FormatType.Markdown // Markdown format
FormatType.Txt // Plain textPlaceholders
"document.docx"→ Replace with"{output-filename}"FormatType.Docx→ Replace with desired format type
Encryption & Document Protection
Encrypt with password, open encrypted documents, remove encryption, restrict editing, and manage editable ranges.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Encrypt Document
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("input.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Automatic);
doc.EncryptDocument("password");
doc.Save(outputPath);
stream.Close();
doc.Close();Placeholders
"password"→ Replace with"{encryption-password}"
---
Open Encrypted Document
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("encrypted.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, "password");
doc.Save(outputPath);
stream.Close();
doc.Close();Placeholders
"password"→ Replace with"{decryption-password}"
---
Remove Encryption
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("encrypted.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx, "password");
doc.RemoveEncryption();
doc.Save(outputPath);
stream.Close();
doc.Close();Placeholders
"password"→ Replace with"{existing-password}"
---
Protect Document from Editing
Restricts editing to a specific type. Pass "" as password for no-password protection.
Common for Cross-Platform and Windows-Specific
var stream = new FileStream("input.docx", FileMode.Open, FileAccess.Read);
var doc = new WordDocument(stream, FormatType.Docx);
// ProtectionType options:
// AllowOnlyComments – only comments can be added/modified
// AllowOnlyFormFields – only form field values can be changed
// AllowOnlyRevisions – only tracked changes allowed
// AllowOnlyReading – read-only; no edits
// NoProtection – removes all protection
doc.Protect(ProtectionType.AllowOnlyFormFields, "password");
// Optional: Gets the current protection type applied to the document
ProtectionType protectionType = doc.ProtectionType;
doc.Save(outputPath);
stream.Close();
doc.Close();Placeholders
ProtectionType.AllowOnlyFormFields→ Replace with desiredProtectionType"password"→ Replace with"{protection-password}"or""for no password
---
Add Editable Range (within protected document)
Allows a specific portion to remain editable when the rest is read-only.
Minimal Code
Common for Cross-Platform and Windows-Specific
var doc = new WordDocument();
doc.EnsureMinimal();
var para = doc.LastParagraph as WParagraph;
para.AppendText("Protected text. ");
var rangeStart = para.AppendEditableRangeStart();
// Optional: restrict to a group or single user
// rangeStart.EditorGroup = EditorType.Everyone;
// rangeStart.SingleUser = "user@domain.com";
para.AppendText("Editable text.");
var rangeEnd = para.AppendEditableRangeEnd(rangeStart);
doc.Protect(ProtectionType.AllowOnlyReading, "password");
doc.Save(outputPath);
doc.Close();Add Editable Range inside Table
Common for Cross-Platform and Windows-Specific
var doc = new WordDocument();
doc.EnsureMinimal();
WTable table = doc.LastSection.AddTable() as WTable;
table.ResetCells(2, 3);
// Add text and start the editable range at column 1
table[0, 1].AddParagraph().AppendText("Editable content");
EditableRangeStart rangeStart = table[0, 1].Paragraphs[0].AppendEditableRangeStart();
rangeStart.FirstColumn = 1;
// Add content inside the editable range
table[1, 2].AddParagraph().AppendText("Editable Content");
// End the editable range at column 2
EditableRangeEnd rangeEnd = table[1, 2].Paragraphs[0].AppendEditableRangeEnd();
rangeStart.LastColumn = 2;
doc.Protect(ProtectionType.AllowOnlyReading, "password");
doc.Save(outputPath);
doc.Close();Editable Range Start and End Options
Common for Cross-Platform and Windows-Specific
rangeStart.EditorGroup = EditorType.Everyone; // group permission
rangeStart.SingleUser = "user@domain.com"; // single-user permission (mutually exclusive with EditorGroup)
string rangeStartId = rangeStart.Id; // ID of the editable range start
string rangeEndId = rangeEnd.Id; // ID of the editable range end
// Restrict the editable range to specific table columns (zero-based)
// Applicable only when the editable range is defined within a table
rangeStart.FirstColumn = 1;
rangeStart.LastColumn = 2;
Editable Range Properties (EditableRange)
Common for Cross-Platform and Windows-Specific
doc.EditableRanges[0].EditorGroup = EditorType.Everyone; // group permission
doc.EditableRanges[0].SingleUser = "user@domain.com"; // single-user permission (mutually exclusive with EditorGroup)
string editableRangeId = doc.EditableRanges[0].Id; // ID of the editable range
EditableRangeStart rangeStart = doc.EditableRanges[0].EditableRangeStart; // Get editable range start marker
EditableRangeEnd rangeEnd = doc.EditableRanges[0].EditableRangeEnd; // Get editable range end marker
document.EditableRanges[0].FirstColumn = 1; // First editable column
document.EditableRanges[0].LastColumn = 2; // Last editable column---
Find & Remove Editable Range
Common for Cross-Platform and Windows-Specific
// Find by Id
var range = doc.EditableRanges.FindById("0");
// Remove by instance
doc.EditableRanges.Remove(range);
// Remove by index
doc.EditableRanges.RemoveAt(0);Fields
DocIO snippets for working with Word fields — inserting, formatting, updating, and retrieving dynamic content.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Cross-Platform
using Syncfusion.DocIORenderer;---
Add Merge Field
Minimal Code
Common for Cross-Platform and Windows-Specific
var para = section.AddParagraph();
para.AppendText("Name: ");
para.AppendField("Name", FieldType.FieldMergeField);---
Add Date Field
Minimal Code
Common for Cross-Platform and Windows-Specific
var para = section.AddParagraph();
var field = para.AppendField("Date", FieldType.FieldDate);
field.FieldCode = @"DATE \@" + "\"MMMM d, yyyy\""; ---
Add Page Number Field
Minimal Code
Common for Cross-Platform and Windows-Specific
var footer = section.HeadersFooters.Footer.AddParagraph();
footer.AppendText("Page ");
footer.AppendField("Page", FieldType.FieldPage);
footer.AppendText(" of ");
footer.AppendField("NumPages", FieldType.FieldNumPages);---
Updating Fields
Minimal Code
Cross-Platform
using Syncfusion.DocIORenderer;
doc.UpdateDocumentFields(true);Windows-Specific
doc.UpdateDocumentFields();---
IF Field (Conditional Field)
Minimal Code
Common for Cross-Platform and Windows-Specific
var field = section.AddParagraph()
.AppendField("If", FieldType.FieldIf) as WIfField;
field.FieldCode = "IF 100 >= 1000 \"The given statement is Correct\" \"The given statement is Wrong\"";
doc.UpdateDocumentFields();---
SEQ Field (Sequence Field)
Minimal Code
Common for Cross-Platform and Windows-Specific
var field = section.AddParagraph()
.AppendField("SEQ", FieldType.FieldSequence);
field.FieldCode = "SEQ Item \\* ARABIC";
doc.UpdateDocumentFields();Multiple Sequence
Common for Cross-Platform and Windows-Specific
for (int i = 0; i < 3; i++)
{
var para = section.AddParagraph();
para.AppendText("Item ");
var field = para.AppendField("SEQ", FieldType.FieldSequence);
field.FieldCode = "SEQ Item \\* ARABIC";
}
doc.UpdateDocumentFields();Sequence Options
Common for Cross-Platform and Windows-Specific
WSeqField field = (WSeqField)section.AddParagraph().AppendField("SEQ", FieldType.FieldSequence);
//Set the RepeatNearestNumber of the SeqField.
field.RepeatNearestNumber = true;
//Set the ResetNumber of the SeqField.
field.ResetNumber = 7;
//Set the NumberFormat of the SeqField.
field.NumberFormat = CaptionNumberingFormat.Number;
//Set the BookmarkName of the SeqField.
field.BookmarkName = "Bookmark1";
//Set the HideResult of the SeqField.
field.HideResult = true;
//Set the InsertNextNumber of the SeqField.
field.InsertNextNumber = true;
doc.UpdateDocumentFields();---
Document variables
Minimal Code
Common for Cross-Platform and Windows-Specific
var para = section.AddParagraph();
//Adds the DocVariable field with Variable name and its type
para.AppendField("FirstName", FieldType.FieldDocVariable);
para = section.AddParagraph();
//Adds the DocVariable field with Variable name and its type
para.AppendField("LastName", FieldType.FieldDocVariable);
//Adds the value for variable in WordDocument.Variable collection
doc.Variables.Add("FirstName", "Jeff");
doc.Variables.Add("LastName", "Smith");
//Updates the document fields
doc.UpdateDocumentFields();---
Cross Reference Field (Bookmark)
Minimal Code
Common for Cross-Platform and Windows-Specific
IWSection section = doc.AddSection();
//Adds a new paragraph into Word document
IWParagraph paragraph = section.AddParagraph();
//Adds text, bookmark start and end in the paragraph
paragraph.AppendBookmarkStart("Title");
paragraph.AppendText("Adventure Works Cycles");
paragraph.AppendBookmarkEnd("Title");
paragraph = section.AddParagraph();
paragraph.AppendText("Adventure Works Cycles, the fictitious company on which the AdventureWorks sample databases are based, is a large, multinational manufacturing company.");
section = doc.AddSection();
section.AddParagraph();
paragraph = section.AddParagraph() as WParagraph;
//Gets the collection of bookmark start in the word document
List<Entity> items = doc.GetCrossReferenceItems(ReferenceType.Bookmark);
paragraph.AppendText("Bookmark Cross Reference starts here ");
//Appends the cross reference for bookmark “Title” with ContentText as reference kind
paragraph.AppendCrossReference(ReferenceType.Bookmark, ReferenceKind.ContentText, items[0], true, false, false, string.Empty);
//Updates the document Fields
doc.UpdateDocumentFields();---
Unlink fields
Minimal Code
Common for Cross-Platform and Windows-Specific
WField field = section.AddParagraph().AppendField("Date", FieldType.FieldDate) as WField;
//Updates the field
field.Update();
//Unlink the field
field.Unlink();---
Formatting Fields
Minimal Code
Common for Cross-Platform and Windows-Specific
IWField field = section.AddParagraph().AppendField("Page", FieldType.FieldPage);
IEntity entity = field;
//Iterates to sibling items until Field End
while (entity.NextSibling != null)
{
if (entity is WTextRange)
//Sets character format for text ranges
(entity as WTextRange).CharacterFormat.FontSize = 6;
else if ((entity is WFieldMark) && (entity as WFieldMark).Type == FieldMarkType.FieldEnd)
break;
//Gets next sibling item.
entity = entity.NextSibling;
}---
Retrieve Fields
Minimal Code
Common for Cross-Platform and Windows-Specific
foreach (WSection sec in doc.Sections)
{
foreach (WParagraph para in sec.Body.Paragraphs)
{
foreach (var item in para.ChildEntities)
{
if (item is WField field)
{
string code = field.FieldCode;
string value = field.FieldValue;
}
}
}
}
//Retrieve by index
//WField field = doc.Sections[0].Paragraphs[0].ChildEntities[2] as WField;---
Find, Replace & Find-Item
DocIO snippets for finding text, replacing text (string/regex), navigating matches, and locating document items by properties.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Find first text occurrence
Common for Cross-Platform and Windows-Specific
TextSelection sel = doc.Find("{find-text}", caseSensitive: false, wholeWord: true);
if (sel != null)
{
WTextRange r = sel.GetAsOneRange();
r.Text = "{new-text}"; // optional inline replace
}Notes
Findreturns the first match asTextSelection(can be null).
---
Find all occurrences (and optionally format)
Common for Cross-Platform and Windows-Specific
TextSelection[] hits = doc.FindAll("{find-text}", caseSensitive: true, wholeWord: true);
foreach (var h in hits)
{Cross-Platform
h.GetAsOneRange().CharacterFormat.HighlightColor = Syncfusion.Drawing.Color.Yellow;Windows-Specific
h.GetAsOneRange().CharacterFormat.HighlightColor = System.Drawing.Color.Yellow;Common for Cross-Platform and Windows-Specific
}---
Find using Regex
Common for Cross-Platform and Windows-Specific
var sel = doc.Find(new System.Text.RegularExpressions.Regex(@"{pattern}"));
var hits = doc.FindAll(new System.Text.RegularExpressions.Regex(@"{pattern}"));---
Find next occurrence (continue from a body item)
Common for Cross-Platform and Windows-Specific
// After a previous match
WTextRange prev = sel.GetAsOneRange();
TextSelection next = doc.FindNext(prev.OwnerParagraph, "{find-text}", caseSensitive: false, wholeWord: true);Notes
FindNextstarts searching after the providedTextBodyItem(e.g., a paragraph/table).
---
Find multi-paragraph / multi-line text
Use these when the find text can span across paragraph boundaries.
Common for Cross-Platform and Windows-Specific
TextSelection[] hits = doc.FindSingleLine("{multiline-find}", caseSensitive: true, wholeWord: false);
// Regex variant
// TextSelection[] hits = doc.FindSingleLine(new Regex(@"{pattern}"));---
Find next multi-paragraph / multi-line text
Common for Cross-Platform and Windows-Specific
// After a previous match
WTextRange prev = sel.GetAsOneRange();
TextSelection[] next = doc.FindNextSingleLine(prev.OwnerParagraph, "{multiline-find}", caseSensitive: false, wholeWord: true);
// Regex variant
// TextSelection[] next = doc.FindNextSingleLine(prev.OwnerParagraph, new Regex(@"{pattern}"));Notes
FindNextSingleLinestarts searching after the providedTextBodyItem(e.g., a paragraph/table).
---
Replace all occurrences (string → string)
Common for Cross-Platform and Windows-Specific
// Replaces ALL occurrences by default
// (set doc.ReplaceFirst = true to replace only first occurrence)
doc.Replace("{find-text}", "{replace-text}", caseSensitive: true, wholeWord: true);Replace only first occurrence
Common for Cross-Platform and Windows-Specific
doc.ReplaceFirst = true;
doc.Replace("{find-text}", "{replace-text}", caseSensitive: false, wholeWord: false);---
Replace all occurrences (Regex → string)
Common for Cross-Platform and Windows-Specific
doc.Replace(new System.Text.RegularExpressions.Regex(@"{pattern}"), "{replace-text}");---
Replace multi-paragraph / multi-line text
Use these when the target text can span across paragraph boundaries.
Common for Cross-Platform and Windows-Specific
doc.ReplaceSingleLine("{multiline-find}", "{replace-text}", caseSensitive: true, wholeWord: false);
// Regex variant
// doc.ReplaceSingleLine(new Regex(@"{pattern}"), "{replace-text}");---
Replace using selected content (keeps formatting)
Common for Cross-Platform and Windows-Specific
TextSelection replacement = doc.Find(new System.Text.RegularExpressions.Regex(@"{replacement-pattern}"));
if (replacement != null)
doc.Replace("{find-text}", replacement, caseSensitive: false, wholeWord: false, saveFormatting: true);---
Find items (pictures, charts, tables, fields, content controls)
Find first item by a single property
Common for Cross-Platform and Windows-Specific
// Example: find picture by AlternativeText
WPicture pic = doc.FindItemByProperty(EntityType.Picture, "AlternativeText", "{alt-text}") as WPicture;
if (pic != null)
{
pic.Width = 100;
pic.Height = 75;
}Find first item by multiple properties
Common for Cross-Platform and Windows-Specific
string[] names = { "Title", "Rows.Count" };
string[] values = { "{table-title}", "{rows-count}" };
WTable table = doc.FindItemByProperties(EntityType.Table, names, values) as WTable;
if (table != null)
table.OwnerTextBody.ChildEntities.Remove(table);Find ALL items by property / properties
Common for Cross-Platform and Windows-Specific
// Passing null/null can return all entities of a type
List<Entity> allFootnotes = doc.FindAllItemsByProperty(EntityType.Footnote, null, null);
string[] names = { "ContentControlProperties.Title", "ContentControlProperties.Tag" };
string[] values = { "{title}", "{tag}" };
List<Entity> ccs = doc.FindAllItemsByProperties(EntityType.BlockContentControl, names, values);Placeholders
{find-text},{replace-text},{pattern}etc.- Entity properties must match DocIO property names (e.g.,
AlternativeText,Rows.Count).
Footnotes & Endnotes
Footnotes and endnotes — add footnotes, add endnotes, set positions, configure separators, modify content, and remove footnotes/endnotes.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Add Footnotes
Insert Footnote with Text
Common for Cross-Platform and Windows-Specific
WordDocument document = new WordDocument();
IWSection section = document.AddSection();
IWParagraph paragraph = section.AddParagraph();
paragraph.AppendText("Working with footnotes");
paragraph.ApplyStyle(BuiltinStyle.Heading1);
paragraph = section.AddParagraph();
WFootnote footnote = (WFootnote)paragraph.AppendFootnote(FootnoteType.Footnote);
footnote.MarkerCharacterFormat.SubSuperScript = SubSuperScript.SuperScript;
paragraph.AppendText("Sample content for footnotes").CharacterFormat.Bold = true;
IWParagraph footnotePara = footnote.TextBody.AddParagraph();
footnotePara.AppendText("Footnote content at bottom of page.");---
Add Endnotes
Insert Endnote with Text
Common for Cross-Platform and Windows-Specific
WordDocument document = new WordDocument();
IWSection section = document.AddSection();
IWParagraph paragraph = section.AddParagraph();
paragraph.AppendText("Working with endnotes");
paragraph.ApplyStyle(BuiltinStyle.Heading1);
paragraph = section.AddParagraph();
WFootnote endnote = (WFootnote)paragraph.AppendFootnote(FootnoteType.Endnote);
endnote.MarkerCharacterFormat.SubSuperScript = SubSuperScript.SuperScript;
paragraph.AppendText("Sample content for endnotes").CharacterFormat.Bold = true;
IWParagraph endnotePara = endnote.TextBody.AddParagraph();
endnotePara.AppendText("Endnote content at end of document or section.");---
Set Positions & Numbering
Configure Position and Numbering Format
Common for Cross-Platform and Windows-Specific
// Set footnote position and numbering
document.FootnoteNumberFormat = FootEndNoteNumberFormat.Arabic;
document.FootnotePosition = FootnotePosition.PrintImmediatelyBeneathText;
// Set endnote position and numbering
document.EndnoteNumberFormat = FootEndNoteNumberFormat.LowerCaseRoman;
document.EndnotePosition = EndnotePosition.DisplayEndOfSection;
// Then add notes to document
IWParagraph para = section.AddParagraph();
WFootnote footnote = (WFootnote)para.AppendFootnote(FootnoteType.Footnote);
footnote.TextBody.AddParagraph().AppendText("Footnote content");Position & Numbering Options
| Type | Option | Value |
|---|---|---|
| Footnote Position | PrintAtBottomOfPage | At bottom of page (default) |
| PrintImmediatelyBeneathText | Immediately beneath text | |
| Endnote Position | DisplayAtEndOfDocument | At end of document |
| DisplayEndOfSection | At end of section | |
| Number Format | Arabic | 1, 2, 3... |
| UpperCaseRoman | I, II, III... | |
| LowerCaseRoman | i, ii, iii... | |
| UpperCaseLetter | A, B, C... | |
| LowerCaseLetter | a, b, c... |
---
Footnote & Endnote Separators
Modify Separators
Common for Cross-Platform and Windows-Specific
// Customize footnote separator
WTextBody footnoteSep = document.Footnotes.Separator;
footnoteSep.Paragraphs[0].Text = "--- Footnote Separator ---";
// Customize endnote separator
WTextBody endnoteSep = document.Endnotes.Separator;
endnoteSep.Paragraphs[0].Text = "--- Endnote Separator ---";
// Separator types: Separator (default line), Continuation Separator, Continuation Notice---
Modify Content
Modify Existing Footnote or Endnote
Common for Cross-Platform and Windows-Specific
// Open document (see Open and Save Document section)
WordDocument document = new WordDocument("input.docx"); // or FileStream for cross-platform
// Access footnote in paragraph
WParagraph paragraph = document.Sections[0].Paragraphs[6] as WParagraph;
WFootnote footnote = paragraph.ChildEntities[0] as WFootnote;
// Clear and update content
footnote.TextBody.ChildEntities.Clear();
WParagraph notePara = footnote.TextBody.AddParagraph() as WParagraph;
footnote.MarkerCharacterFormat.SubSuperScript = SubSuperScript.SuperScript;
notePara.AppendText("Modified footnote text.");
// Save (see Open and Save Document section)---
Remove Footnotes & Endnotes
Remove Helper Method
Common for Cross-Platform and Windows-Specific
private static void RemoveFootnoteEndnote(WTextBody textBody)
{
for (int i = 0; i < textBody.ChildEntities.Count; i++)
{
IEntity entity = textBody.ChildEntities[i];
if (entity.EntityType == EntityType.Paragraph)
{
WParagraph para = entity as WParagraph;
for (int j = para.ChildEntities.Count - 1; j >= 0; j--)
if (para.ChildEntities[j] is WFootnote)
para.ChildEntities.RemoveAt(j);
}
else if (entity.EntityType == EntityType.Table)
{
foreach (WTableRow row in (entity as WTable).Rows)
foreach (WTableCell cell in row.Cells)
RemoveFootnoteEndnote(cell);
}
else if (entity.EntityType == EntityType.BlockContentControl)
RemoveFootnoteEndnote((entity as BlockContentControl).TextBody);
}
}Remove from Document
Common for Cross-Platform and Windows-Specific
// Open document (see Open and Save Document section)
WordDocument document = new WordDocument("input.docx");
// Remove from all sections
foreach (WSection section in document.Sections)
RemoveFootnoteEndnote(section.Body);
// Save (see Open and Save Document section)---
Practical Example: Document with Both Notes
Complete Example with Footnotes and Endnotes
Common for Cross-Platform and Windows-Specific
WordDocument document = new WordDocument();
IWSection section = document.AddSection();
document.FootnoteNumberFormat = FootEndNoteNumberFormat.Arabic;
document.EndnoteNumberFormat = FootEndNoteNumberFormat.LowerCaseRoman;
document.FootnotePosition = FootnotePosition.PrintAtBottomOfPage;
document.EndnotePosition = EndnotePosition.DisplayEndOfDocument;
IWParagraph title = section.AddParagraph();
title.AppendText("Document with Notes");
title.ApplyStyle(BuiltinStyle.Heading1);
// Add text with footnote
IWParagraph para1 = section.AddParagraph();
para1.AppendText("Sample text");
WFootnote footnote = (WFootnote)para1.AppendFootnote(FootnoteType.Footnote);
footnote.MarkerCharacterFormat.SubSuperScript = SubSuperScript.SuperScript;
para1.AppendText(" with footnote.");
footnote.TextBody.AddParagraph().AppendText("Footnote content");
// Add text with endnote
IWParagraph para2 = section.AddParagraph();
para2.AppendText("Another text");
WFootnote endnote = (WFootnote)para2.AppendFootnote(FootnoteType.Endnote);
endnote.MarkerCharacterFormat.SubSuperScript = SubSuperScript.SuperScript;
para2.AppendText(" with endnote.");
endnote.TextBody.AddParagraph().AppendText("Endnote content");
// Customize separator
document.Footnotes.Separator.Paragraphs[0].Text = "─────────────";---
Placeholders
"{input-document}"→ Replace with"input.docx"or file path"{output-filename}"→ Replace with"output.docx"or desired file path"Sample content for footnotes"→ Replace with actual text"Footnote content"→ Replace with actual footnote text"--- Footnote Separator ---"→ Replace with desired separator text- Paragraph indices (e.g.,
[6],[1]) depend on actual document structure
Form Fields
All form field operations — creating checkboxes, dropdowns, text input fields, modifying properties, and managing form fields in Word documents.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Checkbox
Minimal Code
Common for Cross-Platform and Windows-Specific
WParagraph para = section.AddParagraph() as WParagraph;
para.AppendText("Gender\t");
WCheckBox checkbox = para.AppendCheckBox();
checkbox.Checked = false;
checkbox.CheckBoxSize = 10;With Properties
Common for Cross-Platform and Windows-Specific
WParagraph para = section.AddParagraph() as WParagraph;
para.AppendText("Agree to terms\t");
WCheckBox checkbox = para.AppendCheckBox();
checkbox.Checked = false;
checkbox.CheckBoxSize = 12;
checkbox.CalculateOnExit = true;
checkbox.Help = "Check if you agree";
para.AppendText("I agree");Modify Checkbox
Common for Cross-Platform and Windows-Specific
foreach (ParagraphItem item in document.LastParagraph.ChildEntities)
{
if (item is WCheckBox)
{
WCheckBox checkbox = item as WCheckBox;
checkbox.Checked = true;
checkbox.SizeType = CheckBoxSizeType.Exactly;
}
}Placeholders
checkbox.CheckBoxSize→ Replace with{size-in-points}(e.g., 8, 10, 12)checkbox.Help→ Replace with"{help-text}"
---
Dropdown
Minimal Code
Common for Cross-Platform and Windows-Specific
WParagraph para = section.AddParagraph() as WParagraph;
para.AppendText("Select option\t");
WDropDownFormField dropdown = para.AppendDropDownFormField();
dropdown.DropDownItems.Add("Option 1");
dropdown.DropDownItems.Add("Option 2");
dropdown.DropDownSelectedIndex = 0;With Properties
Common for Cross-Platform and Windows-Specific
WParagraph para = section.AddParagraph() as WParagraph;
para.AppendText("Education\t");
WDropDownFormField dropdown = para.AppendDropDownFormField();
dropdown.DropDownItems.Add("High School");
dropdown.DropDownItems.Add("Bachelor");
dropdown.DropDownItems.Add("Master");
dropdown.Enabled = true;
dropdown.DropDownSelectedIndex = 1;
dropdown.CalculateOnExit = true;Modify Dropdown
Common for Cross-Platform and Windows-Specific
foreach (ParagraphItem item in document.LastParagraph.ChildEntities)
{
if (item is WDropDownFormField)
{
WDropDownFormField dropdown = item as WDropDownFormField;
dropdown.DropDownItems.Remove(1);
dropdown.DropDownSelectedIndex = 0;
dropdown.CharacterFormat.FontName = "Arial";
}
}Placeholders
dropdown.DropDownItems.Add()→ Replace with"{item-text}"dropdown.DropDownSelectedIndex→ Replace with{index}(0-based)
---
Text Form Field
Minimal Code
Common for Cross-Platform and Windows-Specific
WParagraph para = section.AddParagraph() as WParagraph;
para.AppendText("Full Name\t");
WTextFormField textField = para.AppendTextFormField(null);
textField.Type = TextFormFieldType.RegularText;With Default Text
Common for Cross-Platform and Windows-Specific
WParagraph para = section.AddParagraph() as WParagraph;
var text = para.AppendText("Name\t");
text.CharacterFormat.Bold = true;
WTextFormField textField = para.AppendTextFormField("Name", "Enter full name");
textField.Type = TextFormFieldType.RegularText;
textField.CharacterFormat.FontName = "Calibri";
textField.CalculateOnExit = true;Date Text Field
Common for Cross-Platform and Windows-Specific
WParagraph para = section.AddParagraph() as WParagraph;
para.AppendText("Date of Birth\t");
WTextFormField dateField = para.AppendTextFormField("DOB", DateTime.Now.ToString("MM/DD/YY"));
dateField.Type = TextFormFieldType.DateText;
dateField.StringFormat = "MM/DD/YY";
dateField.CalculateOnExit = true;Number Text Field
Common for Cross-Platform and Windows-Specific
WParagraph para = section.AddParagraph() as WParagraph;
para.AppendText("Age\t");
WTextFormField numberField = para.AppendTextFormField("Age", "");
numberField.Type = TextFormFieldType.NumberText;
numberField.CharacterFormat.FontName = "Calibri";Modify Text Field
Common for Cross-Platform and Windows-Specific
foreach (WSection section in document.Sections)
{
foreach (WTextBody textBody in section.ChildEntities)
{
foreach (WFormField formField in textBody.FormFields)
{
if (formField.FormFieldType == FormFieldType.TextInput &&
formField.Name == "Text1")
{
WTextFormField textField = formField as WTextFormField;
if (textField.Type == TextFormFieldType.DateText)
{
textField.Type = TextFormFieldType.RegularText;
textField.StringFormat = "";
textField.DefaultText = "Enter text";
textField.CalculateOnExit = false;
textField.Text = "Updated text value";
}
}
}
}
}Placeholders
textField.Type→ Replace withTextFormFieldType.RegularText,TextFormFieldType.DateText, orTextFormFieldType.NumbertextField.StringFormat→ Replace with"{format}"(e.g., "MM/DD/YY", "0.00")textField.DefaultText→ Replace with"{default-text}""Text1"→ Replace with"{form-field-bookmark-name}"textField.Text→ Use to get or set the current value of the text form field
---
Complete Example
Full Workflow
Common for Cross-Platform and Windows-Specific
var document = new WordDocument();
var section = document.AddSection();
var title = section.AddParagraph() as WParagraph;
title.AppendText("Employee Application Form");
title.ApplyStyle(BuiltinStyle.Heading1);
section.AddParagraph();
// Text fields
var para = section.AddParagraph() as WParagraph;
var text = para.AppendText("Full Name\t");
text.CharacterFormat.Bold = true;
WTextFormField nameField = para.AppendTextFormField(null);
nameField.Type = TextFormFieldType.RegularText;
para = section.AddParagraph() as WParagraph;
text = para.AppendText("Email\t");
text.CharacterFormat.Bold = true;
WTextFormField emailField = para.AppendTextFormField(null);
emailField.Type = TextFormFieldType.RegularText;
section.AddParagraph();
// Dropdown
para = section.AddParagraph() as WParagraph;
text = para.AppendText("Department\t");
text.CharacterFormat.Bold = true;
WDropDownFormField deptField = para.AppendDropDownFormField();
deptField.DropDownItems.Add("Engineering");
deptField.DropDownItems.Add("Sales");
deptField.DropDownItems.Add("HR");
deptField.DropDownSelectedIndex = 0;
section.AddParagraph();
// Checkbox
para = section.AddParagraph() as WParagraph;
WCheckBox checkbox = para.AppendCheckBox();
checkbox.CheckBoxSize = 10;
checkbox.DefaultCheckBoxValue = true;
para.AppendText("I agree to the terms and conditions");
var outputPath = Path.Combine(Directory.GetCurrentDirectory(), "output", "FormDocument.docx");
var stream = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite);
document.Save(stream, FormatType.Docx);
stream.Close();
document.Close();---
Form Field Types
| Type | Class | Purpose |
|---|---|---|
| Checkbox | WCheckBox | Binary selection (checked/unchecked) |
| Dropdown | WDropDownFormField | Select from predefined list |
| Text Input | WTextFormField | Enter regular, date, or number text |
---
Common Properties
| Property | Type | Description |
|---|---|---|
Checked (Checkbox) | bool | Checkbox checked state |
CheckBoxSize | int | Size in points |
SizeType | CheckBoxSizeType | Fixed size or auto |
DefaultCheckBoxValue (Checkbox) | bool | Specifies whether the checkbox is checked by default |
Help | string | Help text on focus |
CalculateOnExit | bool | Trigger calculation when field exits |
DropDownItems | StringCollection | List of dropdown options |
DropDownSelectedIndex | int | Default selected item index (0-based) |
Enabled | bool | Enable/disable field interaction |
Type (TextFormField) | TextFormFieldType | Regular, Date, or Number |
StringFormat | string | Format for date/number fields |
DefaultText | string | Initial text value |
CharacterFormat | ICharacterFormat | Font and text properties |
Name | string | Bookmark name of the form field |
Text (TextFormField) | string | Current value of the text form field |
Headers & Footers
Headers and footers — add headers/footers (odd, even, first page), page numbers with fields, borders, images, and remove headers/footers.
---
Required common usings
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;Required usings for Windows-Specific
using System;
using System.IO;Add Headers & Footers
Add Default Header & Footer
Common for Cross-Platform and Windows-Specific
WordDocument document = new WordDocument();
IWSection section = document.AddSection();
// Add default header (odd pages)
IWParagraph headerPara = section.HeadersFooters.OddHeader.AddParagraph();
headerPara.AppendText("[ Default Page Header ]");
// Add default footer (odd pages)
IWParagraph footerPara = section.HeadersFooters.OddFooter.AddParagraph();
footerPara.AppendText("[ Default Page Footer ]");
// Add content to document
IWParagraph para = section.AddParagraph();
para.AppendText("AdventureWorks Cycles, the fictitious company on which the AdventureWorks sample databases are based, is a large, multinational manufacturing company.");---
Different First Page Header & Footer
Set Different First Page Header/Footer
Common for Cross-Platform and Windows-Specific
IWSection section = document.Sections[0];
section.PageSetup.DifferentFirstPage = true;
IWParagraph firstPageHeader = section.HeadersFooters.FirstPageHeader.AddParagraph();
firstPageHeader.AppendText("[First Page Header]");
IWParagraph firstPageFooter = section.HeadersFooters.FirstPageFooter.AddParagraph();
firstPageFooter.AppendText("[ First Page Footer ]");
IWParagraph defaultHeader = section.HeadersFooters.OddHeader.AddParagraph();
defaultHeader.AppendText("[ Default Page Header ]");
IWParagraph defaultFooter = section.HeadersFooters.OddFooter.AddParagraph();
defaultFooter.AppendText("[ Default Page Footer ]");---
Different Odd & Even Page Headers/Footers
Set Different Headers for Odd and Even Pages
Common for Cross-Platform and Windows-Specific
IWSection section = document.Sections[0];
section.PageSetup.DifferentOddAndEvenPages = true;
IWParagraph oddHeader = section.HeadersFooters.OddHeader.AddParagraph();
oddHeader.AppendText("[ Odd Page Header ]");
IWParagraph oddFooter = section.HeadersFooters.OddFooter.AddParagraph();
oddFooter.AppendText("[ Odd Page Footer ]");
IWParagraph evenHeader = section.HeadersFooters.EvenHeader.AddParagraph();
evenHeader.AppendText("[Even Page Header ]");
IWParagraph evenFooter = section.HeadersFooters.EvenFooter.AddParagraph();
evenFooter.AppendText("[ Even Page Footer ]");---
Link Headers/Footers to Previous Section
Use Previous Section Header/Footer
Common for Cross-Platform and Windows-Specific
WordDocument document = new WordDocument();
IWSection section1 = document.AddSection();
section1.HeadersFooters.Header.AddParagraph().AppendText("[ First Section Header ]");
section1.HeadersFooters.Footer.AddParagraph().AppendText("[ First Section Footer ]");
IWParagraph para1 = section1.AddParagraph();
para1.AppendText("First section content");
// Second section (linked to previous)
IWSection section2 = document.AddSection();
section2.HeadersFooters.Header.AddParagraph().AppendText("[ Second Section Header ]");
section2.HeadersFooters.Footer.AddParagraph().AppendText("[ Second Section Footer ]");
section2.HeadersFooters.LinkToPrevious = true; // Inherit header/footer
IWParagraph para2 = section2.AddParagraph();
para2.AppendText("Second section content");
// Third section (unlink from previous)
IWSection section3 = document.AddSection();
section3.HeadersFooters.Header.AddParagraph().AppendText("[ Third Section Header ]");
section3.HeadersFooters.Footer.AddParagraph().AppendText("[ Third Section Footer ]");
IWParagraph para3 = section3.AddParagraph();
para3.AppendText("Third section content");Options
| API | Effect |
|---|---|
| HeadersFooters.LinkToPrevious | Links all headers & footers |
| HeadersFooters.Header.LinkToPrevious | Links only header |
| HeadersFooters.Footer.LinkToPrevious | Links only footer |
---
Add Page Numbers
Add Simple Page Number
Common for Cross-Platform and Windows-Specific
IWSection section = document.Sections[0];
IWParagraph footerPara = section.HeadersFooters.Footer.AddParagraph();
footerPara.AppendText("Page ");
footerPara.AppendField("Page", FieldType.FieldPage);Add Page Number with Total Pages
Common for Cross-Platform and Windows-Specific
IWSection section = document.Sections[0];
section.PageSetup.PageStartingNumber = 1;
section.PageSetup.RestartPageNumbering = true;
section.PageSetup.PageNumberStyle = PageNumberStyle.Arabic;
IWParagraph footerPara = section.HeadersFooters.Footer.AddParagraph();
footerPara.ParagraphFormat.Tabs.AddTab(523f, TabJustification.Right, TabLeader.NoLeader);
footerPara.AppendText("Copyright Northwind Inc. 2001 - 2015\t");
footerPara.AppendText(" Page ");
footerPara.AppendField("CurrentPageNumber", FieldType.FieldPage);
footerPara.AppendText(" of ");
footerPara.AppendField("TotalNumberOfPages", FieldType.FieldNumPages);Page Number Field Types
Common for Cross-Platform and Windows-Specific
FieldType.FieldPage // Current page number
FieldType.FieldNumPages // Total number of pages
FieldType.FieldDate // Current date field
FieldType.FieldTime // Current time fieldPage Number Style Options
Common for Cross-Platform and Windows-Specific
PageNumberStyle.Arabic // 1, 2, 3...
PageNumberStyle.RomanUpper // I, II, III...
PageNumberStyle.RomanLower // i, ii, iii...---
Add Images to Headers/Footers
Add Logo to Header
Common Setup
IWSection section = document.Sections[0];
IWParagraph headerPara = section.HeadersFooters.Header.AddParagraph();Cross-Platform
FileStream imageStream = new FileStream("logo.jpg", FileMode.Open, FileAccess.Read);
IWPicture picture = headerPara.AppendPicture(imageStream);
picture.Width = 50;
picture.Height = 50;
headerPara.AppendText(" Company Logo");
imageStream.Close();Windows-Specific
Image img = Image.FromFile("logo.jpg");
IWPicture pictureWin = headerPara.AppendPicture(img);
pictureWin.Width = 50;
pictureWin.Height = 50;
headerPara.AppendText(" Company Logo");
img.Dispose();---
Adjust Header/Footer Distance
Set Header & Footer Distance
Common for Cross-Platform and Windows-Specific
IWSection section = document.Sections[0];
section.PageSetup.HeaderDistance = 100;
section.PageSetup.FooterDistance = 100;---
Add Borders to Page
Apply Page Borders
Common for Cross-Platform and Windows-Specific
IWSection section = document.Sections[0];
section.PageSetup.Borders.BorderType = BorderStyle.Single;
section.PageSetup.Borders.Color = Color.Blue;
section.PageSetup.Borders.LineWidth = 0.75f;
section.PageSetup.Borders.Top.Space = 5f;
section.PageSetup.Borders.Bottom.Space = 5f;
section.PageSetup.Borders.Right.Space = 5f;
section.PageSetup.Borders.Left.Space = 5f;Border Style Options
Common for Cross-Platform and Windows-Specific
BorderStyle.Single // Single line
BorderStyle.Double // Double line
BorderStyle.Dot // Dotted line
BorderStyle.DotDash // Dot-dash line
BorderStyle.Triple // Triple line---
Remove Headers & Footers
Remove All Headers and Footers
Common for Cross-Platform and Windows-Specific
WordDocument document = new WordDocument();
foreach (WSection section in document.Sections)
{
section.HeadersFooters.FirstPageHeader.ChildEntities.Clear();
section.HeadersFooters.FirstPageFooter.ChildEntities.Clear();
section.HeadersFooters.OddHeader.ChildEntities.Clear();
section.HeadersFooters.OddFooter.ChildEntities.Clear();
section.HeadersFooters.EvenHeader.ChildEntities.Clear();
section.HeadersFooters.EvenFooter.ChildEntities.Clear();
}Remove Headers from Specific Section
Common for Cross-Platform and Windows-Specific
IWSection section = document.Sections[0];
section.HeadersFooters.OddHeader.ChildEntities.Clear();
section.HeadersFooters.EvenHeader.ChildEntities.Clear();
section.HeadersFooters.FirstPageHeader.ChildEntities.Clear();Remove Footers from Specific Section
Common for Cross-Platform and Windows-Specific
IWSection section = document.Sections[0];
section.HeadersFooters.OddFooter.ChildEntities.Clear();
section.HeadersFooters.EvenFooter.ChildEntities.Clear();
section.HeadersFooters.FirstPageFooter.ChildEntities.Clear();---
Open Existing Document and Modify Headers/Footers
Open and Modify Headers
Cross-Platform
FileStream inputStream = new FileStream("input.docx", FileMode.Open, FileAccess.Read);
WordDocument document = new WordDocument(inputStream, FormatType.Docx);
IWParagraph headerPara = document.Sections[0].HeadersFooters.Header.AddParagraph();
headerPara.AppendText("Modified Header");
MemoryStream outputStream = new MemoryStream();
document.Save(outputStream, FormatType.Docx);
document.Close();Windows-Specific
WordDocument document = new WordDocument("input.docx");
IWParagraph headerPara = document.Sections[0].HeadersFooters.Header.AddParagraph();
headerPara.AppendText("Modified Header");
document.Save("output.docx");
document.Close();---
Practical Example: Complete Document with Header/Footer
Common for Cross-Platform and Windows-Specific
WordDocument document = new WordDocument();
IWSection section = document.AddSection();
// Configure page setup
section.PageSetup.PageStartingNumber = 1;
section.PageSetup.PageNumberStyle = PageNumberStyle.Arabic;
// Add header with company name
IWParagraph headerPara = section.HeadersFooters.Header.AddParagraph();
headerPara.AppendText("Company Report");
headerPara.ParagraphFormat.HorizontalAlignment = HorizontalAlignment.Center;
// Add footer with page numbers
IWParagraph footerPara = section.HeadersFooters.Footer.AddParagraph();
footerPara.ParagraphFormat.Tabs.AddTab(523f, TabJustification.Right, TabLeader.NoLeader);
footerPara.AppendText("Copyright 2025\t");
footerPara.AppendText("Page ");
footerPara.AppendField("Page", FieldType.FieldPage);
footerPara.AppendText(" of ");
footerPara.AppendField("NumPages", FieldType.FieldNumPages);
// Add document content
IWParagraph contentPara = section.AddParagraph();
contentPara.AppendText("This is the document body content.");
contentPara.ParagraphFormat.PageBreakAfter = true;
IWParagraph contentPara2 = section.AddParagraph();
contentPara2.AppendText("This is content on the second page.");---
Placeholders
"{input-document}"→ Replace with"input.docx"or file path"{output-filename}"→ Replace with"output.docx"or desired file path"{image-file-path}"→ Replace with"logo.jpg"or image path- Header/footer text like
"[ Default Page Header ]"→ Replace with actual header/footer content - Border width values in points (0.75f = 0.75 point, 0.5f = 0.5 point)
- Tab position
523fis in twips (1/20th of a point) for right alignment
#!/usr/bin/env dotnet-script
#r "nuget: Syncfusion.DocIO.Net.Core"
#r "nuget: Syncfusion.DocIORenderer.Net.Core"
#r "nuget: Syncfusion.Licensing"
using System;
using System.IO;
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;
using Syncfusion.DocIORenderer;
// Register Syncfusion License
var licenseKey = Environment.GetEnvironmentVariable("SYNCFUSION_LICENSE_KEY");
if (string.IsNullOrWhiteSpace(licenseKey))
{
var licenseFile = Path.Combine(Directory.GetCurrentDirectory(), "SyncfusionLicense.txt");
if (File.Exists(licenseFile))
{
licenseKey = File.ReadAllText(licenseFile).Trim();
}
}
if (!string.IsNullOrWhiteSpace(licenseKey))
{
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(licenseKey);
}
// Ensure output directory exists
Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(), "output"));
try
{
// *** INSERT OPERATION CODE HERE ***
Console.WriteLine("SUCCESS: {output-file-path}");
}
catch (Exception ex)
{
Console.Error.WriteLine($"ERROR: {ex.Message}");
Environment.Exit(1);
}