Proč překlad DOCX ztrácí tučné písmo? Nejprve nechte běh a pak mluvte o výměně celé sekce.
DOCX tučné písmo a kurzíva ztracené po překladu? Problém je asi v tom, že se vymění celý úsek a vyplaví se běh. Tento článek používá python-docx k uložení formátu běhu jeden po druhém a po uložení si jej znovu přečte a přijme. Pokud narazí na složitou strukturu nebo segment neodpovídá, přímo ji odmítne nahradit.
Po překladu DOCX se ztratí tučné písmo, kurzíva a velikost písma. Častým důvodem je, že obsah odstavce je přímo nahrazen celým textem, což smyje původní formát na úrovni běhu. Poté, co mnoho týmů dostane překlad, je běžnou reakcí, že ve Wordu chybí formát zvýraznění. Tento článek je vhodný pro vývojáře, kteří používají python-docx ke zpracování DOCX, a také pro editory, kteří potřebují doručovat dvojjazyčné dokumenty.
Zdá se, že odstavec má ve Wordu pouze jednu větu, ale v DOCX se může skládat z více běhů: běžný text, zdůrazněný text, změny velikosti písma a hypertextové odkazy a další struktury, které nepatří do běžného seznamu běhů. Po přečtení tohoto článku budete vědět, kde obvykle spočívá problém, jak odepsat překlady za běhu a kdy byste měli automatické nahrazení odmítnout.
Co mám dělat, když se formát DOCX po překladu ztratí? Závěr jednou větou
Nejprve omezte zpracování pouze na běžné odstavce běhu textu, zapište překlad jeden po druhém zpět podle původního pořadového čísla běhu, uložte jej a znovu si jej přečtěte pro přijetí; pokud narazí na složitou strukturu nebo segment neodpovídá, přímo odmítněte náhradu.
| vaší situaci | Doporučené postupy | důvod |
|---|---|---|
| Odstavce mají pouze normální běh textu | Zapište překlady jeden po druhém podle pořadového čísla běhu | Hranice formátu pro každý běh jsou zachovány |
| Odstavce obsahují hypertextové odkazy, obrázky, pole, konce řádků nebo tabulátory | Explicitně odmítnout a převést do speciálního procesu | Kód tyto prvky tiše nezplošťuje |
| Počet nebo pořadí překladových segmentů není konzistentní s původním během | Místo toho, abyste se zabývali stávajícími běhy, použijte strategie přeformátování nebo ruční kontrolu | Nucená korespondence naruší formát |
| Je třeba potvrdit výsledek zpětného zápisu | Po uložení soubor znovu otevřete a přijměte jej. | Vyhněte se kontrole pouze objektů v paměti |
Přímo přiřaďte hodnotu paragraph.text | vyhnout se použití | Stávající obsah odstavce bude nahrazen novým textem a formátování na úrovni běhu nebude automaticky zachováno. |
Kde je problém: Nahrazením celého odstavce se vymaže formát běhu
Přímé přiřazení hodnoty paragraph.text nahradí stávající obsah odstavce novým textem. Styly na úrovni odstavce lze zachovat, ale původní formátování na úrovni běhu nebude automaticky zachováno. Toto chování je výslovně zdokumentováno v textové API python-docx.
Výsledek překladu vypadá přesně, ale formát je úplně pryč. To je pravděpodobně důvod.
Rozsah použití: Formát je zachován, ale to neznamená, že byly vyřešeny další problémy.
Testovací záznamy tohoto článku pocházejí z místně syntetizovaného DOCX, nikoli ze snímků obrazovky sázecího stroje. Řeší to "omezené nahrazení bez ztráty formátu". Neřeší automaticky přeuspořádání syntaxe mezi jazyky ani nezajišťuje, že stránkování zůstane po překladu nezměněno.
Nejprve omezte rozsah, který lze bezpečně upravit
Tento zhuštěný příklad přijímá pouze odstavce skládající se z běhu prostého textu. Pokud odstavec obsahuje hypertextové odkazy, obrázky, pole, konce řádků, tabulátory nebo jiné složité uzly XML, výslovně jej odmítněte a přesměrujte volajícího na specializovaný proces. Kód tyto prvky tiše nevyrovná.
Vstup překladu není libovolný seznam řetězců: každý výsledek musí mít sériové číslo původního běhu a před zahájením úpravy se musí všechny shodovat číslo, pořadí a typ. Ověření je umístěno před zápisem, aby se předešlo problémům s následnými poli po aktualizaci v polovině.
Minimální test, který lze spouštět opakovaně
Testovací prostředí je python-docx==1.2.0. Angličtina zde pochází z ručně psaného pevného srovnání, které se používá k ověření struktury a nevyvolává strojový překlad.
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))
Po uložení znovu otevřete translated-runs.docx a poté jej přijměte, abyste se vyhnuli kontrole pouze objektů v paměti.
Proč nedat každý běh překladateli jednotlivě?
run je hranice formátu, nikoli sémantická hranice. Historie úprav aplikace Word může také rozdělit slovo do několika běhů. Izolované překlady ztratí kontext; slovosled různých jazyků může také přesunout důraz na začátek nebo konec věty.
Vlastní generování překladu by mělo poskytnout kontext jako úplné segmenty a poté vrátit ověřené strukturované segmenty. Pokud vrácený výsledek není stejný jako původní délka, nevnucujte jej do stávajícího běhu. Vyžaduje se jasná strategie přeformátování nebo ruční kontrola. Jednoduchý příklad v tomto článku může obsahovat pouze tři fragmenty, ale nelze to zobecnit na všechny jazyky.
Rozdělte přijetí do tří úrovní
| úroveň | Zkontrolujte obsah | Pokrývá tento článek |
|---|---|---|
| datová struktura | Po uložení spusťte množství, objednávku, tučný podpis a obnovení | Přepište tento omezený příklad |
| sémantický obsah | Termíny, záporná slova, data, částky, vynechání | Nepokryté; vyžaduje nezávislou korekturu |
| vizuální rozvržení | Vrácení písma, zalomení řádků, čísla stránek, přetečení tabulek | Nepokryté; je třeba vykreslit a znovu zkontrolovat |
_p a _r jsou interní vlastnosti používané zde pro kontrolu XML. Při upgradu python-docx musíte opravit verzi a znovu spustit test. Nemůžete předpokládat, že vnitřní struktura se nikdy nezmění. Když potřebujete zpracovat tabulky, záhlaví, zápatí, textová pole a stopy revizí, musíte také samostatně vyčíslit rozsahy obsahu, protože document.paragraphs nemůže reprezentovat veškerý text v dokumentu.
Stav zastavení před dodáním
Nepodporované struktury, neodpovídající segmenty, chybějící písma, změny důležitých polí, to vše by mělo zabránit automatickému doručení. Uložte původní soubor jako pouze pro čtení, zapište překlad do nového souboru a připojte jazyk, verzi zpracování a záznam o ručním přijetí. To je lepší ukazatel kvality než „úspěšně uložit".
Pokud potřebujete přejít od nahrávání dokumentů k procesu překladu a kontroly, můžete se podívat na Produktový portál OmniDoc. Příklady kódu v tomto článku jsou ukázky nezávislých výukových knihoven s otevřeným zdrojovým kódem a nepředstavují implementaci aktuálního importéru nebo modulu rozložení OmniDoc. Existuje pouze jeden základní princip: považovat formát za data, která mají být přijata, spíše než za přeložený bonus.
📊 Srovnání jádra
| praxe | Hlavní rizika | Návrhy uvedené v článku |
|---|---|---|
Přímo přiřaďte hodnotu paragraph.text | Formátování na úrovni běhu není automaticky zachováno | Nepoužívá se pro odstavce, které potřebují zachovat formátování |
| Spusťte izolované překlady jeden po druhém | Kontext je ztracen, změny slovosledu mohou přesunout důraz | Poskytněte kontext jako úplné segmenty |
| Po přeložení celého segmentu stiskněte Spustit pro ověření a zapište jej zpět. | Pokud vrácený výsledek není stejně dlouhý jako původní běh, nemůže být těžké s ním souhlasit. | Místo toho použijte strategii přeformátování nebo ruční kontrolu |
🎯 Která metoda je pro vás vhodná?
Pokud váš odstavec obsahuje pouze normální text
Podle minimálního příkladu v tomto článku nejprve ověřte sériové číslo, množství, objednávku a typ, poté jeden po druhém odepište, uložte a znovu přečtěte pro přijetí.
Pokud váš odstavec obsahuje hypertextové odkazy, pole nebo obrázky
Přímo odmítněte automatickou výměnu a převeďte ji do speciálního procesu. Kód tyto struktury tiše nezplošťuje.
Pokud dodáváte formální dvojjazyčnou dokumentaci
Uložte původní soubor jako pouze pro čtení, zapište překlad do nového souboru a připojte záznamy o jazyce, verzi zpracování a ručním přijetí. Chybějící písma, změny v důležitých polích, neshodné segmenty atd. by měly bránit automatickému doručení.
❓ Často kladené otázky (FAQ)
1. Ztratí se tučné písmo, pokud přímo přiřadíte hodnotu do odstavce.text?
zasedání. Styly na úrovni odstavce lze zachovat, ale původní formátování na úrovni běhu nebude automaticky zachováno.
2. Proč nedat každý běh překladateli jednotlivě?
run je spíše hranicí formátu než sémantickou hranicí. Izolovaný překlad jeden po druhém ztratí kontext a slovosled různých jazyků může také přesunout důraz na začátek nebo konec věty.
3. Znamená úspěšné uložení, že je formát v pořádku?
nemůže. Datová struktura přijetí souboru by měla být po uložení znovu otevřena; sémantický obsah a vizuální uspořádání je třeba zkontrolovat samostatně.
4. Na co bych měl dávat pozor při upgradu python-docx?
Kód využívá vnitřní vlastnosti _p a _r. Musíte opravit verzi a znovu spustit test. Nemůžete předpokládat, že vnitřní struktura se nikdy nezmění.
📝 Shrnutí
Existuje pouze jeden základní princip: považovat formát za data, která mají být přijata, spíše než za přeložený bonus. Příklady kódu v tomto článku jsou ukázky nezávislých výukových knihoven s otevřeným zdrojovým kódem a nepředstavují implementaci aktuálního importéru nebo modulu rozložení OmniDoc.
Vyzkoušejte to hned: Nahrajte dokument a začněte překládat při zachování původního rozvržení


