Skip to content

Commit 2987494

Browse files
Merge pull request #620 from SyncfusionExamples/1055290-translator
1055290 - Build an AI‑Powered Word Document Translator Using the .NET Word Library
2 parents ebb9377 + 124c21c commit 2987494

3 files changed

Lines changed: 301 additions & 0 deletions

File tree

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
using Azure.AI.OpenAI;
2+
using OpenAI.Chat;
3+
using Syncfusion.DocIO.DLS;
4+
using System.ClientModel;
5+
6+
namespace WordTranslatorWithAzureOpenAI
7+
{
8+
internal class Program
9+
{
10+
// Replace with your Azure OpenAI API key.
11+
static string? azureOpenAIApiKey = "Replace your Azure OpenAI key";
12+
13+
// Replace with your Azure OpenAI deployment name.
14+
static string? azureOpenAIModel = "Replace your deployment name";
15+
16+
static async Task Main(string[] args)
17+
{
18+
// Start the Word document translation process.
19+
await ExecuteTranslation();
20+
}
21+
22+
/// <summary>
23+
/// Execute translation of Word document.
24+
/// </summary>
25+
private async static Task ExecuteTranslation()
26+
{
27+
// Display application title.
28+
Console.WriteLine("AI Powered Word Translator");
29+
30+
// Prompt the user to enter the full path of the Word document.
31+
Console.WriteLine("Enter full Word file path (e.g., C:\\Data\\Input.docx):");
32+
33+
// Read the Word document path entered by the user.
34+
string? wordFilePath = Console.ReadLine()?.Trim().Trim('"');
35+
36+
// Prompt the user to enter the target language.
37+
Console.WriteLine("Enter the language name (e.g., Chinese, Japanese)");
38+
39+
// Read the target language entered by the user.
40+
string? language = Console.ReadLine()?.Trim().Trim('"');
41+
42+
// Validate the specified Word document path.
43+
if (string.IsNullOrWhiteSpace(wordFilePath) || !File.Exists(wordFilePath))
44+
{
45+
Console.WriteLine("Invalid path. Exiting.");
46+
return;
47+
}
48+
49+
// Validate the target language.
50+
if (string.IsNullOrWhiteSpace(language))
51+
{
52+
Console.WriteLine("Invalid language. Exiting.");
53+
return;
54+
}
55+
56+
// Verify that the Azure OpenAI API key is configured.
57+
if (string.IsNullOrWhiteSpace(azureOpenAIApiKey))
58+
{
59+
Console.WriteLine("AZURE_OPENAI_API_KEY not set. Exiting.");
60+
return;
61+
}
62+
63+
try
64+
{
65+
// Generate and save the translated Word document.
66+
await TranslateWordContent(wordFilePath, language);
67+
}
68+
catch (Exception ex)
69+
{
70+
// Handle any errors encountered during translation.
71+
Console.WriteLine($"Failed to read Word document: {ex.StackTrace}");
72+
return;
73+
}
74+
}
75+
76+
/// <summary>
77+
/// Translate Word content using Azure OpenAI and Syncfusion DocIO.
78+
/// </summary>
79+
/// <param name="wordFilePath">Path to the Word file.</param>
80+
/// <param name="language">Target language for translation.</param>
81+
private static async Task TranslateWordContent(string wordFilePath, string language)
82+
{
83+
// Open the existing Word document.
84+
WordDocument wordDocument = new WordDocument(wordFilePath);
85+
86+
// Define a system prompt that instructs Azure OpenAI how to perform the translation.
87+
// The prompt includes rules to preserve formatting, placeholders, and document structure.
88+
string systemPrompt = @"You are a professional translator integrated into an DocIO automation tool.
89+
Your job is to translate text from word document into the" + language + @" language
90+
Rules:
91+
- Preserve original structure as much as possible.
92+
- Prefer literal translation over paraphrasing.
93+
- Return ONLY the translated text, without quotes, labels, or explanations.
94+
- Preserve placeholders (e.g., {0}, {name}) and keep numbers, currency, and dates intact.
95+
- Do not change the meaning, tone, or formatting unnecessarily.
96+
- Do not add extra commentary or code fences.
97+
- If the text is already in the target language, return it unchanged.
98+
- Be concise and accurate.";
99+
100+
// Iterate through each section in the Word document.
101+
foreach (WSection section in wordDocument.Sections)
102+
{
103+
// Access the section body, which contains the main document content.
104+
WTextBody sectionBody = section.Body;
105+
106+
// Translate the content in the section body.
107+
await TranslateTextBody(sectionBody, systemPrompt);
108+
109+
// Access the headers and footers of the current section.
110+
WHeadersFooters headersFooters = section.HeadersFooters;
111+
112+
// Translate the content in the odd-page header and footer.
113+
await TranslateTextBody(headersFooters.OddHeader, systemPrompt);
114+
await TranslateTextBody(headersFooters.OddFooter, systemPrompt);
115+
}
116+
117+
// Save the Translate Word document.
118+
wordDocument.Save(wordFilePath.Replace(".docx", "_DocIOTranslate.docx"));
119+
120+
// Close the Word document and release resources.
121+
wordDocument.Close();
122+
}
123+
124+
/// <summary>
125+
/// Translates the text content of a text body using Azure OpenAI and updates it.
126+
/// </summary>
127+
/// <param name="textBody">The textBody to translate.</param>
128+
/// <param name="systemPrompt">System prompt to guide translation behavior.</param>
129+
private static async Task TranslateTextBody(WTextBody textBody, string systemPrompt)
130+
{
131+
// Iterate through each content element in the text body.
132+
foreach (Entity entity in textBody.ChildEntities)
133+
{
134+
// Translate paragraph content.
135+
if (entity is WParagraph paragraph)
136+
{
137+
await TranslateParagraphs(paragraph, systemPrompt);
138+
}
139+
140+
// Translate table content.
141+
else if (entity is WTable table)
142+
{
143+
await TranslateTable(table, systemPrompt);
144+
}
145+
146+
// Translate content within content controls recursively.
147+
else if (entity is BlockContentControl blockContentControl)
148+
{
149+
await TranslateTextBody(blockContentControl.TextBody, systemPrompt);
150+
}
151+
}
152+
}
153+
154+
/// <summary>
155+
/// Translates all text content within a table using OpenAI.
156+
/// </summary>
157+
/// <param name="table">The table to translate.</param>
158+
/// <param name="systemPrompt">System prompt to guide translation behavior.</param>
159+
private static async Task TranslateTable(WTable table, string systemPrompt)
160+
{
161+
162+
// Iterate through each row in the table.
163+
foreach (WTableRow row in table.Rows)
164+
{
165+
// Iterate through each cell in the current row.
166+
foreach (WTableCell cell in row.Cells)
167+
{
168+
// Iterate through each content element within the cell.
169+
foreach (Entity entity in cell.ChildEntities)
170+
{
171+
// Translate paragraph content.
172+
if (entity is WParagraph paragraph)
173+
{
174+
await TranslateParagraphs(paragraph, systemPrompt);
175+
}
176+
177+
// Translate paragraph content.
178+
else if (entity is WTable nestedTable)
179+
{
180+
await TranslateTable(nestedTable, systemPrompt);
181+
}
182+
}
183+
}
184+
}
185+
}
186+
187+
/// <summary>
188+
/// Translates the text content of a paragraph using Azure OpenAI and updates it.
189+
/// </summary>
190+
/// <param name="paragraph">The paragraph to translate.</param>
191+
/// <param name="systemPrompt">System prompt to guide translation behavior.</param>
192+
private static async Task TranslateParagraphs(WParagraph paragraph, string systemPrompt)
193+
{
194+
// Retrieve the paragraph text.
195+
string originalText = paragraph.Text;
196+
if (string.IsNullOrEmpty(originalText)) return;
197+
try
198+
{
199+
string translatedText = originalText;
200+
// Call Azure OpenAI to translate the text and Store the translated result in the dictionary for reuse.
201+
translatedText = await AskAzureOpenAIAsync(azureOpenAIApiKey, azureOpenAIModel, systemPrompt, originalText);
202+
// Replace the original text with the translated version.
203+
paragraph.Text = translatedText;
204+
}
205+
catch (Exception ex)
206+
{
207+
// Log any errors that occur during translation.
208+
Console.WriteLine($"OpenAI error: {ex.Message}");
209+
}
210+
}
211+
212+
/// <summary>
213+
/// Sends a chat completion request to Azure OpenAI and returns the response.
214+
/// </summary>
215+
/// <param name="apiKey">Azure OpenAI API key.</param>
216+
/// <param name="azureOpenAImodel">Model name.</param>
217+
/// <param name="systemPrompt">System prompt.</param>
218+
/// <param name="userContent">User content.</param>
219+
/// <returns>AI-generated response as a string.</returns>
220+
private static async Task<string> AskAzureOpenAIAsync(string apiKey, string azureOpenAImodel, string systemPrompt, string userContent)
221+
{
222+
// Create the Azure OpenAI client using the endpoint and API key
223+
AzureOpenAIClient azureClient = new(
224+
new Uri("https://your-resource-name.openai.azure.com/"),
225+
new ApiKeyCredential(apiKey));
226+
227+
// Create chat client for the specified mode
228+
ChatClient chatClient = azureClient.GetChatClient(azureOpenAIModel);
229+
230+
// Create chat client for the specified mode
231+
ClientResult<ChatCompletion> chatResult = await chatClient.CompleteChatAsync(
232+
new SystemChatMessage(systemPrompt),
233+
new UserChatMessage(userContent));
234+
235+
// Extract the generated content from the response
236+
string response = chatResult.Value.Content[0].Text ?? string.Empty;
237+
return response;
238+
}
239+
}
240+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Build an AI‑Powered Word Document Translator Using the .NET Word Library
2+
3+
This repository provides an example of how to translate the content of a Word document **Azure OpenAI** and the **[.NET Word Library](https://www.syncfusion.com/document-sdk/net-word-library) (DocIO)**. The sample reads content from a Word document, translates the text into the specified language, and saves the translated content as a new Word document.
4+
5+
## Process Behind Word Content Translation
6+
7+
This sample demonstrates how to automate Word document translation by combining the document-processing capabilities of the **.NET Word Library (DocIO)** with the language translation capabilities of **Azure OpenAI**.
8+
9+
The workflow consists of the following steps:
10+
11+
1. Load and read the content of a Word document.
12+
2. Extract text from the document.
13+
3. Send the extracted content to Azure OpenAI with a translation prompt.
14+
4. Translate the content into the target language.
15+
5. Write the translated text back into a new Word document.
16+
6. Save the translated document as a new .docx file.
17+
18+
## Prerequisites
19+
20+
Before running the sample, ensure that you have:
21+
22+
- An Azure OpenAI resource.
23+
- A deployed chat model in Azure OpenAI.
24+
- A valid Azure OpenAI API key.
25+
- The Syncfusion DocIO NuGet package installed.
26+
27+
## Steps to Use the Sample
28+
29+
1. Open the application where the Syncfusion DocIO package is installed.
30+
2. Replace the following placeholders in the code:
31+
- `Replace your Azure OpenAI key` with your Azure OpenAI API key.
32+
- `https://your-resource-name.openai.azure.com/` with your Azure OpenAI endpoint.
33+
- `your-model-name` with your deployed Azure OpenAI model name.
34+
3. Run the application.
35+
4. Save the translated document as a new .docx file.
36+
5. Specify the target language.
37+
6. The application translates the document content and saves it as a new Word document.
38+
39+
## Input
40+
41+
- Source Word document (`.docx`)
42+
- Target translation language
43+
44+
## Output
45+
46+
A new Word document containing the translated content.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net10.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Azure.AI.OpenAI" Version="2.1.0" />
12+
<PackageReference Include="Syncfusion.DocIO.Net.Core" Version="35.1.40" />
13+
</ItemGroup>
14+
15+
</Project>

0 commit comments

Comments
 (0)