---
title: "Excel File Translation."
description: "Smart translation for Excel files, multiple language support, preserve original formatting."

---

# Excel File Translation.


> Smart translation for Excel files, multiple language support, preserve original formatting.





















































```
- 
:root {
--cells-cloud-ai-text-primary-color: #4f46e5;
--cells-cloud-ai-text-secondary-color: #7c3aed;
--cells-cloud-ai-text-accent-color: #06b6d4;
--cells-cloud-ai-text-dark-color: #1e293b;
--cells-cloud-ai-text-light-color: #f8fafc;
--cells-cloud-ai-text-card-bg: rgba(255, 255, 255, 0.95);
--cells-cloud-ai-text-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
--cells-cloud-ai-text-transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.cells-cloud-ai-text {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
color: var(--cells-cloud-ai-text-dark-color);
line-height: 1.6;
min-height: 100vh;
overflow-x: hidden;
}
.cells-cloud-ai-text-container {
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
}
.cells-cloud-ai-text-page-header {
text-align: center;
margin-bottom: 2rem;
padding-top: 1rem;
}
.cells-cloud-ai-text-page-header h1 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
background: linear-gradient(to right, var(--cells-cloud-ai-text-primary-color), var(--cells-cloud-ai-text-accent-color));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.cells-cloud-ai-text-page-header p {
color: #64748b;
font-size: 1.1rem;
max-width: 600px;
margin: 0 auto;
}
.cells-cloud-ai-text-control-section {
background: var(--cells-cloud-ai-text-card-bg);
border-radius: 15px;
padding: 1.5rem 2rem;
box-shadow: var(--cells-cloud-ai-text-shadow);
margin-bottom: 2rem;
display: flex;
align-items: center;
gap: 2rem;
flex-wrap: wrap;
}
.cells-cloud-ai-text-upload-container {
flex: 1;
min-width: 300px;
}
.cells-cloud-ai-text-upload-area {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
border: 2px dashed rgba(79, 70, 229, 0.2);
border-radius: 10px;
transition: var(--cells-cloud-ai-text-transition);
cursor: pointer;
}
.cells-cloud-ai-text-upload-area:hover {
border-color: var(--cells-cloud-ai-text-primary-color);
background: rgba(79, 70, 229, 0.02);
}
.cells-cloud-ai-text-upload-area.drag-over {
border-color: var(--cells-cloud-ai-text-accent-color);
background: rgba(79, 70, 229, 0.05);
}
.cells-cloud-ai-text-upload-icon {
width: 50px;
height: 50px;
background: linear-gradient(135deg, var(--cells-cloud-ai-text-primary-color), var(--cells-cloud-ai-text-secondary-color));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 1.5rem;
flex-shrink: 0;
}
.cells-cloud-ai-text-upload-info {
flex: 1;
}
.cells-cloud-ai-text-upload-info h3 {
margin: 0 0 0.3rem 0;
font-size: 1.1rem;
color: var(--cells-cloud-ai-text-dark-color);
}
.cells-cloud-ai-text-upload-info p {
margin: 0;
color: #64748b;
font-size: 0.9rem;
}
.cells-cloud-ai-text-file-input {
display: none;
}
.cells-cloud-ai-text-file-info {
margin-top: 0.8rem;
padding: 0.8rem;
background: #f8fafc;
border-radius: 8px;
display: none;
animation: cells-cloud-ai-text-fadeIn 0.3s ease;
}
@keyframes cells-cloud-ai-text-fadeIn {
from { opacity: 0; transform: translateY(5px); }
to { opacity: 1; transform: translateY(0); }
}
.cells-cloud-ai-text-file-info.show {
display: flex;
align-items: center;
justify-content: space-between;
}
.cells-cloud-ai-text-file-details {
flex: 1;
}
.cells-cloud-ai-text-file-name {
font-weight: 600;
color: var(--cells-cloud-ai-text-dark-color);
font-size: 0.95rem;
margin-bottom: 0.2rem;
word-break: break-all;
}
.cells-cloud-ai-text-file-size {
color: #64748b;
font-size: 0.85rem;
}
.cells-cloud-ai-text-file-remove {
color: #ef4444;
cursor: pointer;
font-size: 1.1rem;
transition: var(--cells-cloud-ai-text-transition);
padding: 0.3rem;
border-radius: 50%;
}
.cells-cloud-ai-text-file-remove:hover {
background: #fee2e2;
transform: scale(1.1);
}
.cells-cloud-ai-text-language-container {
flex: 1;
min-width: 300px;
}
.cells-cloud-ai-text-language-select-wrapper {
position: relative;
}
.cells-cloud-ai-text-language-select {
width: 100%;
padding: 1rem 1.2rem;
font-size: 1rem;
border: 2px solid #e2e8f0;
border-radius: 10px;
background: white;
color: var(--cells-cloud-ai-text-dark-color);
cursor: pointer;
appearance: none;
transition: var(--cells-cloud-ai-text-transition);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%234f46e5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 1rem center;
background-size: 1rem;
padding-right: 3rem;
}
.cells-cloud-ai-text-language-select:focus {
outline: none;
border-color: var(--cells-cloud-ai-text-primary-color);
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
.cells-cloud-ai-text-language-select:hover {
border-color: #cbd5e1;
}
.cells-cloud-ai-text-action-container {
flex-shrink: 0;
min-width: 200px;
}
.cells-cloud-ai-text-translate-btn {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(to right, var(--cells-cloud-ai-text-primary-color), var(--cells-cloud-ai-text-secondary-color));
color: white;
padding: 1rem 2rem;
border-radius: 10px;
border: none;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: var(--cells-cloud-ai-text-transition);
box-shadow: 0 5px 20px rgba(79, 70, 229, 0.3);
position: relative;
overflow: hidden;
}
.cells-cloud-ai-text-translate-btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(79, 70, 229, 0.4);
}
.cells-cloud-ai-text-translate-btn:hover::before {
left: 100%;
}
.cells-cloud-ai-text-translate-btn i {
margin-right: 10px;
font-size: 1.2rem;
transition: var(--cells-cloud-ai-text-transition);
}
.cells-cloud-ai-text-translate-btn:hover i {
transform: rotate(10deg);
}
.cells-cloud-ai-text-translate-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none !important;
}
.cells-cloud-ai-text-io-section {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
margin-bottom: 2rem;
min-height: 400px;
}
@media (max-width: 1100px) {
.cells-cloud-ai-text-io-section {
grid-template-columns: 1fr;
}
}
.cells-cloud-ai-text-io-card {
background: var(--cells-cloud-ai-text-card-bg);
border-radius: 15px;
padding: 1.5rem;
box-shadow: var(--cells-cloud-ai-text-shadow);
display: flex;
flex-direction: column;
transition: var(--cells-cloud-ai-text-transition);
}
.cells-cloud-ai-text-io-card:hover {
transform: translateY(-5px);
}
.cells-cloud-ai-text-io-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 1rem;
padding-bottom: 0.8rem;
border-bottom: 2px solid #f1f5f9;
}
.cells-cloud-ai-text-io-header h2 {
font-size: 1.4rem;
color: var(--cells-cloud-ai-text-dark-color);
margin: 0;
display: flex;
align-items: center;
gap: 0.6rem;
}
.cells-cloud-ai-text-io-header h2 i {
color: var(--cells-cloud-ai-text-primary-color);
}
.cells-cloud-ai-text-char-count {
color: #64748b;
font-size: 0.9rem;
background: #f1f5f9;
padding: 0.3rem 0.8rem;
border-radius: 20px;
}
.cells-cloud-ai-text-textarea {
flex: 1;
width: 100%;
min-height: 300px;
border: 2px solid #e2e8f0;
border-radius: 10px;
font-size: 1rem;
font-family: inherit;
line-height: 1.6;
resize: none;
transition: var(--cells-cloud-ai-text-transition);
background: #f8fafc;
}
.cells-cloud-ai-text-textarea:focus {
outline: none;
border-color: var(--cells-cloud-ai-text-primary-color);
background: white;
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
.cells-cloud-ai-text-textarea::placeholder {
color: #94a3b8;
}
.cells-cloud-ai-text-textarea[readonly] {
background: #f8fafc;
cursor: default;
}
.cells-cloud-ai-text-progress {
margin-top: 1rem;
display: none;
}
.cells-cloud-ai-text-progress-bar {
width: 100%;
height: 6px;
background: #e2e8f0;
border-radius: 3px;
overflow: hidden;
margin-bottom: 0.5rem;
}
.cells-cloud-ai-text-progress-fill {
width: 0%;
height: 100%;
background: linear-gradient(to right, var(--cells-cloud-ai-text-primary-color), var(--cells-cloud-ai-text-accent-color));
border-radius: 3px;
transition: width 0.3s ease;
}
.cells-cloud-ai-text-progress-text {
text-align: center;
color: #64748b;
font-size: 0.85rem;
}
.cells-cloud-ai-text-result-actions {
display: flex;
gap: 0.8rem;
margin-top: 1rem;
flex-wrap: wrap;
}
.cells-cloud-ai-text-result-btn {
display: inline-flex;
align-items: center;
padding: 0.6rem 1.2rem;
border-radius: 8px;
text-decoration: none;
font-weight: 600;
transition: var(--cells-cloud-ai-text-transition);
border: none;
cursor: pointer;
font-size: 0.9rem;
}
.cells-cloud-ai-text-result-btn i {
margin-right: 6px;
}
.cells-cloud-ai-text-download-btn {
background: linear-gradient(to right, #10b981, #34d399);
color: white;
box-shadow: 0 3px 10px rgba(16, 185, 129, 0.2);
}
.cells-cloud-ai-text-download-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(16, 185, 129, 0.3);
}
.cells-cloud-ai-text-copy-btn {
background: linear-gradient(to right, #3b82f6, #60a5fa);
color: white;
box-shadow: 0 3px 10px rgba(59, 130, 246, 0.2);
}
.cells-cloud-ai-text-copy-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(59, 130, 246, 0.3);
}
.cells-cloud-ai-text-features {
margin-top: 3rem;
}
.cells-cloud-ai-text-features h2 {
text-align: center;
font-size: 1.8rem;
margin-bottom: 1.5rem;
color: var(--cells-cloud-ai-text-dark-color);
}
.cells-cloud-ai-text-feature-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.2rem;
}
.cells-cloud-ai-text-feature-item {
background: var(--cells-cloud-ai-text-card-bg);
padding: 1.2rem;
border-radius: 12px;
box-shadow: var(--cells-cloud-ai-text-shadow);
transition: var(--cells-cloud-ai-text-transition);
}
.cells-cloud-ai-text-feature-item:hover {
transform: translateY(-3px);
}
.cells-cloud-ai-text-feature-item i {
font-size: 1.8rem;
color: var(--cells-cloud-ai-text-primary-color);
margin-bottom: 0.8rem;
}
.cells-cloud-ai-text-feature-item h3 {
font-size: 1.1rem;
margin-bottom: 0.4rem;
color: var(--cells-cloud-ai-text-dark-color);
}
.cells-cloud-ai-text-feature-item p {
color: #64748b;
font-size: 0.85rem;
margin: 0;
}
.cells-cloud-ai-text-notification {
position: fixed;
top: 65px;
right: 20px;
padding: 1rem 1.2rem;
background: #10b981;
color: white;
border-radius: 8px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
display: none;
align-items: center;
gap: 0.6rem;
z-index: 1000;
animation: cells-cloud-ai-text-slideIn 0.3s ease;
}
@keyframes cells-cloud-ai-text-slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@media (max-width: 768px) {
.cells-cloud-ai-text-container {
padding: 1rem;
}
.cells-cloud-ai-text-page-header h1 {
font-size: 2rem;
}
.cells-cloud-ai-text-control-section {
flex-direction: column;
gap: 1.5rem;
padding: 1.5rem;
}
.cells-cloud-ai-text-upload-container,
.cells-cloud-ai-text-language-container,
.cells-cloud-ai-text-action-container {
width: 100%;
min-width: auto;
}
.cells-cloud-ai-text-io-section {
gap: 1.5rem;
}
.cells-cloud-ai-text-io-card {
padding: 1.2rem;
}
.cells-cloud-ai-text-result-actions {
justify-content: center;
}
}
# Text Translation
Translate text files or input text directly. Supports multiple languages with AI-powered accuracy.
### Upload Text File
Drag & drop or click to upload .txt file
Select target language...
Translate
## Input Text
0 characters
## Translation Result
0 characters
Preparing translation...
Download
Copy
## Features
### File Upload
Upload .txt files for bulk text translation
### Direct Input
Type or paste text directly for instant translation
### Multi-language
Support 20+ commonly used languages
### Real-time
AI-powered translation with real-time results
Text copied to clipboard!
const languages = [
{ code: 'en', name: 'English', flag: '🇺🇸' },
{ code: 'zh', name: 'Chinese', flag: '🇨🇳' },
{ code: 'es', name: 'Spanish', flag: '🇪🇸' },
{ code: 'fr', name: 'French', flag: '🇫🇷' },
{ code: 'de', name: 'German', flag: '🇩🇪' },
{ code: 'ja', name: 'Japanese', flag: '🇯🇵' },
{ code: 'ko', name: 'Korean', flag: '🇰🇷' },
{ code: 'ru', name: 'Russian', flag: '🇷🇺' },
{ code: 'pt', name: 'Portuguese', flag: '🇵🇹' },
{ code: 'it', name: 'Italian', flag: '🇮🇹' },
{ code: 'ar', name: 'Arabic', flag: '🇸🇦' },
{ code: 'nl', name: 'Dutch', flag: '🇳🇱' },
{ code: 'tr', name: 'Turkish', flag: '🇹🇷' },
{ code: 'pl', name: 'Polish', flag: '🇵🇱' },
{ code: 'sv', name: 'Swedish', flag: '🇸🇪' },
{ code: 'da', name: 'Danish', flag: '🇩🇰' },
{ code: 'fi', name: 'Finnish', flag: '🇫🇮' },
{ code: 'no', name: 'Norwegian', flag: '🇳🇴' },
{ code: 'hi', name: 'Hindi', flag: '🇮🇳' },
{ code: 'vi', name: 'Vietnamese', flag: '🇻🇳' }
];
const API_ENDPOINT = 'https://cells-scripting-api.aspose.cloud/v4.0/cells/runwebapi';
const TRANSLATE_ENDPOINT = 'https://api.aspose.cloud/v4.0/cells/ai/translate/text';
document.addEventListener('DOMContentLoaded', function() {
const uploadArea = document.getElementById('uploadArea');
const fileInput = document.getElementById('textFile');
const fileInfo = document.getElementById('fileInfo');
const fileName = document.getElementById('fileName');
const fileSize = document.getElementById('fileSize');
const removeFile = document.getElementById('removeFile');
const textInput = document.getElementById('textInput');
const textOutput = document.getElementById('textOutput');
const inputCharCount = document.getElementById('inputCharCount');
const outputCharCount = document.getElementById('outputCharCount');
const languageSelect = document.getElementById('languageSelect');
const translateBtn = document.getElementById('translateBtn');
const progress = document.getElementById('progress');
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
const resultActions = document.getElementById('resultActions');
const downloadBtn = document.getElementById('downloadBtn');
const copyBtn = document.getElementById('copyBtn');
const notification = document.getElementById('notification');
const notificationText = document.getElementById('notificationText');
let selectedFile = null;
let selectedLanguage = null;
let inputText = '';
function initLanguageSelect() {
languages.forEach(lang => {
const option = document.createElement('option');
option.value = lang.code;
option.textContent = `${lang.flag} ${lang.name} (${lang.code.toUpperCase()})`;
languageSelect.appendChild(option);
});
}
languageSelect.addEventListener('change', function() {
selectedLanguage = this.value;
updateTranslateButton();
});
textInput.addEventListener('input', function() {
inputText = this.value;
inputCharCount.textContent = `${this.value.length} characters`;
updateTranslateButton();
});
function updateTranslateButton() {
const hasFile = selectedFile !== null;
const hasText = inputText.trim().length > 0;
const hasLanguage = selectedLanguage !== null;
const hasContent = (hasFile || hasText) && hasLanguage;
translateBtn.disabled = !hasContent;
if (!hasFile) {
textInput.placeholder = "Enter text to translate...";
}
}
uploadArea.addEventListener('click', function(e) {
e.stopPropagation();
fileInput.click();
});
fileInput.addEventListener('change', handleFileSelect);
uploadArea.addEventListener('dragover', function(e) {
e.preventDefault();
e.stopPropagation();
uploadArea.classList.add('drag-over');
});
uploadArea.addEventListener('dragleave', function(e) {
e.preventDefault();
e.stopPropagation();
uploadArea.classList.remove('drag-over');
});
uploadArea.addEventListener('drop', function(e) {
e.preventDefault();
e.stopPropagation();
uploadArea.classList.remove('drag-over');
if (e.dataTransfer.files.length) {
handleFile(e.dataTransfer.files[0]);
}
});
function handleFileSelect(e) {
if (e.target.files.length) {
handleFile(e.target.files[0]);
}
}
function handleFile(file) {
const validTypes = ['.txt', '.text'];
const fileExtension = file.name.slice(file.name.lastIndexOf('.')).toLowerCase();
if (!validTypes.includes(fileExtension)) {
showNotification('Please select a text file (.txt format)', 'error');
fileInput.value = '';
return;
}
selectedFile = file;
fileName.textContent = file.name;
fileSize.textContent = formatFileSize(file.size);
fileInfo.classList.add('show');
updateTranslateButton();
if (textInput.value.trim()) {
showNotification('File selected. File content will be used for translation.', 'info');
}
}
removeFile.addEventListener('click', function(e) {
e.stopPropagation();
e.preventDefault();
selectedFile = null;
fileInput.value = '';
fileInfo.classList.remove('show');
updateTranslateButton();
showNotification('File removed', 'info');
});
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
translateBtn.addEventListener('click', async function() {
if (!selectedLanguage) {
showNotification('Please select a target language', 'error');
return;
}
let isFileMode = false;
let filename = null;
if (selectedFile) {
isFileMode = true;
filename = selectedFile.name;
if (selectedFile.size > 10 * 1024 * 1024) {
showNotification('File is too large (max 10MB)', 'error');
return;
}
} else if (!inputText.trim()) {
showNotification('Please upload a file or enter text to translate', 'error');
return;
}
progress.style.display = 'block';
resultActions.style.display = 'none';
translateBtn.disabled = true;
updateProgress(30, 'Preparing translation...');
try {
const translatedText = await translateContent(
selectedFile,
inputText.trim(),
selectedLanguage,
isFileMode,
filename
);
showTranslationResult(translatedText, isFileMode, filename);
} catch (error) {
console.error('Translation error:', error);
showNotification(`Translation failed: ${error.message}`, 'error');
translateBtn.disabled = false;
progress.style.display = 'none';
}
});
function updateProgress(value, text) {
progressFill.style.width = value + '%';
progressText.textContent = text;
}
async function translateContent(file, text, targetLanguage, isFileMode, filename) {
const translateUrl = `${TRANSLATE_ENDPOINT}?targetLanguage=${targetLanguage}`;
console.log('Translating content:', {
targetLanguage,
isFileMode,
textLength: text?.length || 0,
translateUrl
});
const formData = new FormData();
formData.append("url", translateUrl);
formData.append("method", "PUT");
if (isFileMode) {
updateProgress(50, 'Uploading file...');
formData.append("files", file);
console.log('FormData created with file:', {
url: translateUrl,
method: "PUT",
file: file.name,
fileSize: file.size
});
} else {
updateProgress(50, 'Sending text...');
formData.append("body", text);
console.log('FormData created with text:', {
url: translateUrl,
method: "PUT",
contentLength: text.length
});
}
updateProgress(70, 'Sending translation request...');
try {
const response = await fetch(API_ENDPOINT, {
method: 'POST',
body: formData
});
console.log('Response status:', response.status);
if (!response.ok) {
const errorText = await response.text();
console.log('Error response:', errorText);
throw new Error(`API request failed with status ${response.status}: ${errorText}`);
}
updateProgress(90, 'Processing translation...');
const result = await handleResponse(response);
console.log('Translation successful, result length:', result.length);
return result;
} catch (error) {
console.error('Fetch error:', error);
throw error;
}
}
async function handleResponse(response) {
const contentType = response.headers.get('content-type') || '';
console.log('Response content-type:', contentType);
if (contentType.includes('text/plain')) {
const text = await response.text();
return text;
} else {
const blob = await response.blob();
console.log('Received blob:', blob.size, 'bytes, type:', blob.type);
if (blob.size === 0) {
throw new Error('Received empty file');
}
const text = await blob.text();
return text;
}
}
function showTranslationResult(translatedText, isFileMode, originalFilename) {
updateProgress(100, 'Translation complete!');
setTimeout(() => {
progress.style.display = 'none';
if (isFileMode) {
textOutput.value = "";
textOutput.placeholder = "File translation completed. Use download button to get translated file.";
outputCharCount.textContent = "File translation completed";
} else {
textOutput.value = translatedText;
textOutput.placeholder = "Translation will appear here...";
outputCharCount.textContent = `${translatedText.length} characters`;
}
resultActions.style.display = 'flex';
translateBtn.disabled = false;
downloadBtn.onclick = function(e) {
e.preventDefault();
const filename = isFileMode && originalFilename ?
`${originalFilename.replace('.txt', '')}_translated.txt` :
'translated_text.txt';
downloadTextFile(translatedText, filename);
};
if (isFileMode) {
copyBtn.disabled = true;
copyBtn.style.opacity = '0.5';
copyBtn.style.cursor = 'not-allowed';
copyBtn.onclick = function(e) {
e.preventDefault();
showNotification('For file translation, please use download button', 'info');
};
} else {
copyBtn.disabled = false;
copyBtn.style.opacity = '1';
copyBtn.style.cursor = 'pointer';
copyBtn.onclick = function() {
copyToClipboard(translatedText);
};
}
const mode = isFileMode ? 'file' : 'text';
showNotification(`${mode} translation completed successfully!`, 'success');
textOutput.scrollIntoView({ behavior: 'smooth', block: 'start' });
}, 500);
}
function downloadTextFile(text, filename) {
const blob = new Blob([text], { type: 'text/plain; charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showNotification(`File "${filename}" downloaded!`, 'success');
}
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
showNotification('Text copied to clipboard!', 'success');
}).catch(err => {
console.error('Failed to copy text: ', err);
showNotification('Failed to copy text', 'error');
});
}
function showNotification(message, type) {
notificationText.textContent = message;
switch(type) {
case 'error':
notification.style.background = '#ef4444';
break;
case 'success':
notification.style.background = '#10b981';
break;
case 'info':
notification.style.background = '#3b82f6';
break;
default:
notification.style.background = '#10b981';
}
notification.style.display = 'flex';
setTimeout(() => {
notification.style.display = 'none';
}, 3000);
}
initLanguageSelect();
console.log('Text Translation App initialized');
console.log('API Endpoint:', API_ENDPOINT);
console.log('Translate Endpoint:', TRANSLATE_ENDPOINT);
});
```



