使用python-docx替换Word文本时如何保留原文本格式
问题原因
直接调用paragraph.text.replace()后赋值给paragraph.text会丢失原有格式,核心原因是Word文档中段落的字体、颜色、字号等样式属性是绑定在Run(文本块)对象上的,直接修改paragraph.text会清空段落下所有带格式的原有Run,自动生成一个使用默认样式的新Run存储文本,原有的样式自然全部丢失。
你找到的手动设置Run字体颜色的参考代码逻辑是可行的,但完全不需要手动重新给替换后的文本设置样式——只要在原有Run上做文本替换,Run本身的样式属性会完整保留,替换后的文本自动继承原格式。
可直接复用的适配方案
基础版(覆盖90%常规场景)
适用场景:待替换的目标词汇没有被拆分到多个文本块(即没有对词汇内的单个字符单独设置格式、没有Word自动拆分Run的情况),直接替换对应Run的文本即可,格式100%保留。
把你原有代码中直接修改paragraph.text的逻辑替换为遍历Run的逻辑即可:
from docx import Document # 加载你的目标文档 doc = Document("你的文档路径.docx") target_word = "example" replace_word = "hello" # 表格内文本替换 for table in doc.tables: for row in table.rows: for cell in row.cells: for paragraph in cell.paragraphs: # 遍历段落内所有带格式的文本块做替换 for run in paragraph.runs: if target_word in run.text: run.text = run.text.replace(target_word, replace_word) # 如果需要同时替换正文(非表格内)的对应词汇,保留这段,不需要可删除 for paragraph in doc.paragraphs: for run in paragraph.runs: if target_word in run.text: run.text = run.text.replace(target_word, replace_word) doc.save("替换完成的文档.docx")
替换后的hello会自动继承原example所在文本块的所有样式,包括字体、颜色、字号、加粗、斜体、下划线等属性,不需要额外手动设置字体参数。
增强版(兼容目标词跨多个文本块的场景)
如果之前对目标词内的部分字符做过单独格式调整,Word会把一个词拆分到多个Run中存储,基础版会出现匹配不到的问题,用下面的封装函数即可处理:
from docx import Document def replace_keep_format(paragraph, target, replacement): runs = paragraph.runs full_text = "".join([run.text for run in runs]) if target not in full_text: return # 定位目标词在整段文本中的位置 start_pos = full_text.find(target) end_pos = start_pos + len(target) # 建立字符到对应Run的映射 char_to_run = [] for run_idx, run in enumerate(runs): char_to_run.extend([(run_idx, char_idx) for char_idx in range(len(run.text))]) # 定位目标词覆盖的首尾Run start_run_idx, start_char_idx = char_to_run[start_pos] end_run_idx, end_char_idx = char_to_run[end_pos - 1] # 替换文本写入起始Run,自动继承该Run的格式 runs[start_run_idx].text = runs[start_run_idx].text[:start_char_idx] + replacement # 清空目标词覆盖的中间Run内容 for run_idx in range(start_run_idx + 1, end_run_idx): runs[run_idx].text = "" # 处理尾Run剩余文本 if start_run_idx != end_run_idx: runs[start_run_idx].text += runs[end_run_idx].text[end_char_idx + 1:] runs[end_run_idx].text = "" # 调用示例 doc = Document("你的文档路径.docx") # 处理表格内文本 for table in doc.tables: for row in table.rows: for cell in row.cells: for paragraph in cell.paragraphs: replace_keep_format(paragraph, "example", "hello") # 如需处理正文加下面这段 for paragraph in doc.paragraphs: replace_keep_format(paragraph, "example", "hello") doc.save("替换完成的文档.docx")
内容的提问来源于stack exchange,提问作者Tim Gast
相关产品推荐
相关产品推荐

