Tous les articles
Article13 min de lecture

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.

Translate Excel ChatGPT

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 .xlsx que 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.

L'Explorateur Windows affichant le contenu d'un fichier report.xlsx décompressé

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 openpyxl

2. 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 nom

Cell (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!"    # écriture

Lignes 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 openai

2. 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() avec model="gpt-4". Cette syntaxe provient du SDK antérieur à la version 1.0 et ne fonctionne plus avec openai>=1.0. Le code ci-dessus utilise l'interface actuelle client.chat.completions.create(). Choisissez gpt-4o-mini pour un coût et une rapidité optimaux, ou gpt-4o lorsque 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 defusedxml

C'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ésConservés automatiquement
FormulesVous écrivez vos propres conditions pour les ignorerIgnorées automatiquement
Ce qu'il vous fautClé d'API OpenAI + savoir coderIl suffit de déposer le fichier
Idéal pourLes développeurs qui automatisent des traitements en masse ou récurrentsQuiconque a besoin de traduire un fichier maintenant
Rapport financier traduit de l'anglais vers le français par Doc2Lang, avec graphiques et mise en forme préservés

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

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.

Traduire un fichier Excel sans écrire de code

Partager