当前位置: 代码网 > it编程>前端脚本>Python > Python文档处理之实现自动删除Word中带指定底纹颜色的内容

Python文档处理之实现自动删除Word中带指定底纹颜色的内容

2026年02月28日 Python 我要评论
代码功能概述该脚本用于自动删除 word 文档中带有指定底纹颜色的解析内容(如【分析】、【详解】等),同时保留答案块(以【答案】开头的有底纹段落及其后续连续有底纹的答案内容)。文档中所有无底纹的段落(

代码功能概述

该脚本用于自动删除 word 文档中带有指定底纹颜色的解析内容(如【分析】、【详解】等),同时保留答案块(以【答案】开头的有底纹段落及其后续连续有底纹的答案内容)。文档中所有无底纹的段落(题目描述、选项等)以及答案块内的内容都会被原样保留,其余文档结构(表格、页眉页脚、样式)不受影响。

脚本支持两种输入模式:

  • 处理单个文件:输入一个 .docx 文件路径,输出一个处理后的文件。
  • 批量处理文件夹:输入一个文件夹路径,自动处理该文件夹下所有 .docx 文件,输出到指定文件夹。

文档内容示例

脚本代码 

import os
from docx import document
from docx.oxml.ns import qn

# ====== 配置参数(请根据您的文档修改)======
target_shading_color = 'f2f2f2'  # 从检测脚本获得的底纹颜色
analysis_markers = ['【分析】', '【详解】', '【点睛】', '【错因】', '【避错关键】']
answer_marker = '【答案】'
debug = true  # 打印详细处理信息

# word命名空间(用于查找元素)
nsmap = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}


def has_shading_color(element, color):
    """判断元素是否具有指定底纹颜色"""
    # 使用 findall 并传入命名空间
    shading_elements = element.findall('.//w:shd', namespaces=nsmap)
    if shading_elements:
        fill = shading_elements[0].get(qn('w:fill'))
        if fill:
            fill_clean = fill.strip().upper().lstrip('#')
            color_clean = color.strip().upper().lstrip('#')
            return fill_clean == color_clean
    return false


def is_analysis_start(text):
    """是否以解析标记开头"""
    return any(text.startswith(marker) for marker in analysis_markers)


def collect_all_shaded_paragraphs(doc):
    """
    收集文档中所有具有目标底纹颜色的段落(包括文本框内)。
    返回列表,每个元素为 (element, text, parent)
    """
    items = []
    # 普通段落
    for para in doc.paragraphs:
        element = para._element
        if has_shading_color(element, target_shading_color):
            items.append((element, para.text.strip(), element.getparent()))
    # 文本框段落
    for txbx in doc.element.findall('.//w:txbxcontent', namespaces=nsmap):
        for p in txbx.findall('.//w:p', namespaces=nsmap):
            if has_shading_color(p, target_shading_color):
                # 提取文本
                texts = [t.text for t in p.findall('.//w:t', namespaces=nsmap) if t.text]
                full_text = ''.join(texts).strip()
                items.append((p, full_text, p.getparent()))
    return items


def process_docx_inplace(input_path, output_path):
    """
    在原文档基础上直接删除解析段落,保存到 output_path。
    """
    doc = document(input_path)
    # 收集所有有底纹的段落
    shaded_items = collect_all_shaded_paragraphs(doc)
    n = len(shaded_items)
    delete_flags = [false] * n
    debug_info = []

    i = 0
    while i < n:
        element, text, parent = shaded_items[i]
        if text.startswith(answer_marker):
            # 答案开始,保留
            if debug:
                debug_info.append(f"保留答案开始 {i}: {text[:50]}")
            i += 1
            # 保留后续连续的有底纹段落,直到遇到解析标记
            while i < n:
                next_element, next_text, _ = shaded_items[i]
                if is_analysis_start(next_text):
                    break
                if debug:
                    debug_info.append(f"保留答案内容 {i}: {next_text[:50]}")
                i += 1
            continue
        elif is_analysis_start(text):
            # 解析标记,删除本段及其后连续的有底纹段落(直到下一个答案块或解析标记)
            if debug:
                debug_info.append(f"删除解析开始 {i}: {text[:50]}")
            delete_flags[i] = true
            i += 1
            while i < n:
                next_element, next_text, _ = shaded_items[i]
                if next_text.startswith(answer_marker) or is_analysis_start(next_text):
                    break
                if debug:
                    debug_info.append(f"删除解析内容 {i}: {next_text[:50]}")
                delete_flags[i] = true
                i += 1
            continue
        else:
            # 有底纹但不是答案也不是解析,删除(通常不会出现)
            if debug:
                debug_info.append(f"删除其他有底纹段落 {i}: {text[:50]}")
            delete_flags[i] = true
            i += 1

    # 从后往前删除标记的段落元素
    for idx in range(n - 1, -1, -1):
        if delete_flags[idx]:
            element, _, parent = shaded_items[idx]
            parent.remove(element)

    # 保存文档
    doc.save(output_path)

    if debug:
        print(f"处理文件: {os.path.basename(input_path)}")
        print(f"共处理有底纹段落 {n} 个,删除 {sum(delete_flags)} 个")
        print("=== 调试信息 ===")
        for info in debug_info[-20:]:  # 只打印最后20条,避免过长
            print(info)
        print("=== 处理完成 ===\n")


def process_file_or_folder(input_path, output_path):
    """
    自动判断输入是文件还是文件夹:
    - 如果是文件,处理该文件
    - 如果是文件夹,处理文件夹下所有 .docx 文件
    """
    if os.path.isfile(input_path):
        # 单个文件
        if not input_path.endswith('.docx'):
            print("请提供 .docx 文件")
            return
        if os.path.isdir(output_path):
            base = os.path.basename(input_path).replace('.docx', '_已处理.docx')
            output_file = os.path.join(output_path, base)
        else:
            output_file = output_path
        process_docx_inplace(input_path, output_file)
        print(f'处理完成:{os.path.basename(input_path)} -> {output_file}')
    elif os.path.isdir(input_path):
        # 文件夹
        if not os.path.exists(output_path):
            os.makedirs(output_path)
        for filename in os.listdir(input_path):
            if filename.endswith('.docx'):
                full_input = os.path.join(input_path, filename)
                full_output = os.path.join(output_path, filename.replace('.docx', '_已处理.docx'))
                process_docx_inplace(full_input, full_output)
                print(f'处理完成:{filename}')
    else:
        print("输入路径不存在")


if __name__ == '__main__':
    # ===== 使用示例 =====
    # 1. 处理单个文件,输出到指定路径
    input_path = r'c:\desktop\读书笔记\讲义'
    output_path = r'c:\desktop\读书笔记\讲义'
    process_file_or_folder(input_path, output_path)

到此这篇关于python文档处理之实现自动删除word中带指定底纹颜色的内容的文章就介绍到这了,更多相关python word文档处理内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com