Skip to content

Commit a737b3e

Browse files
committed
ExcelContentTranslator
1 parent 1e2805d commit a737b3e

File tree

4 files changed

+217
-0
lines changed

4 files changed

+217
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 18
4+
VisualStudioVersion = 18.0.11116.177 d18.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExcelContentTranslator", "ExcelContentTranslator\ExcelContentTranslator.csproj", "{835F8C64-7AEF-4936-A643-6FAFECF88AFC}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{835F8C64-7AEF-4936-A643-6FAFECF88AFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{835F8C64-7AEF-4936-A643-6FAFECF88AFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{835F8C64-7AEF-4936-A643-6FAFECF88AFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{835F8C64-7AEF-4936-A643-6FAFECF88AFC}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {D726F656-F0EE-4360-85B8-564E505CE54A}
24+
EndGlobalSection
25+
EndGlobal
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>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="OpenAI" Version="2.5.0" />
12+
<PackageReference Include="Syncfusion.XlsIO.Net.Core" Version="31.2.3" />
13+
</ItemGroup>
14+
15+
</Project>
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
using OpenAI;
2+
using OpenAI.Chat;
3+
using Syncfusion.XlsIO;
4+
using System;
5+
using System.ClientModel;
6+
using System.Linq;
7+
using System.Text;
8+
9+
/// <summary>
10+
/// AI-powered Excel translator for using Syncfusion XlsIO and OpenAI.
11+
/// </summary>
12+
class ExcelContentTranslator
13+
{
14+
/// <summary>
15+
/// Entry point for the Translator.
16+
/// </summary>
17+
static async Task Main()
18+
{
19+
// Replace with your actual OpenAI API key or set it in environment variables for security
20+
string? openAIApiKey = "Replace the OpenAI Key";
21+
await ExecuteTranslation(openAIApiKey);
22+
}
23+
24+
/// <summary>
25+
/// Execute translation of Excel document.
26+
/// </summary>
27+
private async static Task ExecuteTranslation(string openAIApiKey)
28+
{
29+
Console.WriteLine("AI Powered Excel Translator");
30+
31+
Console.WriteLine("Enter full Excel file path (e.g., C:\\Data\\report.xlsx):");
32+
33+
//Read user input for Excel file path
34+
string? excelFilePath = Console.ReadLine()?.Trim().Trim('"');
35+
36+
Console.WriteLine("Enter the language name (e.g., Chinese, Japanese)");
37+
38+
//Read user input for required language
39+
string? language = Console.ReadLine()?.Trim().Trim('"');
40+
41+
if (string.IsNullOrWhiteSpace(excelFilePath) || !File.Exists(excelFilePath))
42+
{
43+
Console.WriteLine("Invalid path. Exiting.");
44+
return;
45+
}
46+
47+
if (string.IsNullOrWhiteSpace(language))
48+
{
49+
Console.WriteLine("Invalid language. Exiting.");
50+
return;
51+
}
52+
53+
54+
if (string.IsNullOrWhiteSpace(openAIApiKey))
55+
{
56+
Console.WriteLine("OPENAI_API_KEY not set. Exiting.");
57+
return;
58+
}
59+
60+
try
61+
{
62+
// Translate Excel content
63+
await TranslateExcelContent(openAIApiKey, excelFilePath, language);
64+
}
65+
catch (Exception ex)
66+
{
67+
Console.WriteLine($"Failed to read Excel: {ex.StackTrace}");
68+
return;
69+
}
70+
}
71+
72+
/// <summary>
73+
/// Translate Excel content using OpenAI and Syncfusion XlsIO.
74+
/// </summary>
75+
/// <param name="openAIApiKey">OpenAI API key.</param>
76+
/// <param name="excelFilePath">Path to the Excel file.</param>
77+
/// <param name="language">Target language for translation.</param>
78+
private static async Task TranslateExcelContent(string openAIApiKey, string excelFilePath, string language)
79+
{
80+
// Initialize Syncfusion Excel engine
81+
using ExcelEngine excelEngine = new ExcelEngine();
82+
83+
// Set default version to XLSX
84+
IApplication excelApp = excelEngine.Excel;
85+
excelApp.DefaultVersion = ExcelVersion.Xlsx;
86+
87+
IWorkbook workbook = excelApp.Workbooks.Open(excelFilePath);
88+
89+
// Convert each worksheet to CSV format and append to the context
90+
foreach (IWorksheet worksheet in workbook.Worksheets)
91+
{
92+
worksheet.UsedRangeIncludesFormatting = false;
93+
IRange usedRange = worksheet.UsedRange;
94+
95+
int firstRow = usedRange.Row;
96+
int lastRow = usedRange.LastRow;
97+
int firstCol = usedRange.Column;
98+
int lastCol = usedRange.LastColumn;
99+
100+
string systemPrompt = @"You are a professional translator integrated into an Excel automation tool.
101+
Your job is to translate text from Excel cells into the" + language + @" language
102+
Rules:
103+
- Preserve original structure as much as possible.
104+
- Prefer literal translation over paraphrasing.
105+
- Return ONLY the translated text, without quotes, labels, or explanations.
106+
- Preserve placeholders (e.g., {0}, {name}) and keep numbers, currency, and dates intact.
107+
- Do not change the meaning, tone, or formatting unnecessarily.
108+
- Do not add extra commentary or code fences.
109+
- If the text is already in the target language, return it unchanged.
110+
- Be concise and accurate.";
111+
112+
113+
for (int row = firstRow; row <= lastRow; row++)
114+
{
115+
for (int col = firstCol; col <= lastCol; col++)
116+
{
117+
118+
// Skip formula cells
119+
if (worksheet[row, col].HasFormula)
120+
{
121+
continue;
122+
}
123+
124+
// Get cell value
125+
string cellValue = worksheet.GetCellValue(row, col, false);
126+
127+
// Skip empty cells
128+
if (string.IsNullOrEmpty(cellValue))
129+
{
130+
continue;
131+
}
132+
133+
// Prepare user prompt
134+
string userPrompt = cellValue;
135+
136+
try
137+
{
138+
// Get translated text from OpenAI
139+
string translatedText = await AskOpenAIAsync(openAIApiKey, "gpt-4o-mini", systemPrompt, userPrompt);
140+
worksheet.SetValue(row, col, translatedText);
141+
}
142+
catch (Exception ex)
143+
{
144+
Console.WriteLine($"OpenAI error: {ex.Message}");
145+
}
146+
}
147+
148+
}
149+
}
150+
workbook.SaveAs("TranslatedExcelDocument.xlsx");
151+
}
152+
153+
/// <summary>
154+
/// Sends a chat completion request to OpenAI and returns the response.
155+
/// </summary>
156+
/// <param name="apiKey">OpenAI API key.</param>
157+
/// <param name="model">Model name.</param>
158+
/// <param name="systemPrompt">System prompt.</param>
159+
/// <param name="userContent">User content.</param>
160+
/// <returns>AI-generated response as a string.</returns>
161+
private static async Task<string> AskOpenAIAsync(string apiKey, string model, string systemPrompt, string userContent)
162+
{
163+
// Initialize OpenAI client
164+
OpenAIClient openAIClient = new OpenAIClient(apiKey);
165+
166+
// Create chat client for the specified model
167+
ChatClient chatClient = openAIClient.GetChatClient(model);
168+
169+
//Get AI response
170+
ClientResult<ChatCompletion> chatResult = await chatClient.CompleteChatAsync(new SystemChatMessage(systemPrompt), new UserChatMessage(userContent));
171+
172+
string response = chatResult.Value.Content[0].Text ?? string.Empty;
173+
174+
return response;
175+
}
176+
177+
}
Binary file not shown.

0 commit comments

Comments
 (0)