如何用Python修改docx表格中指定文本的颜色?
使用python-docx仅修改docx表格中指定文本的颜色(保留其余格式)
我想通过python-docx库修改docx文件表格中特定文本的颜色,只把“P.O. No.:”这类指定文本改成黑色,同时保留单元格内其他文本的原有格式。但我写的代码达不到预期效果,求指导或替代方案。
原代码
from docx import Document from docx.shared import RGBColor def change_text_color(docx_file, text_to_change, color): doc = Document(docx_file) color_changed = False 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 text_to_change in run.text: run.text = run.text[:9] run.font.color.rgb = color color_changed = True break if color_changed: break if color_changed: break if color_changed: break if color_changed: break modified_docx_file = "modified.docx" doc.save(modified_docx_file) print(f"Modified DOCX file '{docx_file}' with the new text color. Saved as '{modified_docx_file}'.") docx_file = "C:\\Users\\RAJAGANESH\\Desktop\\New folder\\897506 1st Sample.docx" text_to_change = "P.O. No.:" color = RGBColor(0, 0, 0) # 注释错误,实际为黑色 change_text_color(docx_file, text_to_change, color) # 预期:仅将"P.O. No.:"改为黑色,单元格内其余文本格式保持不变
原代码问题分析
- 直接截断
run.text为前9个字符,丢失了单元格内的其余文本,完全不符合需求 - 修改的是整个run的颜色,无法实现仅目标文本变色的效果
- 多层
break逻辑导致找到第一个匹配项后就停止遍历,无法处理文档中多个目标文本的情况
修正后的代码
from docx import Document from docx.shared import RGBColor def change_text_color(docx_file, text_to_change, target_color): doc = Document(docx_file) text_len = len(text_to_change) for table in doc.tables: for row in table.rows: for cell in row.cells: for paragraph in cell.paragraphs: # 遍历run的副本,避免修改时干扰遍历流程 runs = list(paragraph.runs) for run in runs: if text_to_change not in run.text: continue # 拆分原run为三个部分:目标文本前内容、目标文本、目标文本后内容 original_text = run.text start_pos = original_text.index(text_to_change) # 处理目标文本前的内容,保留原格式 if start_pos > 0: pre_run = paragraph.add_run(original_text[:start_pos]) pre_run.font.bold = run.font.bold pre_run.font.italic = run.font.italic pre_run.font.color.rgb = run.font.color.rgb pre_run.font.name = run.font.name pre_run.font.size = run.font.size # 处理目标文本,设置指定颜色,保留其他格式 target_run = paragraph.add_run(text_to_change) target_run.font.color.rgb = target_color target_run.font.bold = run.font.bold target_run.font.italic = run.font.italic target_run.font.name = run.font.name target_run.font.size = run.font.size # 处理目标文本后的内容,保留原格式 end_pos = start_pos + text_len if end_pos < len(original_text): post_run = paragraph.add_run(original_text[end_pos:]) post_run.font.bold = run.font.bold post_run.font.italic = run.font.italic post_run.font.color.rgb = run.font.color.rgb post_run.font.name = run.font.name post_run.font.size = run.font.size # 删除原run,避免内容重复 paragraph._p.remove(run._p) modified_docx_file = "modified.docx" doc.save(modified_docx_file) print(f"修改完成,已保存为'{modified_docx_file}'") # 调用示例 docx_file = "C:\\Users\\RAJAGANESH\\Desktop\\New folder\\897506 1st Sample.docx" text_to_change = "P.O. No.:" color = RGBColor(0, 0, 0) # 黑色 change_text_color(docx_file, text_to_change, color)
代码关键点说明
- 遍历所有表格、行、单元格、段落和run,确保不遗漏任何匹配项
- 将包含目标文本的run拆分为三个独立run,分别对应目标文本前后内容和目标文本本身
- 复制原run的格式(字体、字号、粗斜体等)到前后内容的新run,保证其余文本格式不变
- 仅给目标文本对应的run设置指定颜色
- 删除原run,避免出现重复内容
注意事项
- 如果目标文本跨多个run(比如“P.O.”在一个run,“ No.:”在另一个run),上述代码无法处理,这种情况需要额外逻辑合并相邻run后再拆分
- 操作前建议备份原文档,避免意外修改
内容的提问来源于stack exchange,提问作者rajaganesh b.e
相关产品推荐
相关产品推荐

