You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:13:24