Traduire un fichier Excel avec Python et ChatGPT (2026)
Tutoriel pas à pas avec code complet : traduisez vos fichiers Excel via openpyxl et l'API OpenAI sans casser formules ni mise en forme.
Dernière mise à jour : juin 2026 — testé avec le SDK Python d'OpenAI v1.x et l'API Chat Completions.
Ce tutoriel utilise l'API Chat Completions car elle est simple et très largement prise en charge. Pour de nouvelles applications, vous pouvez aussi envisager l'API Responses d'OpenAI et les sorties structurées.
Deux façons de traduire un fichier Excel
Avant d'écrire la moindre ligne de code, mieux vaut être honnête sur l'approche qui vous convient réellement :
- Écrire un script Python (ce guide). Idéal si vous voulez automatiser la traduction de nombreux fichiers, l'exécuter de façon planifiée ou l'intégrer dans un pipeline plus large. Il vous faudra une clé d'API OpenAI et quelques bases en Python.
- Utiliser un outil prêt à l'emploi. Si vous avez simplement besoin de traduire un classeur tout de suite — avec les graphiques, les formules et la mise en forme conservés automatiquement —, le déposer sur le traducteur Excel de Doc2Lang est plus rapide et ne demande aucun code.
Ce guide se concentre sur l'approche Python et vous fournit un code complet et fonctionnel. Nous indiquerons aussi précisément où l'approche « fait maison » devient délicate, afin que vous puissiez choisir en connaissance de cause. Une comparaison détaillée vous attend vers la fin.
Prérequis
Avant de commencer, vous aurez besoin de quelques éléments :
- Des bases en Python. Cet article contient du code. Quelques notions de Python aident, mais nous expliquerons chaque étape.
- Python installé. Si ce n'est pas encore le cas, téléchargez-le depuis le site officiel.
- pip. C'est l'outil qui installe les bibliothèques Python. Si vous avez Python 3, vous disposez presque certainement déjà de pip.
- Une clé d'API OpenAI. Créez-la dans le tableau de bord de votre compte OpenAI. La même clé fonctionne avec tous les modèles actuels (
gpt-4o,gpt-4o-mini, etc.). - Votre fichier Excel. Préparez le fichier
.xlsxque vous souhaitez traduire.
Définissez votre clé d'API dans une variable d'environnement afin qu'elle ne figure jamais dans votre code :
macOS / Linux :
export OPENAI_API_KEY="your_api_key_here"Windows PowerShell :
$env:OPENAI_API_KEY="your_api_key_here"Comment est structuré un fichier .xlsx (contexte facultatif)
Lorsque vous enregistrez un classeur au format .xlsx, vous regroupez en réalité plusieurs fichiers dans une seule archive. Ce format s'appelle OpenXML. Par curiosité, vous pouvez renommer le fichier en .zip, le décompresser et regarder à l'intérieur :
xl/worksheets/— un fichier XML par feuille (sheet1.xml,sheet2.xml, …). C'est là que résident réellement vos lignes, vos colonnes et les données des cellules.xl/styles.xml— tous les styles du classeur : quelles cellules sont en gras, lesquelles sont en bleu, quels nombres sont formatés en devise, et ainsi de suite.xl/sharedStrings.xml— pour gagner de la place, Excel stocke chaque chaîne unique une seule fois ici et y fait référence partout où elle est utilisée. Si « Total » apparaît 1 000 fois, il n'est stocké qu'une seule fois.xl/workbook.xml— la table des matières : quelles feuilles existent, leur ordre et des propriétés comme la protection des feuilles.
Des bibliothèques comme openpyxl vous masquent l'essentiel de ces détails, mais comprendre cette structure est utile lorsque vous avez besoin d'opérations avancées ou de diagnostiquer un problème.
Un fichier report.xlsx décompressé : les feuilles, les chaînes partagées, les styles et la structure du classeur ne sont que des fichiers XML dans une archive zip.
Lire et écrire des fichiers Excel avec openpyxl
openpyxl est une bibliothèque Python conçue spécifiquement pour lire et écrire des fichiers Excel (.xlsx, .xlsm, .xltx, .xltm). Elle vous permet de manipuler directement les feuilles et les cellules.
Une précision s'impose d'emblée : openpyxl est excellent pour le travail au niveau des cellules, mais ce n'est pas un moteur de mise en page Excel haute fidélité. Les formes, certaines images, les graphiques, les macros et le texte enrichi à l'intérieur d'une même cellule peuvent ne pas être conservés lorsque vous ouvrez puis réenregistrez un fichier. Pour les fichiers .xlsm contenant des macros, chargez-les avec load_workbook(..., keep_vba=True) et réenregistrez-les en .xlsm, sinon les macros risquent d'être perdues. Nous reviendrons sur ces limites à la fin.
1. Installer openpyxl
pip install openpyxl2. Concepts de base
Quelques concepts correspondent directement à openpyxl :
Workbook (classeur) — un fichier Excel dans son ensemble.
from openpyxl import load_workbook
workbook = load_workbook(filename="sample.xlsx")Sheet (feuille) — un classeur contient une ou plusieurs feuilles.
sheet = workbook.active # la feuille active
another_sheet = workbook["Sheet2"] # une feuille par son nomCell (cellule) — l'intersection d'une ligne et d'une colonne. C'est là que se trouvent les données.
cell_value = sheet["A1"].value # lecture
sheet["B1"] = "Hello, Excel!" # écritureLignes et colonnes — parcourez-les facilement :
for row in sheet.iter_rows(values_only=True):
for value in row:
print(value)Traduire du texte avec l'API OpenAI
Une fois vos données chargées avec openpyxl, l'étape suivante consiste à les traduire avec l'API OpenAI.
1. Installer la bibliothèque Python d'OpenAI
pip install openai2. Une fonction de traduction moderne (2026)
import os
from openai import OpenAI
# Lit la clé depuis une variable d'environnement — ne la codez jamais en dur dans votre script.
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
def translate_text(text, target_lang="French"):
response = client.chat.completions.create(
model="gpt-4o-mini", # rapide et économique ; utilisez "gpt-4o" pour la meilleure qualité
messages=[
{
"role": "system",
"content": (
f"You are a professional translator. Translate the user's text "
f"into {target_lang}. Return only the translation, with no extra commentary."
),
},
{"role": "user", "content": text},
],
)
return response.choices[0].message.content.strip()Attention : beaucoup de tutoriels plus anciens utilisent
openai.ChatCompletion.create()avecmodel="gpt-4". Cette syntaxe provient du SDK antérieur à la version 1.0 et ne fonctionne plus avecopenai>=1.0. Le code ci-dessus utilise l'interface actuelleclient.chat.completions.create(). Choisissezgpt-4o-minipour un coût et une rapidité optimaux, ougpt-4olorsque vous avez besoin d'une qualité de traduction maximale.
3. Une première tentative naïve
L'approche la plus répandue dans les tutoriels consiste à parcourir chaque cellule et à l'écraser :
from openpyxl import load_workbook
workbook = load_workbook(filename="your_file.xlsx")
for sheet in workbook.worksheets:
for row in sheet.iter_rows():
for cell in row:
if isinstance(cell.value, str):
cell.value = translate_text(cell.value)
workbook.save("your_translated_file.xlsx")Cela fonctionne dans une démo, mais pose de vrais problèmes sur des classeurs réels : un appel d'API par cellule (lent et coûteux), la traduction des formules qui les casse, et aucune protection contre les limites de débit. Corrigeons tout cela.
Le rendre prêt pour la production
1. Ne pas traduire les formules
Si une cellule contient une formule comme =SUM(A1:A10), la traduire corrompra le classeur. Ignorez les formules, les cellules vides et les valeurs non textuelles :
def is_translatable(cell):
# Ignore les cellules vides, les nombres et les cellules de formule.
value = cell.value
return (
isinstance(value, str)
and value.strip() != ""
and cell.data_type != "f" # "f" = formule
)openpyxl ne réécrit que cell.value, donc les formats de nombres, les polices, les remplissages et la majeure partie de la mise en forme restent intacts tant que vous laissez les cellules non textuelles tranquilles.
2. Mettre en cache les chaînes répétées pour réduire les coûts
Les classeurs répètent sans cesse les mêmes libellés (« Total », « Date », un nom de service). Ne traduisez chaque chaîne unique qu'une seule fois :
cache = {}
def translate_cached(text, target_lang="French"):
if text not in cache:
cache[text] = translate_text(text, target_lang)
return cache[text]Sur un rapport classique, cela à lui seul peut réduire considérablement le nombre d'appels à l'API — et donc votre facture.
3. Regrouper les cellules dans une seule requête
Un appel d'API par cellule est la principale source de lenteur. Envoyez plutôt de nombreuses chaînes en une seule requête, en demandant au modèle de renvoyer du JSON afin de pouvoir associer les résultats de façon fiable :
import json
def translate_batch(texts, target_lang="French"):
numbered = {str(i): t for i, t in enumerate(texts)}
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": (
f"You are a professional translator. Translate each value in the "
f"JSON object into {target_lang}. Keep the same keys. "
f"Return only a JSON object."
),
},
{"role": "user", "content": json.dumps(numbered, ensure_ascii=False)},
],
response_format={"type": "json_object"},
)
result = json.loads(response.choices[0].message.content)
return [result[str(i)] for i in range(len(texts))]4. Réessayer en cas de limite de débit (backoff exponentiel)
Lorsque vous atteignez une limite de débit, ne plantez pas : attendez et réessayez, en doublant le délai à chaque fois :
import time
def with_retry(func, *args, retries=5, **kwargs):
for attempt in range(retries):
try:
return func(*args, **kwargs)
except Exception as e:
wait = 2 ** attempt
print(f"Error: {e}. Retrying in {wait}s...")
time.sleep(wait)
raise RuntimeError("Translation failed after several retries.")5. Traiter les fichiers non fiables en toute sécurité
Si vous traitez des fichiers Excel envoyés par d'autres personnes, protégez-vous contre le XML malveillant. Installez defusedxml, qu'openpyxl utilisera automatiquement lorsqu'il est présent, et vérifiez la taille et le type du fichier avant de le charger :
pip install defusedxmlC'est facultatif pour vos propres fichiers, mais fortement recommandé pour tout fichier que vous n'avez pas créé vous-même.
Script complet et fonctionnel
Voici tout réuni dans un seul script que vous pouvez copier et exécuter. Il collecte les chaînes uniques, les traduit par lots avec des tentatives de réessai, met les résultats en cache, ignore les formules et enregistre dans un nouveau fichier afin que votre original reste intact.
import json
import os
import time
from openai import OpenAI
from openpyxl import load_workbook
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
TARGET_LANG = "French"
MODEL = "gpt-4o-mini" # utilisez "gpt-4o" pour une meilleure qualité
BATCH_SIZE = 40
def is_translatable(cell):
value = cell.value
return (
isinstance(value, str)
and value.strip() != ""
and cell.data_type != "f" # "f" = formule
)
def translate_batch(texts, target_lang=TARGET_LANG, retries=5):
numbered = {str(i): t for i, t in enumerate(texts)}
system = (
f"You are a professional translator. Translate each value in the JSON object "
f"into {target_lang}. Keep the same keys. Return only a JSON object."
)
for attempt in range(retries):
try:
response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": system},
{"role": "user", "content": json.dumps(numbered, ensure_ascii=False)},
],
response_format={"type": "json_object"},
)
result = json.loads(response.choices[0].message.content)
return [result[str(i)] for i in range(len(texts))]
except Exception as e:
wait = 2 ** attempt
print(f"Error: {e}. Retrying in {wait}s...")
time.sleep(wait)
raise RuntimeError("Translation failed after several retries.")
# 1. Charger le classeur
workbook = load_workbook(filename="your_file.xlsx")
# 2. Collecter chaque chaîne unique et traduisible
unique_texts = set()
for sheet in workbook.worksheets:
for row in sheet.iter_rows():
for cell in row:
if is_translatable(cell):
unique_texts.add(cell.value)
unique_texts = list(unique_texts)
# 3. Traduire par lots et construire un cache {original: traduction}
cache = {}
for start in range(0, len(unique_texts), BATCH_SIZE):
chunk = unique_texts[start:start + BATCH_SIZE]
cache.update(dict(zip(chunk, translate_batch(chunk))))
# 4. Réécrire les traductions sans toucher aux formules ni à la mise en forme
for sheet in workbook.worksheets:
for row in sheet.iter_rows():
for cell in row:
if is_translatable(cell):
cell.value = cache[cell.value]
# 5. Enregistrer dans un nouveau fichier
workbook.save("your_translated_file.xlsx")
print("Done!")Voilà un traducteur complet et pratique en bien moins de 100 lignes — rapide, sûr pour les formules et bien moins cher que la version cellule par cellule.
Facultatif : renforcer le script pour des charges de travail réelles
Le script ci-dessus est déjà pratique. Pour des tâches plus volumineuses ou récurrentes, trois garde-fous supplémentaires sont utiles.
N'avalez pas toutes les exceptions. Réessayer à chaque exception signifie qu'une clé d'API invalide ou un nom de modèle erroné sera lui aussi réessayé cinq fois. Ne réessayez que pour les limites de débit, et échouez immédiatement pour tout le reste :
from openai import RateLimitError
def translate_batch(texts, target_lang=TARGET_LANG, retries=5):
numbered = {str(i): t for i, t in enumerate(texts)}
system = (
f"You are a professional translator. Translate each value in the JSON object "
f"into {target_lang}. Keep the same keys. Return only a JSON object."
)
for attempt in range(retries):
try:
response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": system},
{"role": "user", "content": json.dumps(numbered, ensure_ascii=False)},
],
response_format={"type": "json_object"},
)
result = json.loads(response.choices[0].message.content)
missing = [str(i) for i in range(len(texts)) if str(i) not in result]
if missing:
raise ValueError(f"Missing translations for keys: {missing}")
return [result[str(i)] for i in range(len(texts))]
except RateLimitError:
wait = 2 ** attempt
print(f"Rate limited. Retrying in {wait}s...")
time.sleep(wait)
raise RuntimeError("Translation failed after several retries.")Cette version vérifie aussi que le modèle a bien renvoyé chacune des clés qui lui ont été fournies, de sorte qu'une réponse tronquée ou malformée échoue bruyamment au lieu de supprimer silencieusement des cellules.
Conservez l'ordre lors de la déduplication. Utilisez une déduplication ordonnée plutôt qu'un ensemble, pour que les journaux et les messages d'erreur restent prévisibles :
# avant : unique_texts = list(unique_texts) avec un set()
unique_texts = list(dict.fromkeys(collected_texts))Script Python vs. Doc2Lang : lequel choisir ?
Écrire son propre script est puissant, mais cela a de vraies limites. Voici une comparaison honnête :
| Python (fait maison) | Doc2Lang | |
|---|---|---|
| Mise en forme et graphiques | À votre charge ; facilement cassés | Conservés automatiquement |
| Formules | Vous écrivez vos propres conditions pour les ignorer | Ignorées automatiquement |
| Ce qu'il vous faut | Clé d'API OpenAI + savoir coder | Il suffit de déposer le fichier |
| Idéal pour | Les développeurs qui automatisent des traitements en masse ou récurrents | Quiconque a besoin de traduire un fichier maintenant |
Un rapport financier en anglais traduit vers le français par Doc2Lang : les graphiques en colonnes et en courbes, les formules, les formats de nombres et les largeurs de colonnes sont tous préservés (les noms des onglets restent dans la langue d'origine, sans traduction).
→ Essayez le traducteur Excel — sans clé d'API, sans code.
La règle générale : si vous voulez automatiser des traitements de traduction récurrents, créez le script ci-dessus. Si vous avez simplement besoin de traduire un classeur tout de suite sans écrire de code, utilisez le traducteur Excel — déposez, traduisez, téléchargez, avec la mise en forme préservée.
Guides connexes
- Traduire un fichier Excel en anglais : la voie sans code et ce qui reste intact
- Automatiser la traduction de documents Word avec Python et ChatGPT
- Traduire facilement des PDF avec Python et OpenAI
Foire aux questions
Que faire si j'obtiens une erreur de limite de débit ?
OpenAI applique des limites de débit selon le palier de votre compte. Utilisez la stratégie de réessai avec backoff exponentiel présentée plus haut, réduisez la taille de vos lots, ou faites passer votre compte à un palier supérieur si vous traitez de gros volumes.
Comment traduire vers plusieurs langues à la fois ?
Parcourez une liste de langues cibles et exécutez l'ensemble du processus une fois par langue, en enregistrant chaque résultat dans son propre fichier (par exemple report_fr.xlsx, report_de.xlsx).
L'utilisation de l'API OpenAI est-elle payante ?
Oui. Vous payez selon le nombre de tokens utilisés. La mise en cache des chaînes répétées et le regroupement des requêtes (tous deux présentés ci-dessus) maintiennent les coûts bas. gpt-4o-mini est nettement moins cher que les modèles plus grands pour de la traduction au quotidien.
Cela préservera-t-il ma mise en forme et mes formules ?
Le script ne modifie que la valeur des cellules de texte, si bien que les styles de cellule de base — polices, remplissages, bordures, alignement et formats de nombres — sont généralement préservés, et les formules sont ignorées. Cependant, openpyxl n'est pas un moteur de mise en page Excel haute fidélité. Les macros, les formes, les graphiques, les images, le texte enrichi à l'intérieur d'une même cellule et les fonctionnalités complexes de classeur peuvent ne pas être parfaitement conservés. Pour les fichiers .xlsm, chargez-les avec keep_vba=True et réenregistrez-les en .xlsm. Si une mise en page au pixel près compte plus que l'automatisation, un outil dédié gère ces cas automatiquement.
Conclusion
Avec openpyxl et l'API OpenAI, vous pouvez créer un traducteur Excel rapide et sûr pour les formules en bien moins de 100 lignes de code — un excellent choix lorsque vous devez automatiser la traduction à grande échelle.
Si votre priorité est la préservation de la mise en page plutôt que l'automatisation, un outil de traduction Excel dédié sera peut-être plus adapté — il gère les graphiques, les formes et la mise en forme qu'openpyxl ne peut pas prendre en charge.