Perché la traduzione DOCX perde il grassetto? Continua prima la corsa, quindi parla della sostituzione dell'intera sezione.

DOCX grassetto e corsivo perso dopo la traduzione? Il problema probabilmente è che tutta la sezione viene sostituita e la fuga viene dilavata. Questo articolo utilizza python-docx per salvare il formato di esecuzione uno per uno e rileggerlo e accettarlo dopo il salvataggio. Se incontra una struttura complessa o il segmento non corrisponde, rifiuterà direttamente di sostituirlo.

Grassetto, corsivo e dimensione del carattere vengono persi dopo la traduzione DOCX. Il motivo comune è che il contenuto del paragrafo viene sostituito direttamente con l'intero testo, cancellando così il formato run-level originale. Dopo che molti team hanno ricevuto la traduzione, una reazione comune è che manca il formato di enfasi in Word. Questo articolo è adatto agli sviluppatori che utilizzano python-docx per elaborare DOCX, nonché agli editor che devono fornire documenti bilingue.

Un paragrafo sembra avere una sola frase in Word, ma in DOCX può essere composto da più sequenze: testo ordinario, testo enfatizzato, modifiche alla dimensione del carattere, collegamenti ipertestuali e altre strutture che non appartengono all'elenco delle sequenze ordinarie. Dopo aver letto questo, saprai dove si trova solitamente il problema, come riscrivere le traduzioni esecuzione per esecuzione e quando dovresti semplicemente rifiutare la sostituzione automatica.

Cosa devo fare se il formato DOCX viene perso dopo la traduzione? Conclusione di una frase

Innanzitutto limitare l'elaborazione ai soli paragrafi di testo ordinario, riscrivere la traduzione una per una in base al numero di sequenza di esecuzione originale, salvarla e rileggerla per accettazione; se incontra una struttura complessa o il segmento non corrisponde, rifiuta direttamente la sostituzione.

la tua situazionePratiche consigliatemotivo
I paragrafi hanno solo il testo normaleRiscrivere le traduzioni una per una in base al numero di sequenza di esecuzioneI limiti del formato per ogni esecuzione vengono preservati
I paragrafi contengono collegamenti ipertestuali, immagini, campi, interruzioni di riga o tabulazioniRifiutare esplicitamente e trasferire al processo specialeIl codice non appiattisce silenziosamente questi elementi
Il numero o l'ordine dei segmenti di traduzione non è coerente con la sequenza originaleInvece di limitarti alle esecuzioni esistenti, utilizza strategie di riformattazione o revisione manualeLa corrispondenza forzata interromperà il formato
È necessario confermare il risultato della riscritturaDopo aver salvato, riapri il file e accettalo.Evitare di controllare solo gli oggetti in memoria
Assegna direttamente il valore a paragraph.textevitare di utilizzareIl contenuto esistente del paragrafo verrà sostituito con il nuovo testo e la formattazione a livello di esecuzione non verrà mantenuta automaticamente.

Dov'è il problema: la sostituzione dell'intero paragrafo cancellerà il formato di esecuzione

Assegnando direttamente un valore a paragraph.text si sostituirà il contenuto esistente del paragrafo con un nuovo testo. Gli stili a livello di paragrafo possono essere mantenuti, ma la formattazione originale a livello di esecuzione non verrà mantenuta automaticamente. Questo comportamento è esplicitamente documentato in API di testo python-docx.

Il risultato della traduzione sembra accurato, ma il formato è completamente scomparso. Questo è probabilmente il motivo.

Ambito di applicazione: il formato è preservato, ma ciò non significa che altri problemi siano stati risolti.

I record di test di questo articolo provengono da DOCX sintetizzati localmente, non da screenshot del motore di composizione. Ciò che risolve è la "sostituzione vincolata senza perdere il formato". Non risolve automaticamente i riarrangiamenti della sintassi tra lingue diverse, né garantisce che l'impaginazione rimanga invariata dopo la traduzione.

Limitare innanzitutto l'intervallo che può essere modificato in modo sicuro

Questo esempio condensato accetta solo paragrafi costituiti da testo semplice. Quando un paragrafo contiene collegamenti ipertestuali, immagini, campi, interruzioni di riga, tabulazioni o altri nodi XML complessi, rifiutalo esplicitamente e reindirizza il chiamante a un processo specializzato. Il codice non appiattirà questi elementi in modo silenzioso.

L'input della traduzione non è un elenco arbitrario di stringhe: ogni risultato deve avere il numero di serie dell'esecuzione originale e il numero, l'ordine e il tipo devono corrispondere prima che venga avviata la modifica. La convalida viene effettuata prima della scrittura per evitare di scoprire problemi con i campi successivi dopo l'aggiornamento a metà.

Un test minimo che può essere eseguito ripetutamente

L'ambiente di test è python-docx==1.2.0. L'inglese qui deriva da un confronto fisso scritto a mano, che viene utilizzato per verificare la struttura e non invoca la traduzione automatica.

from docx import Document
from docx.oxml.ns import qn

def replace_plain_runs(paragraph, translated):
    if any(child.tag not in {qn("w:pPr"), qn("w:r")}
           for child in paragraph._p):
        raise ValueError("paragraph contains unsupported structures")
    runs = paragraph.runs
    for run in runs:
        if any(child.tag not in {qn("w:rPr"), qn("w:t")}
               for child in run._r):
            raise ValueError("run contains a field, image or control")
    if len(translated) != len(runs):
        raise ValueError("segment count mismatch")
    for index, item in enumerate(translated):
        if (not isinstance(item, dict) or item.get("id") != index
                or not isinstance(item.get("text"), str)
                or any(ch in item["text"] for ch in "\t\r\n")):
            raise ValueError("segment identity or text mismatch")
    for run, item in zip(runs, translated):
        run.text = item["text"]

def signature(paragraph):
    return [(r.text, r.bold, r.italic) for r in paragraph.runs]

doc = Document()
p = doc.add_paragraph()
p.add_run("请在 ")
p.add_run("周五之前").bold = True
p.add_run(" 提交报告。")
before = signature(p)
try:
    replace_plain_runs(p, [{"id": 0, "text": "Incomplete"}])
    raise AssertionError("bad segments accepted")
except ValueError:
    assert signature(p) == before

replace_plain_runs(p, [
    {"id": 0, "text": "Submit the report "},
    {"id": 1, "text": "before Friday"},
    {"id": 2, "text": "."},
])
doc.save("translated-runs.docx")
restored = Document("translated-runs.docx").paragraphs[0]
assert restored.text == "Submit the report before Friday."
assert restored.runs[1].bold is True
assert len(restored.runs) == 3
complex_p = doc.add_paragraph("keep")
complex_p.runs[0].add_break()
try:
    replace_plain_runs(complex_p, [{"id": 0, "text": "reject"}])
    raise AssertionError("line break accepted")
except ValueError:
    assert complex_p.text == "keep\n"
print("PASS count mismatch: no partial write")
print("PASS save/reopen: 3 runs, emphasis preserved")
print("PASS unsupported control: rejected")
print(signature(restored))

Dopo aver salvato, riaprire translated-runs.docx e poi accettarlo per evitare di controllare solo gli oggetti in memoria.

Perché non affidare ogni passaggio al traduttore individualmente?

run è un confine di formato, non un confine semantico. La cronologia delle modifiche di Word può anche dividere una parola in più esecuzioni. Le traduzioni isolate perderanno il contesto; l'ordine delle parole nelle diverse lingue può anche spostare l'accento all'inizio o alla fine della frase.

L'effettiva generazione della traduzione dovrebbe fornire il contesto sotto forma di segmenti completi e quindi restituire segmenti strutturati convalidati. Quando il risultato restituito non è uguale alla lunghezza originale, non forzarlo nella sequenza esistente. È necessaria una chiara strategia di riformattazione o una revisione manuale. Il semplice esempio in questo articolo può contenere solo tre frammenti, ma ciò non può essere generalizzato a tutte le lingue.

Suddividi l'accettazione in tre livelli

livelloControlla il contenutoQuesto articolo copre
struttura dei datiEsegui quantità, ordine, firma in grassetto e recupero dopo il salvataggioSostituisci questo esempio limitato
contenuto semanticoTermini, parole negative, date, importi, omissioniNon coperto; richiede una correzione di bozze indipendente
disposizione visivaRollback dei caratteri, interruzioni di riga, numeri di pagina, overflow della tabellaNon coperto; deve essere renderizzato e controllato di nuovo

_p e _r sono le proprietà interne utilizzate qui per controllare XML. Quando si aggiorna python-docx, è necessario correggere la versione ed eseguire nuovamente il test. Non si può dare per scontato che la struttura interna non cambierà mai. Quando è necessario elaborare tabelle, intestazioni, piè di pagina, caselle di testo e tracce di revisione, è necessario anche enumerare separatamente gli intervalli di contenuto, poiché document.paragraphs non può rappresentare tutto il testo nel documento.

Condizione di arresto prima della consegna

Strutture non supportate, segmenti non corrispondenti, caratteri mancanti, modifiche a campi importanti: tutto ciò dovrebbe impedire la consegna automatica. Salvare il file originale in sola lettura, scrivere la traduzione in un nuovo file e allegare la lingua, la versione di elaborazione e il record di accettazione manuale. Questo è un indicatore di qualità migliore rispetto a "salvataggio riuscito".

Se devi passare dal caricamento dei documenti al processo di traduzione e revisione, puoi controllare Portale del prodotto OmniDoc. Gli esempi di codice contenuti in questo articolo sono esempi didattici di librerie open source indipendenti e non rappresentano l'implementazione dell'attuale importatore o motore di layout di OmniDoc. Esiste un solo principio fondamentale: trattare il formato come dati da accettare, piuttosto che come un bonus tradotto.

📊 Confronto fondamentale

praticaPrincipali rischiSuggerimenti forniti nell'articolo
Assegna direttamente il valore a paragraph.textLa formattazione a livello di esecuzione non viene mantenuta automaticamenteNon utilizzato per i paragrafi che devono preservare la formattazione
Esegui traduzioni isolate una per unaSi perde il contesto, i cambiamenti nell'ordine delle parole possono spostare l'enfasiFornire il contesto come segmenti completi
Dopo che il segmento completo è stato tradotto, premi Esegui per verificarlo e riscriverlo.Se il risultato restituito non ha la stessa lunghezza della corsa originale, non può essere difficile corrispondere.Utilizzare invece la strategia di riformattazione o la revisione manuale

🎯Quale metodo è adatto a te?

Se il tuo paragrafo ha solo testo normale

Secondo l'esempio minimo in questo articolo, verificare prima il numero di serie, la quantità, l'ordine e il tipo, quindi riscrivere uno per uno, salvare e rileggere per l'accettazione.

Se il tuo paragrafo contiene collegamenti ipertestuali, campi o immagini

Rifiuta direttamente la sostituzione automatica e trasferiscila in un processo speciale. Il codice non appiattisce silenziosamente queste strutture.

Se stai consegnando documentazione bilingue formale

Salvare il file originale in sola lettura, scrivere la traduzione in un nuovo file e allegare la lingua, la versione di elaborazione e i record di accettazione manuale. Caratteri mancanti, modifiche in campi importanti, segmenti non corrispondenti, ecc. dovrebbero impedire la consegna automatica.

❓ Domande frequenti (FAQ)

1. Il grassetto andrà perso se assegni direttamente un valore a paragrafo.testo?

incontro. Gli stili a livello di paragrafo possono essere mantenuti, ma la formattazione originale a livello di esecuzione non verrà mantenuta automaticamente.

2. Perché non affidare ogni passaggio al traduttore individualmente?

run è un confine di formato piuttosto che un confine semantico. La traduzione isolata una per una perderà il contesto e l'ordine delle parole di lingue diverse potrebbe anche spostare l'enfasi all'inizio o alla fine della frase.

3. Il salvataggio riuscito significa che il formato è corretto?

non può. Le strutture dei dati di accettazione dei file devono essere riaperte dopo il salvataggio; il contenuto semantico e il layout visivo devono essere controllati separatamente.

4. A cosa dovrei prestare attenzione quando aggiorno python-docx?

Il codice utilizza le proprietà interne di _p e _r. È necessario correggere la versione ed eseguire nuovamente il test. Non si può dare per scontato che la struttura interna non cambierà mai.

📝 Riepilogo

Esiste un solo principio fondamentale: trattare il formato come dati da accettare, piuttosto che come un bonus tradotto. Gli esempi di codice contenuti in questo articolo sono esempi didattici di librerie open source indipendenti e non rappresentano l'implementazione dell'attuale importatore o motore di layout di OmniDoc.

Provalo subito: carica il documento per iniziare la traduzione, mantenendo il layout originale

Aggiornato il 2026-11-14